I am troubleshooting some problems with POSTing to a remote site, specifically the remote host never returns any data (empty string).
Before I try to troubleshoot anything else, I want to make sure the calling code is actually correct. The code is:
$context = stream_context_create(array('http' => array(
'method' => "POST",
'header' => "Content-Type: application/xml",
'timeout' => 60.0,
'ignore_errors' => true, # return body even if HTTP status != 200
'content' => $send_xml
)));
$response = trim(file_get_contents($this->bulk_service_url, false, $context));
All my questions belong to the "header" option and it's values, and how to correctly format it and write it. The PHP documentation, discussion below it and even stackoverflow research yield very inconsistent results.
1) do I have to include the Content-Length header, and if not, will PHP calculate it correctly? The documentation does not include it, but I've seen many people include it manually, is it then respected or overwritten by PHP?
2) do I have to pass the header option as a string, or an associative array? Manual says string, majority pass it as a string, but this comment says that if PHP was compiled with --with-curlwrappers option, you have to pass it as an array. This is very inconsistent behavior.
3) when passing as a string, do I have to include terminating \r\n
characters? Especially when specifying just one header. Manual does not provide such an example, first comment on manual page does include it, second one does not, again, no clear rule on how to specify this. Does PHP automatically handle both cases?
The server is using PHP 5.3.
You should really store your headers within code as an array and finalize the preparation just prior to sending the request...
function prepareHeaders($headers) {
$flattened = array();
foreach ($headers as $key => $header) {
if (is_int($key)) {
$flattened[] = $header;
} else {
$flattened[] = $key.': '.$header;
}
}
return implode("\r\n", $flattened);
}
$headers = array(
'Content-Type' => 'application/xml',
'ContentLength' => $dl,
);
$context = stream_context_create(array('http' => array(
'method' => "POST",
'header' => prepareHeaders($headers),
'timeout' => 60.0,
'ignore_errors' => true,
'content' => $send_xml
)));
$response = trim(file_get_contents($url, FALSE, $context));
Preparing context try to add:
So it should look like:
$dl = strlen($send_xml);//YOUR_DATA_LENGTH
$context = stream_context_create(array('http' => array(
'method' => "POST",
'header' => "Content-Type: application/xml\r\nContentLength: $dl\r\n",
'timeout' => 60.0,
'ignore_errors' => true, # return body even if HTTP status != 200
'content' => $send_xml
)));
Just a little improvement of the suggestion by @doublejosh, in case it helps someone:
(use of array notation and one-liner lambda function)
$headers = [
'Content-Type' => 'application/xml',
'Content-Length' => strlen($send_xml)
];
$context = stream_context_create(['http' => [
'method' => "POST",
'header' => array_map(function ($h, $v) {return "$h: $v";}, array_keys($headers), $headers),
'timeout' => 60.0,
'ignore_errors'=> true,
'content' => $send_xml
]
]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With