上下文
我一直在努力弄清楚如何让这项工作工作一段时间,而我根本不明白为什么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的路线,但由于简洁,我真的更喜欢。任何意见都将不胜感激。
答案 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"
);