2013-10-22 4 views
5

リモートサイトへのPOSTに関するいくつかの問題をトラブルシューティングしています。特に、リモートホストは決してデータ(空文字列)を返しません。PHPのstream_context_createとHTTPヘッダー - 配列または文字列、最後に r n、Content-Lengthはオプションですか?

何か他のトラブルシューティングを行う前に、呼び出しコードが実際に正しいかどうか確認したいと思います。コードは次のとおりです:

$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)); 

私の質問はすべて「ヘッダー」オプションに属しています。正しく値を書式設定して書き込む方法です。 PHPのドキュメント、その下の議論、さらにはstackoverflowの研究でさえも、一貫性のない結果が得られます。

1)Content-Lengthヘッダーを含める必要がありますか?そうでない場合、PHPは正しく計算しますか? The documentationには含まれていませんが、多くの人が手動でそれを組み込むのを見たことがありますが、それはPHPによって尊重されるか上書きされますか?

2)ヘッダーオプションを文字列または連想配列として渡す必要がありますか? Manualは文字列を示し、大部分を文字列として渡しますが、this commentは、PHPが--with-curlwrappersオプションでコンパイルされた場合、配列として渡す必要があると言います。これは非常に矛盾した動作です。

3)文字列として渡す場合、終了する文字を含む必要がありますか?\r\n文字ですか?特に1つのヘッダーを指定する場合。マニュアルはそのような例を提供していません。マニュアルページの最初のコメントはそれを含みます。もう1つは、もう一度、これを指定する方法に関する明確なルールはありません。 PHPは自動的に両方のケースを処理しますか?

サーバーでPHP 5.3が使用されています。

+0

私はfile_get_contentsの代わりにcURLを使うべきだと思います –

答えて

2

準備コンテキストが追加しよう:

  1. ん。ContentLength:\ r \ nの
  2. で始まる 'ヘッダ' キーで{here_calculated_length} "\ R \ n" は 'ヘッダ' キーの末尾。

だから、それは次のようになります。あなたは本当に配列としてコード内であなたのヘッダを格納し、直前にリクエストを送信する準備を確定する必要があり

$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 
     ))); 
4

...

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)); 
0

誰かを助ける場合に備えて@doublejoshによる提案のほんの少しの改善。

$headers = array(
    '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 
    ] 
]); 
関連する問題