卷曲CURLOPT_POSTFIELDS的POST格式

时间:2011-03-07 20:20:57

标签: php post curl

当我通过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);

10 个答案:

答案 0 :(得分:94)

如果您要发送字符串,请输入urlencode()。否则,如果是数组,则应将key =>值配对,并将Content-type标头自动设置为multipart/form-data

此外,您不必创建额外的函数来构建阵列的查询,您已经拥有:

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

答案 1 :(得分:56)

编辑:从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'的类型的文件名来明确指定文件类型。 此参数既可以作为urlencoded字符串传递,例如'para1 = val1&amp; para2 = val2&amp; ...',也可以作为数组传递,字段名称为键,字段数据为值。如果value是一个数组,则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);
}

答案 2 :(得分:37)

根本不传递字符串!

你可以传递一个数组,让php / curl完成编码等的脏工作。

答案 3 :(得分:5)

这取决于content-type

采用网址编码或multipart / form-data

要以标准方式发送数据,就像浏览器使用表单一样,只需传递关联数组即可。如PHP手册所述:

此参数可以作为诸如'para1 = val1&para2 = val2&...'的urlencoded字符串或以字段名称作为键且字段数据作为值的数组传递。如果value是一个数组,则Content-Type标头将设置为multipart / form-data。

JSON编码

无论如何,在与JSON API通信时,必须对API内容进行JSON编码才能理解我们的POST数据。

在这种情况下,必须将内容显式编码为JSON:

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

使用JSON进行通信时,我们通常还会相应地设置acceptcontent-type标头:

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

答案 4 :(得分:3)

根据PHP手册,作为字符串传递给cURL的数据应该是URLencoded。请参阅curl_setopt()页面并搜索CURLOPT_POSTFIELDS

答案 5 :(得分:3)

此处尚未提及的另一个主要区别是CURLOPT_POSTFIELDS无法处理嵌套数组。

如果我们使用嵌套数组['a' => 1, 'b' => [2, 3, 4]],则应将其参数化为a=1&b[]=2&b[]=3&b[]=4({/ {1}}和[将被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

  

PHP注意:在线...上的数组到字符串的转换...

答案 6 :(得分:2)

对于嵌套数组,您可以使用:

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

答案 7 :(得分:0)

对于CURLOPT_POSTFIELDS,参数可以作为urlencoded字符串传递,如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);

答案 8 :(得分:0)

有趣的是,Postman进行POST的方式是使用以下两个附加选项的完整GET操作:

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

另一种方式,并且效果很好。

答案 9 :(得分:-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);