当我通过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);
答案 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
*/
?>
:
来自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
要以标准方式发送数据,就像浏览器使用表单一样,只需传递关联数组即可。如PHP手册所述:
此参数可以作为诸如'para1 = val1&para2 = val2&...'的urlencoded字符串或以字段名称作为键且字段数据作为值的数组传递。如果value是一个数组,则Content-Type标头将设置为multipart / form-data。
无论如何,在与JSON API通信时,必须对API内容进行JSON编码才能理解我们的POST数据。
在这种情况下,必须将内容显式编码为JSON:
CURLOPT_POSTFIELDS => json_encode(['param1' => $param1, 'param2' => $param2]),
使用JSON进行通信时,我们通常还会相应地设置accept
和content-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¶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);
答案 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);