CURLOPT_POSTFIELDSのcurl POST形式


99

curlvia POSTとset を使用する場合、CURLOPT_POSTFIELDto 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);

回答:


100

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

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

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

13
はデフォルトの区切り文字なhttp_build_query($data)ので&、そのまま使用できます。
nullability 2014

6
もちろん、スキップすることもできます。これは、特定のニーズに合わせて変更できる(または変更できない)他の2つの引数(デフォルトのセパレーターなど)を示すためのものです。
kodeart 2014

62

編集: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の前:

マニュアルから:

CURLOPT_POSTFIELDS

HTTP "POST"操作で送信する完全なデータ。ファイルを投稿するには、ファイル名の前に@を付け、フルパスを使用します。ファイルタイプは、ファイル名の後に「; type = mimetype」の形式のタイプを付けることで明示的に指定できます。このパラメーターは、 'para1 = val1&para2 = val2&...'のようなURLエンコードされた文字列として、またはフィールド名をキーとして、フィールドデータを値として持つ配列として渡すことができます。値が配列の場合、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);
}

11
配列を渡すことができるのに、なぜ文字列を渡すのでしょうか?
ThiefMaster 2011年

1
$ keyも "name&surname"などのようにエンコードする必要があると思います。特にエンドユーザーからデータが提供される場合
MariusBalčytis12年

2
@barius、私はあなたに同意します。そして、http_build_query()は実際には上記で定義された関数よりも優れていると思います。
スカイフリー、2014

1
@skyfree同意する!この関数はphp5に追加されましたが、2011
でした。–チェコ語

1
配列を渡すだけでhttp_build_queryが必要なのはなぜですか?
Offenso 2017年

39

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

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


16
配列を渡すと、文字列とは異なるContent-typeになるため、そうするのには十分な理由があります。それを理解するのにしばらくかかりました。
Thomas Vander Stichele、2012年

理由はわかりませんが、私のwin dev pcで配列を渡すと約1秒長くかかることがわかります(配列を使用http_build_query()する1.029秒と同じ配列を使用する
0.016秒

2
ネストされた配列は機能しません。cURLはそれらを文字列に変換しようとし、PHP 配列から文字列への変換通知が続きます
7ochem

5

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


4

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

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

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

2
こんにちはShraddhaさん。json_encode()有効なパラメータ文字列とはまったく異なるものを提供しますfirst=John&last=Smithjson_encode()出力:{"first":"John","last":"Smith"}POSTリクエストの未加工のボディになります。
7ochem

1
@ 7ochemのコメントに追加するには:受信者が、jsonでエンコードされた文字列を含む単一のパラメーターを期待している場合を除き、json_encode(...)do ではありませんhttp_build_query(...)。これにより、「&」で区切られたパラメーターを含む、予期される「URLエンコードされた文字列」が作成されます。
ToolmakerSteve

4

ここでまだ言及されていないもう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の通知:行...の配列から文字列への変換


4

それは content-type

url-encodedまたはmultipart / form-data

標準的な方法でデータを送信するには、ブラウザの場合と同様に、連想配列を渡します。PHPのマニュアルで述べられているように:

このパラメーターは、 'para1 = val1&para2 = val2&...'のようなURLエンコードされた文字列として、またはフィールド名をキーとして、フィールドデータを値として持つ配列として渡すことができます。値が配列の場合、Content-Typeヘッダーはmultipart / form-dataに設定されます。

JSONエンコーディング

それでも、JSON APIと通信する場合、APIがPOSTデータを理解するには、コンテンツをJSONエンコードする必要があります。

このような場合、コンテンツはJSONとして明示的にエンコードする必要があります。

CURLOPT_POSTFIELDS => json_encode(['param1' => $param1, 'param2' => $param2]),

JSONで通信する場合、我々はまた、通常設定acceptcontent-typeそれに応じて、ヘッダー:

CURLOPT_HTTPHEADER => [
    'accept: application/json',
    'content-type: application/json'
]

2

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

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

0

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

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

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


-3

この答えは、私を見つけるのにも永遠にかかりました。URL(ファイル名と拡張子の後ろの「?」)をURLエンコードされたクエリ文字列と連結するだけでよいことがわかりました。POST cURLオプションを設定する必要があるようにも見えません。以下の偽の例を参照してください。

//create URL
$exampleURL = 'http://www.example.com/example.php?';

// create curl resource
$ch = curl_init(); 

// build URL-encoded query string
$data = http_build_query(
    array('first' => 'John', 'last' => 'Smith', '&'); // set url
curl_setopt($ch, CURLOPT_URL, $exampleURL . $data); 

// return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 

// $output contains the output string
$output = curl_exec($ch); 

// close curl resource to free up system resources <br/>
curl_close($ch);

あなたも使うことができますfile_get_contents()

// read entire webpage file into a string
$output = file_get_contents($exampleURL . $data);

9
POSTではなくGETを実行しているようです。
祖父2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.