【问题标题】:How to send a multidimensional array with PHP cURL without array keys from the nested arrays?如何使用 PHP cURL 发送多维数组,而没有嵌套数组中的数组键?
【发布时间】:2019-10-25 10:14:27
【问题描述】:

简介

所以我试图将表单值作为查询字符串发送到 API。 API 需要这样的查询字符串:

&name=Charles+Hansen&email=example@email.com&locations=23433&locations=23231&propertyTypes=APARTMENT&propertyTypes=TOWNHOUSE&message=test"

正如您所见,根据用户在表单中选择的属性类型或位置的数量,有多个“属性类型”和“位置”。因此,我将所有 $_POST 数据存储在一个看起来像这样的多维数组中,因为我显然不能有多个具有相同名称“propertyTypes”或“locations”的键:

Array
(
    [name] => Charles Hansen
    [email] => example@email.com
    [locations] => Array
        (
            [0] => 23433
            [1] => 23231
        )
    [propertyTypes] => Array
        (
            [0] => APARTMENT
            [1] => TOWNHOUSE
        )
    [message] => test
)

cURL 不支持多维数组,因此我先自己构建查询,然后再使用它。这是我的 cURL 函数:

function sg_order($post_fields) {
    if($post_fields) {
        $query = http_build_query($post_fields);

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, 'https://example.com/order?orgKey=' . constant('ORG_KEY'));
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
          'Content-Type: application/x-www-form-urlencoded',                 
          'Content-Length: ' . strlen($query))
        );
        $result = curl_exec($ch);

        $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        if(curl_errno($ch)) {
          error_log('Curl error: ' . curl_error($ch) . $result);
        }else{
          error_log('Curl response: ' . $status);
        }
        curl_close($ch);

        return $result;
    }
}

orgKey 是验证的必需参数。

问题

我的问题是,$query = http_build_query($post_fields); 构建的查询包含嵌套数组的键([0]、[1] 等)。 $query 的结果如下所示:

&name=Charles+Hansen&email=example@email.com&locations[0]=23433&locations[1]=23231&propertyTypes[0]=APARTMENT&propertyTypes[1]=TOWNHOUSE&message=test"

如何删除键([0]、[1] 等),以使查询看起来完全符合 API 的预期?

其他信息

  • 我无法控制 API
  • 我不发送文件,因此解决方案不必处理文件

【问题讨论】:

  • 将其转换为 json 而不是尝试发送
  • @YasinPatel 我可以试试,但据我所知,他们的 API 只接受 URL 编码的字符串。如果我将其作为 json 发送,是否会因为 HTTPHEADER 设置而通过 curl 自动转换为 URL 编码字符串?
  • 如果您不想编写自己的 http_build_query 版本,那么我建议您修改 php.net/manual/en/function.http-build-query.php#111819,将匹配项替换为空字符串而不是 '%5B%5D'
  • @04FS 是的,行得通!谢谢!如果您做出回答,我会接受它作为解决方案。

标签: php curl php-curl


【解决方案1】:

如果您不想编写自己的 http_build_query 版本,那么我建议您根据手册中的此用户评论修改版本,http://php.net/manual/en/function.http-build-query.php#111819

    $query = http_build_query($query);
    $query = preg_replace('/%5B[0-9]+%5D/simU', '%5B%5D', $query);

他们在这里将 foo[xy] 替换为 foo[] - 因为您也不想保留 [],只需将 preg_replace 调用中的 '%5B%5D' 替换为空字符串即可。

【讨论】:

  • 再次感谢。额外问题:preg_replace 中的“simU”是什么意思?
  • php.net/manual/en/reference.pcre.pattern.modifiers.php : PCRE_DOTALL (恕我直言这里没用), PCRE_CASELESS (恕我直言这里没用), PCRE_MULTILINE (恕我直言这里没用), PCRE_UNGREEDY (恕我直言这里没用)。换句话说,对于这个特定的模式,不需要任何修饰符
  • @Piskvor 谢谢,同时我正在输入类似的回复。我唯一能看到也许在这里有点意义的是i - if http_build_query 有一天会不规律地改变它的行为,并返回小写方括号的百分比编码中的十六进制数字,然后 %5B%5D 仍然匹配 - 但不确定这种可能性有多大。其余的可能只是出于习惯而写的人添加的,我猜。
  • 无论如何都不匹配,[0-9][0123456789],AFAIK 这些没有小写/大写;)看起来像习惯,当然:这就是为什么我有资格“为此具体模式。”
  • @Piskvor 我指的是数字周围的大括号 - 这些在http_build_query 的返回值中被 URL 编码为 %5B%5D,并且是模式的一部分。如果http_build_query 决定有一天将它们返回为%5b%5d(就URL 编码而言,两个版本都是允许的),那么原样的模式仍然可以与i 修饰符一起使用。
猜你喜欢
  • 1970-01-01
  • 2015-01-31
  • 2018-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-15
  • 2023-01-26
相关资源
最近更新 更多