cURL POST请求有效,Guzzle 6没有

时间:2018-05-11 20:27:04

标签: php guzzle6

上下文

我一直在努力弄清楚如何让这项工作工作一段时间,而我根本不明白为什么Guzzle不会为这个特殊的请求工作。相同的初始化和请求结构在我的一些基本单元测试中起作用,但是当涉及API到API通信时,Guzzle只是没有合作。

问题:

我的意思是,它不包括我在$headers数组中设置的标题,并且请求正文为空。

期望的结果:

为了确认这是Guzzle的一个问题,我已经用典型的cURL语法写出了请求,并且请求很顺利。我只需要一些关于如何使用Guzzle来完成这项工作的指导,因为我喜欢Guzzle提供的抽象提示而不是详细的cURL请求。

工作cURL请求:

    $headers = array(
        'Authorization: Bearer '.$sharedSecret,
        'Content-Type: application/x-www-form-urlencoded',
        'Accept: application/json',
        'Content-Length: '.strlen($loginDetails),
    );

    $curlOptions = array(
        CURLOPT_URL             => API_URL.'member/SessionManager',
        CURLOPT_HTTPHEADER      => $headers,
        CURLOPT_RETURNTRANSFER  => FALSE,
        CURLOPT_HEADER          => FALSE,
        CURLOPT_FOLLOWLOCATION  => FALSE,
        CURLOPT_ENCODING        => "",
        CURLOPT_USERAGENT       => "PORTAL",
        CURLOPT_AUTOREFERER     => TRUE,
        CURLOPT_CONNECTTIMEOUT  => 120,
        CURLOPT_TIMEOUT         => 120,
        CURLOPT_MAXREDIRS       => 10,
        CURLOPT_POST            => TRUE,
        CURLOPT_POSTFIELDS      => $loginDetails,
        CURLOPT_SSL_VERIFYHOST  => FALSE,
        CURLOPT_SSL_VERIFYPEER  => FALSE,
        CURLOPT_VERBOSE         => FALSE
    );

    try {
        $ch = curl_init();
        curl_setopt_array($ch,$curlOptions);
        $content    = curl_exec($ch);
        $err        = curl_errno($ch);
        $errmsg     = curl_error($ch);
        $response   = curl_getinfo($ch);
        curl_close($ch);

        if ($content === FALSE) {
            throw new Exception(curl_error($ch), curl_errno($ch));
        } else {
            return true;
        }
    } catch(Exception $e) {
        trigger_error(sprintf('Curl failed with error #%d: %s', $e->getCode(), $e->getMessage()), E_USER_ERROR);
    }

Guzzle客户端在一个全局文件中初始化,该文件创建一个容器,用于存储我们在整个应用程序中使用的各种对象。我包括它,以防我错过了Guzzle的文档中没有的重要内容。

Guzzle初始化:

$container['client'] = function ($c) {
    return new \GuzzleHttp\Client([
        'base_uri'          => API_URL,
        'timeout'           => 30.0,
        'allow_redirects'   => true,
        'verify'            => false,
        'verbose'           => true,
        [
            'headers'   => [
                'Authorization' => 'Bearer '.$sharedSecret,
            ]
        ],
    ]);
};

非工作Guzzle请求:

    $headers = array(
        'Authorization' => 'Bearer '.$sharedSecret,
        'Content-Type'  => 'application/x-www-form-urlencoded',
        'Accept'        => 'application/json',
        'Content-Length'=> strlen($loginDetails),
    );

    try {
        $response = $this->client->post('/api/member/SessionManager',
            ['debug'            => true],
            ['headers'          => $headers],
            ['body'             => $loginDetails]
        );

        if($response) {
            $this->handleResponse($response);
        }

    } catch (GuzzleHttp\Exception\ClientException $e) {
        $response->getResponse();
        $responseBodyAsString = $response->getBody()->getContents();
    }

我是否在Guzzle初始化中删除了headers数组,这并不重要。授权标头在请求中找不到(通过tcpdump,Wireshark和接收API错误日志记录确认),Guzzle的调试输出不显示我的标头,也不显示我的请求正文在请求中的任何位置。

我难以理解为什么这不起作用,而且非常想了解。我可以走不使用Guzzle的路线,但由于简洁,我真的更喜欢。任何意见都将不胜感激。

2 个答案:

答案 0 :(得分:3)

cURL 请求中,被调用的API URL为

  

API_URL.'member/SessionManager'

Guzzle 请求中,所调用的API URL带有额外的文本“ / api /” (假设两种情况下API_URL的定义都相同)

  

new \GuzzleHttp\Client([ 'base_uri' => API_URL,

     

...

     

$this->client->post('/api/member/SessionManager',

答案 1 :(得分:0)

很高兴知道这个问题很久了,但是我想分享自己的经验,因为我对此也感到很苦恼。等同于:

CURLOPT_POSTFIELDS      => $loginDetails,

在Guzzle中是:

"query" => $loginDetails

此外,我发现,如果base_uri不以/结尾,则Guzzle会误解它。

请记住,您的POST请求应如下:

        $response = $this->client->post('api/member/SessionManager', // Removed the first / as it's part of the base_uri now
            ['debug'            => true],
            ['headers'          => $headers],
            ['query'            => $loginDetails] // Replaced "body" with "query"
        );