Guzzle 7.8调用ERP Rest API时base_uri被忽略的问题求助
Guzzle 7.8连接ERP API时base_uri被忽略的问题
我尝试用Guzzle连接ERP系统的Rest API,代码如下:
$client = new GuzzleHttp\Client([ 'base_uri' => "{$this->getBaseUrl()}{$this->getClient()}/", 'timeout' => 10, 'auth' => [$this->getUsername(), $this->getPassword()], 'headers' => $this->getHeader(), ]); $response = $client->request($this->getMethod(), $this->getUrl(), [ 'json' => $request, ]); return $response;
参数说明:
$this->getBaseUrl()返回http://ipaddressofclient:8080/mw/r/$this->getClient()返回erp,因此base_uri最终为http://ipaddressofclient:8080/mw/r/erp/,调试已确认该值正确$this->getUrl()返回obj/data/2:1/query
运行时抛出ConnectException异常,错误信息:
cURL error 6: Could not resolve host: obj,请求地址为http://obj:1/data/2:1/query
明显配置的base_uri被完全忽略,使用的是Guzzle 7.8版本,请问问题出在哪里?
补充:调试时$client->request()的变量情况如下:
问题原因与解决方案
原因
Guzzle的URI解析逻辑会将路径中包含:的片段误判为「主机:端口」格式。你的请求路径obj/data/2:1/query里的2:1被Guzzle错误解析:把obj/data/2当成主机,1当成端口,因此完全忽略了预设的base_uri,直接尝试连接obj这个不存在的主机。
解决方案
可以通过以下两种方式解决:
- URL编码路径中的特殊字符
对路径里包含:的片段进行编码,避免Guzzle误解析:
// 对路径的每个片段单独编码,保留/分隔符 $rawUrl = $this->getUrl(); $encodedUrl = preg_replace_callback('#/([^/]+)#', function ($matches) { return '/' . rawurlencode($matches[1]); }, $rawUrl); $response = $client->request($this->getMethod(), $encodedUrl, [ 'json' => $request, ]);
编码后2:1会变成2%3A1,Guzzle就能正确识别这是路径的一部分。
- 使用Guzzle的Uri类手动拼接URI
借助Guzzle内置的Uri类来确保URI拼接的正确性:
use GuzzleHttp\Psr7\Uri; // 构造基础URI $baseUri = new Uri($this->getBaseUrl() . $this->getClient() . '/'); // 解析并拼接请求路径 $requestUri = Uri::resolve($baseUri, $this->getUrl()); $response = $client->request($this->getMethod(), $requestUri, [ 'json' => $request, ]);
这种方式会严格按照URI规范处理路径,避免特殊字符导致的解析错误。
内容的提问来源于stack exchange,提问作者Borbás Kálmán
相关产品推荐
相关产品推荐

