web-dev-qa-db-ja.com

CURLOPT_POSTFIELDSのcurl POST形式

curl経由でPOSTを使用し、CURLOPT_POSTFIELDを設定する場合、urlencodeまたは特別な形式を使用する必要がありますか?

例:最初と最後の2つのフィールドを投稿する場合:

first=John&last=Smith

curlで使用する正確なコード/形式は何ですか?

$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$reply=curl_exec($ch);
curl_close($ch);
95
Ken

文字列を送信する場合は、urlencode()してください。それ以外の場合、配列の場合、key => valueペアになり、Content-typeヘッダーは自動的にmultipart/form-dataに設定されます。

また、配列のクエリを作成するために追加の関数を作成する必要はありません。既に持っています:

$query = http_build_query($data, '', '&');
94
kodeart

EDIT:php5以降では、 http_build_query の使用が推奨されます:

string http_build_query ( mixed $query_data [, string $numeric_prefix [, 
                          string $arg_separator [, int $enc_type = PHP_QUERY_RFC1738 ]]] )

マニュアルの簡単な例:

<?php
$data = array('foo'=>'bar',
              'baz'=>'boom',
              'cow'=>'milk',
              'php'=>'hypertext processor');

echo http_build_query($data) . "\n";

/* output:
foo=bar&baz=boom&cow=milk&php=hypertext+processor
*/

?>

php5:の前

manual から:

CURLOPT_POSTFIELDS

HTTP "POST"操作で投稿する完全なデータ。ファイルを送信するには、ファイル名の前に@を付けてフルパスを使用します。ファイルタイプは、ファイル名の後に「; type = mimetype」形式のタイプで明示的に指定できます。 このパラメーターは、「para1 = val1&para2 = val2&...」のようなurlencoded文字列として、またはフィールド名をキーとして、フィールドデータを値として持つ配列として渡すことができます。値が配列の場合、Content-Typeヘッダーはmultipart/form-dataに設定されます。PHP 5.2.0以降、このオプションに渡されるファイル@プレフィックスは機能するために配列形式でなければなりません。

したがって、このようなものは完璧に機能するはずです(連想配列で渡されるパラメーターを使用):

function preparePostFields($array) {
  $params = array();

  foreach ($array as $key => $value) {
    $params[] = $key . '=' . urlencode($value);
  }

  return implode('&', $params);
}
56
Czechnology

文字列をまったく渡さないでください!

配列を渡し、php/curlにエンコードなどの汚い仕事をさせることができます。

37
ThiefMaster

ここでまだ言及されていないもう1つの大きな違いは、CURLOPT_POSTFIELDSがネストされた配列を処理できないことです。

ネストされた配列['a' => 1, 'b' => [2, 3, 4]]を使用する場合、これはa=1&b[]=2&b[]=3&b[]=4としてパラメーター化する必要があります([および]はURLエンコードされます/すべきです)。これは、もう一方の端でネストされた配列に自動的に変換されます(ここでは、もう一方の端もPHPであると仮定します)。

これは動作します:

var_dump(http_build_query(['a' => 1, 'b' => [2, 3, 4]]));
// output: string(36) "a=1&b%5B0%5D=2&b%5B1%5D=3&b%5B2%5D=4"

これは機能しません:

curl_setopt($ch, CURLOPT_POSTFIELDS, ['a' => 1, 'b' => [2, 3, 4]]);

これにより通知されます。コードの実行は続行され、エンドポイントはパラメーターbを文字列"Array"として受け取ります。

PHP Notice:...の配列から文字列への変換...

3
7ochem

PHPマニュアルによると、文字列としてcURLに渡されるデータはURLエンコードする必要があります。 curl_setopt() のページを参照し、CURLOPT_POSTFIELDSを検索してください。

3
Surreal Dreams

ネストされた配列の場合、次を使用できます。

$data = [
  'name[0]' = 'value 1',
  'name[1]' = 'value 2',
  'name[2]' = 'value 3',
  'id' = 'value 4',
  ....
];
2
Max

CURLOPT_POSTFIELDSの場合、パラメーターはpara1=val1&para2=val2&..のようなurlencodeされた文字列として、またはフィールド名をキーとして、フィールドデータを値として持つ配列として渡すことができます。

次の形式を試してください:

$data = json_encode(array(
"first"  => "John",
"last" => "Smith"
));

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$output = curl_exec($ch);
curl_close($ch);
0

興味深いことに Postman がPOSTを行う方法は、次の2つの追加オプションを使用した完全なGET操作です。

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, '');

ちょうど別の方法で、非常にうまく機能します。

0
Klompenrunner