0

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.

Howie
  • 2,760
  • 6
  • 32
  • 60
  • 3
    Maybe [`cURL`](http://php.net/curl) might be a better solution, if you need more wide control over the situation? – BlitZ Sep 04 '14 at 07:00
  • just, quick question, did you mean to name the variable in the `$data` portion `$passwort` or is it supposed to be named `$password`? – Jhecht Sep 04 '14 at 07:04
  • @Jhecht does it matter? Ok, so I guess the answer is "it's not possible" when using the file_get_contents function? – Howie Sep 04 '14 at 07:05
  • I agree with @HAL9000, cURL, or even better an HTTP client like Guzzle will make your life much easier: http://guzzle.readthedocs.org/en/latest/ – Onema Sep 04 '14 at 07:07
  • Look at this post - [How to post data in PHP using file_get_contents?](http://stackoverflow.com/questions/2445276/how-to-post-data-in-php-using-file-get-contents). So probably the naming of you post variables are wrong. – Zeusarm Sep 04 '14 at 07:07

1 Answers1

2

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.

Onema
  • 7,331
  • 12
  • 66
  • 102