HTTP请求失败所需的长度

I humbly come before the people for some much needed assistance with this..

I am using (or trying to use) the skyscanner API - http://partners.api.skyscanner.net/apiservices/pricing/v1.0 as documented here. But I am coming up against this error:

HTTP request failed! HTTP/1.1 411 Length Required

PHP attempt 1

function getSkyScanner() {

    $url = 'http://partners.api.skyscanner.net/apiservices/pricing/v1.0?apiKey=MY-API-KEY';

    $headers = array(   'Content-Type' => 'application/x-www-form-urlencoded',
                        'Accept' => 'application/xml');

    $contextData = array ( 
            'method' => 'POST',
            'header' => $headers);

    $context = stream_context_create (array ( 'http' => $contextData ));
    $result = file_get_contents($url, false, $context);

    if ($result === FALSE) { echo 'error'; }
    var_dump($result);
}

My server doesn't support cURL so I'm in need of a solution without it. I'm using localhost with WAMP but I have also tried a live version which comes up with the same error and seemingly same problem. I have tried almost every combination of variables in order to correct the error with a discouraging amount of success (none). This is one such variation including the form contents that I am attempting to send.

PHP attempt 2

function getSkyScanner() {

    $url = 'http://partners.api.skyscanner.net/apiservices/pricing/v1.0?apiKey=MY-API-KEY';

    $params =   array(  'country' => 'GB',
                        'currency' => 'GBP',
                        'locale' => 'en-GB',
                        'originplace' => 'LHR',
                        'destinationplace' => 'EDI',
                        'outbounddate' => '2016-10-10',
                        'adults' => '1'
                );

    $query = http_build_query($params);

    $headers = array(   'Content-Type' => 'application/x-www-form-urlencoded',
                        'Accept' => 'application/xml');

    $contextData = array ( 
            'method' => 'POST',
            'header' => $headers,
            'content' => $query );

    $context = stream_context_create (array ( 'http' => $contextData ));
    $result = file_get_contents($url, false, $context);

    if ($result === FALSE) { echo 'error'; }
    var_dump($result);
}

This throws out:

Content-type not specified

Followed by:

HTTP/1.1 400 Bad Request

If you can help I would appreciate some insight right about now.

Many thanks!

You create headers in a wrong way - instead of an array, headers should be passed as a string.

$headers = "Content-Type: application/x-www-form-urlencoded
" .
           "Accept: application/xml
";

You can use below snippet to create the correct request:

function prepare_headers($headers) {
    return
    implode('', array_map(function($key, $value) {
            return "$key: $value
";
        }, array_keys($headers), array_values($headers))
    );
}

function http_post($url, $data, $ignore_errors = false) {
    $data_query = http_build_query($data);
    $data_len = strlen($data_query);

    $headers = array(
      'Content-Type' => 'application/x-www-form-urlencoded',
      'Accept' => 'application/xml',
      'Content-Length' => $data_len
    );

    $response = 
    file_get_contents($url, false, stream_context_create(
        array('http' => array(
                  'method' => 'POST',
                  'header' => prepare_headers($headers),
                  'content' => $data_query,
                  'ignore_errors' => $ignore_errors
                )
        )
    ));

    return (false === $response) ? false : 
        array(
            'headers' => $http_response_header,
            'body' => $response
        );
}

Example usage of http_post method:

$result = http_post('http://business.skyscanner.net/apiservices/pricing/v1.0', array(
  'apiKey' => 'YOUR_API_KEY',
  'country' => 'UK',
  'currency' => 'GBP',
  'locale' => 'en-GB',
  'locationSchema' => 'iata',
  'originplace' => 'EDI',
  'destinationplace' => 'LHR',
  'outbounddate' => '2016-10-10',
  'adults' => '1'
), false);

Parameter $ignore_errors in http_post method is reponsible for fetching the content even on failure status codes (400, 500, etc.). If you receive Bad request, set ignore_errors = true -> you'll receive full response from server.