【问题标题】:PHP cURL GET request and request's bodyPHP cURL GET 请求和请求正文
【发布时间】:2013-06-18 06:57:42
【问题描述】:

我正在尝试将 cURL 用于这样的 GET 请求:

function connect($id_user){
    $ch = curl_init();
    $headers = array(
    'Accept: application/json',
    'Content-Type: application/json',

    );
    curl_setopt($ch, CURLOPT_URL, $this->service_url.'user/'.$id_user);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    $body = '{}';

    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET"); 
    curl_setopt($ch, CURLOPT_POSTFIELDS,$body);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    // Timeout in seconds
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);

    $authToken = curl_exec($ch);

    return $authToken;
}

如您所见,我想将 $body 作为请求的正文传递,但我不知道它是否正确,实际上我无法调试,您知道是否有权使用 curl_setopt($ch, CURLOPT_POSTFIELDS,$body);使用 GET 请求?

因为整个代码与 POST 完美配合,现在我正在尝试将其更改为 GET,如您所见

【问题讨论】:

标签: php curl http-get


【解决方案1】:

接受的答案是错误的。 GET requests 确实可以包含正文。这是解决方案implemented by WordPress,例如:

curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, 'GET' );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $body );

编辑:澄清一下,在这种情况下,初始 curl_setopt 是必需的,因为当使用 CURLOPT_POSTFIELDS 时,libcurl 会将 HTTP 方法默认为 POST(请参阅 documentation)。

【讨论】:

  • 对于CURLOPT_CUSTOMREQUEST,不需要使用GET,因为在PHP 中使用libcurl 实现意味着每个请求都是GETHEAD 类型。所以基本上没有对GET 的官方支持,而 Wordpress 代码正在做它最擅长的事情——创建冗余。
  • 明确指出类型有什么危害呢?通过这样做,他们避免了需要额外的 case 语句。它涵盖了GETDELETEPATCH 等。恕我直言,代码更简洁。
  • 然而request 函数仍然设置默认值,其中包括GET 作为默认请求方法。 Wordpress 不是编写良好代码的一个很好的例子。
  • 你真的看过引用的代码吗?上例中的GET 实际上是一个变量。听起来你是一个 Web 开发者,他对 WP 让任何人都能够编写网站而感到恼火,这让你失业了 ;)
  • $r['method'](第 1424 行)是从 request 函数参数(第 1361 行)中提取的,该参数由 wb_parse_args 函数处理,另一方面,该函数使用默认值(第 1354 行)以防万一没有请求选项被request 函数参数覆盖。这一切都在代码中,您只需要知道如何阅读它。而且我不处理像 Wordpress 这样的软件。
【解决方案2】:
  <?php
  $post = ['batch_id'=> "2"];
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL,'https://example.com/student_list.php');
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
  $response = curl_exec($ch);
  $result = json_decode($response);
  curl_close($ch); // Close the connection
  $new=   $result->status;
  if( $new =="1")
  {
    echo "<script>alert('Student list')</script>";
  }
  else 
  {
    echo "<script>alert('Not Removed')</script>";
  }

  ?>

【讨论】:

  • 为什么人们坚持用[]的方式来使用数组?太丑了。
  • @FernandoTorres 因为只输入[] 比输入array() 短得多
  • @Siddharth 问题是关于 GET 请求正文而不是 POST
【解决方案3】:

对于那些遇到类似问题的人,this request library 允许您在 php 应用程序中无缝地发出外部 http 请求。简化的 GET、POST、PATCH、DELETE 和 PUT 请求。

示例请求如下所示

use Libraries\Request;

$data = [
  'samplekey' => 'value',
  'otherkey' => 'othervalue'
];

$headers = [
  'Content-Type' => 'application/json',
  'Content-Length' => sizeof($data)
];

$response = Request::post('https://example.com', $data, $headers);
// the $response variable contains response from the request

可以在项目的README.md中找到相同的文档

【讨论】:

    【解决方案4】:

    CURLOPT_POSTFIELDS 顾名思义,用于POST 请求的主体(有效负载)。对于GET 请求,有效负载是查询字符串形式的 URL 的一部分。

    在您的情况下,您需要使用需要发送的参数(如果有)构造 URL,并删除 cURL 的其他选项。

    curl_setopt($ch, CURLOPT_URL, $this->service_url.'user/'.$id_user);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    
    //$body = '{}';
    //curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET"); 
    //curl_setopt($ch, CURLOPT_POSTFIELDS,$body);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    

    【讨论】:

    • @BurhanKhalid 你所说的并不完全正确。 The GET method 不允许 GET 请求的正文,无论如何我对 php 的 cURL 绑定一无所知。 Badbetonbreakbutbedbackbone:搜索你的问题我发现了这个项目尝试it
    • 我没有说不允许,我说GET 是这样工作的。您可以在请求正文中传递任意数量的内容,但其他服务器将忽略它们。请求的有效负载(您打算发送的数据)才是最重要的;对于GET,它位于查询字符串中。
    • 如何通过客户端的实际调用知道服务器是如何管理请求的?由于该问题暗示 badbetonbreakbutbedbackbone 需要查询管理 GET 请求正文的服务器,我认为您编写的内容根本不正确,因此先验查询的服务器丢弃信息是不正确的。只是我的 2 美分。
    • 所以,我对这个问题的理解是 php 客户端如何在 GET 请求中发送正文(他只知道它在 PUT 和 POST 中执行类似操作的选项)。在我写第一条评论之前,我检查了是否通过 cURL(bash 命令)和 httpie(httpie.org),是否有可能在 GET 请求中发送正文。因此,当我意识到 GET 请求中的正文已发送时,我检查了 RFC 以确认它。为了再次保证自己,我编写了一个简单的 express.js 服务器,其中包含一个包含请求日志的 GET 路由:当我再次通过 httpie 查询它时,我看到了我在正文中传递的内容。 :)
    • 这不是正确的答案。它甚至没有回答最初的问题。可以在请求正文中使用 URI 之外的 GET 方法发送请求有效负载。 @Dario,不幸的是,Guzzle 不支持它,因为它不在规范中。
    【解决方案5】:

    你已经用正确的方式完成了

    curl_setopt($ch, CURLOPT_POSTFIELDS,$body);
    

    但我注意到你不见了

    curl_setopt($ch, CURLOPT_POST,1);
    

    【讨论】:

    • 那我为什么要用那个sorry呢?
    • 因为您使用的是 POST 字段,所以您必须发出 post 请求
    • 按照@Khalid 下面所说的去做
    • 这也不是这个问题的答案。 REST 指定您必须使用 GET 请求来检索信息,并且您可能希望在请求有效负载中发送一些过滤器。将方法切换为 POST 会破坏问题的原始规范。在 GET 方法中发送有效负载是可能的,我只是不确定 libcurl。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-24
    • 2021-03-29
    • 1970-01-01
    • 2020-10-10
    相关资源
    最近更新 更多