Php CURLOPT_POSTFIELDS的curl POST格式

Php CURLOPT_POSTFIELDS的curl POST格式,php,post,curl,Php,Post,Curl,当我通过POST使用curl并设置CURLOPT\u POSTFIELD时,我必须urlencode或任何特殊格式吗 例如:如果我想发布两个字段,第一个和最后一个: first=John&last=Smith curl应该使用的确切代码/格式是什么 $ch=curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURL

当我通过
POST
使用
curl
并设置
CURLOPT\u POSTFIELD
时,我必须
urlencode
或任何特殊格式吗

例如:如果我想发布两个字段,第一个和最后一个:

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

根据PHP手册,作为字符串传递给cURL的数据应该进行URL编码。请参阅页面以查找和搜索
CURLOPT_POSTFIELDS

编辑:从php5开始,建议使用:

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
*/

?>

如果您发送的是字符串,urlencode()会将其删除。否则,如果是数组,则它应该是key=>value paired,并且
内容类型
标题将自动设置为
多部分/表单数据

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

$query = http_build_query($data, '', '&');
一根绳子都不要传!
你可以传递一个数组,让php/curl做编码等脏活。

这个答案我也花了很长时间才找到。我发现您所要做的就是将URL(文件名和扩展名后的“?”)与URL编码的查询字符串连接起来。看起来您甚至不必设置后卷曲选项。请参见下面的示例:

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

对于
CURLOPT_POSTFIELDS
,参数可以作为URL编码的字符串传递,如
para1=val1¶2=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);

这里还没有提到的另一个主要区别是
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注意:数组到字符串的转换。。。在线


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

$data = [
  'name[0]' = 'value 1',
  'name[1]' = 'value 2',
  'name[2]' = 'value 3',
  'id' = 'value 4',
  ....
];
有趣的是,does POST是一个完整的GET操作,包含以下两个附加选项:

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, '');
另一种方式,效果非常好。

这取决于
内容类型
url编码或多部分/表单数据 要以标准方式发送数据,就像浏览器使用表单一样,只需传递关联数组即可。如PHP手册所述:

此参数可以作为urlencoded字符串(如“para1=val1¶2=val2&…”)传递,也可以作为以字段名为键、字段数据为值的数组传递。如果值是数组,则内容类型标头将设置为多部分/表单数据

JSON编码 然而,当与JSON API通信时,必须对内容进行JSON编码,以便API理解我们的POST数据

在这种情况下,内容必须明确编码为JSON:

CURLOPT_POSTFIELDS=>json_encode(['param1'=>$param1,'param2'=>$param2]),
在使用JSON进行通信时,我们通常也会相应地设置
accept
content-type
标题:

CURLOPT_HTTPHEADER=>[
'接受:应用程序/json',
'内容类型:应用程序/json'
]

如果可以传递数组,为什么要传递字符串…?我认为$key也应该进行编码,以防出现类似“name&nam姓氏”等的情况。特别是如果数据是在末尾给出的user@barius,我同意你的看法。我认为http_build_query()实际上比上面定义的函数要好。@skyfree我同意!该函数是在php5中添加的,尽管它在2011年还远未达到标准。当您可以只传递数组时,为什么需要http_build_查询?传递数组的内容类型将与传递字符串的内容类型不同,因此有很好的理由这样做。我花了一段时间才弄明白。我不知道为什么,但我发现在我的win-dev pc上传递一个数组需要大约一秒钟的时间(1.029秒使用数组,而0.016秒使用
http\u build\u query()
在同一个数组上)嵌套数组无法工作。cURL将尝试将它们转换为字符串,随后会出现一个PHP数组到字符串转换通知。看起来您正在执行GET而不是POST。您可以使用
http\u build\u query($data)
,因为
&
是默认分隔符。当然,您可以跳过它们。这是为了说明另外两个参数,您可以(也可以不)更改(例如默认分隔符)以满足您的特定需要。您好,Shraddha,
json\u encode()
将为您提供与有效参数字符串完全不同的内容,如
first=John&last=Smith
json_encode()
将输出:
{“first”:“John”,“last”:“Smith”}
,这将成为POST请求的原始正文。要添加到@7ochem的注释中:除非收件人希望一个包含json编码字符串的参数,而不是
json_encode(…)
do
http_build_query(…)
。这将创建预期的“url编码字符串”,其中包含由“&”分隔的参数。
$data = [
  'name[0]' = 'value 1',
  'name[1]' = 'value 2',
  'name[2]' = 'value 3',
  'id' = 'value 4',
  ....
];
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, '');