Howie
Howie

Reputation: 2778

Can file_get_contents() return HTML on 4xx?

I need to send a POST request from PHP to a remote HTTPS address, which returns a JSON.

I've used the following code:

    //$url = ...
    $data = array('username' => $username, 'password' => $passwort);

    $options = array(
        'http' => array(
            'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
            'method'  => 'POST',
            'content' => http_build_query($data),
        ),
    );
    $context  = stream_context_create($options);

    $result = file_get_contents($url, false, $context);

However at the last line the function fails with a failed to open stream: HTTP request failed! HTTP/1.1 403 FORBIDDEN error.

The server also sends an explanation in HTML format, but I have no idea how to access it through file_get_contents. Help?

EDIT: I will use cURL instead.

Upvotes: 0

Views: 149

Answers (2)

Gargaj
Gargaj

Reputation: 1

Add ignore_errors to your options:

    $options = array(
        'http' => array(
            'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
            'method'  => 'POST',
            'content' => http_build_query($data),
            'ignore_errors' => true,
        ),
    );

Upvotes: 0

Onema
Onema

Reputation: 7602

As far as I know it is not possible. But if you use an HTTP client like Guzzle you will be able to perform this request very easy and handle errors gracefully. Also Guzzle uses cURL under the hood so you don't have to deal with it directly!

Send your POST request like this:

$client = new GuzzleHttp\Client();
$response = $client->post($url, [
    'body' => [
        'username' => $username,
        'password' => $password
    ]
]);

echo $response->getStatusCode();           // 200
echo $response->getHeader('content-type'); // 'application/json; charset=utf8'
echo $response->getBody();                 // {"type":"User"...'
var_export($response->json());             // Outputs the JSON decoded data

Because you are placing the username and password in the body array it will automatically be url encoded!

You will be able to deal with errors in an OO way and get the body of the 4xx response if the response exists:

try {
    $client->get('https://github.com/_abc_123_404');
} catch (RequestException $e) {
    echo $e->getRequest();
    if ($e->hasResponse()) {
        echo $e->getResponse();
    }
}

See the documentation for more information.

Upvotes: 2

Related Questions