卷曲CURLOPT_POSTFIELDS的POST格式

Ken*_*Ken 96 php post curl

当我使用curlvia POST和set时CURLOPT_POSTFIELD,我必须urlencode或任何特殊格式?

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

first=John&last=Smith
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

kod*_*art 95

如果你要发送一个字符串,urlencode()它.否则,如果是数组,则应该是key => value paired并且Content-type标头会自动设置为multipart/form-data.

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

$query = http_build_query($data, '', '&');
Run Code Online (Sandbox Code Playgroud)

  • 你可以使用`http_build_query($ data)`因为`&`是默认的分隔符. (11认同)
  • 当然你可以跳过它们.这是为了说明您可能(或可能不)更改的其他两个参数(例如默认分隔符)以满足您的特定需求. (6认同)

Cze*_*ogy 57

编辑:从PHP5以上,http_build_query建议使用:

string http_build_query ( mixed $query_data [, string $numeric_prefix [, 
                          string $arg_separator [, int $enc_type = PHP_QUERY_RFC1738 ]]] )
Run Code Online (Sandbox Code Playgroud)

手册中的简单示例:

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

?>
Run Code Online (Sandbox Code Playgroud)

在php5之前:

手册:

CURLOPT_POSTFIELDS

要在HTTP"POST"操作中发布的完整数据.要发布文件,请在文件前加上@并使用完整路径.可以通过使用格式为'; type = mimetype'的类型的文件名来明确指定文件类型.此参数可以作为urlencoded字符串传递,如'para1 = val1¶2 = val2&...',也可以作为数组传递,字段名称为键,字段数据为值.如果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);
}
Run Code Online (Sandbox Code Playgroud)

  • 如果可以传递数组,为什么要传递一个字符串? (11认同)
  • @barius,我同意你的看法.我认为http_build_query()实际上比上面定义的函数更好. (2认同)

Thi*_*ter 38

根本不要传递一个字符串!

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

  • 传递一个数组将是一个与字符串不同的Content-type,所以有充分的理由这样做.我花了一段时间来弄清楚这一点. (16认同)
  • 嵌套数组将不起作用。cURL将尝试将其转换为字符串,然后将PHP _Array转换为字符串conversion_ (2认同)

7oc*_*hem 8

此处尚未提及的另一个主要区别是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"
Run Code Online (Sandbox Code Playgroud)

这行不通:

curl_setopt($ch, CURLOPT_POSTFIELDS, ['a' => 1, 'b' => [2, 3, 4]]);
Run Code Online (Sandbox Code Playgroud)

这会给你一个通知。代码执行将继续,您的端点将接收b字符串形式的参数"Array"

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


小智 7

对于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);
Run Code Online (Sandbox Code Playgroud)

  • 嗨 Shraddha,`json_encode()` 会给你一些真正不同的有效参数字符串,如 `first=John&amp;last=Smith`。`json_encode()` 将输出:`{"first":"John","last":"Smith"}` 它将成为你的 POST 请求的原始正文。 (3认同)

Sur*_*ams 6

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


Buz*_*zut 6

这取决于 content-type

url-encoded 或 multipart/form-data

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

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

JSON 编码

尽管如此,在与 JSON API 通信时,内容必须是 JSON 编码的 API 才能理解我们的 POST 数据。

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

CURLOPT_POSTFIELDS => json_encode(['param1' => $param1, 'param2' => $param2]),
Run Code Online (Sandbox Code Playgroud)

在 JSON 中进行通信时,我们通常也会相应地设置acceptcontent-type标头:

CURLOPT_HTTPHEADER => [
    'accept: application/json',
    'content-type: application/json'
]
Run Code Online (Sandbox Code Playgroud)