hyperf
hyperf使用guzzle发送http客户端请求使用方法及可能遇到的问题
11-20 17:17在 Hyperf 框架中,使用 Guzzle 作为 HTTP 客户端来发送请求是一种非常常见且被官方推荐的做法。Hyperf 框架对 Guzzle 进行了良好的集成和支持,让其在高性能的协程环境中也能稳定工作。
安装使用与注意事项,hyperf已给出文档:
https://hyperf.wiki/3.1/#/zh-cn/guzzle
Hyperf 并未对 Guzzle 用法进行重构,所以具体使用方法,参考 Guzzle 文档即可:
https://hyperf.wiki/3.1/#/zh-cn/guzzle
建议先阅读 Guzzle 文档,明白 Guzzle 可以做什么,以及基本使用方法,Hyperf 文档并未提及具体用法,所以对于不懂的人来讲,正确顺序应该是:Guzzle -> Hyperf
简单说一下使用方法
<?php
declare(strict_types=1);
namespace App\Controller;
use Hyperf\HttpServer\Annotation\AutoController;
//引入经过Hyperf修改后的Guzzle包,其它包不需要
use Hyperf\Guzzle\ClientFactory;
#[AutoController]
class CarController extends AbstractController{
//$options等同于 GuzzleHttp\Client 构造函数的$config参数
public array $options = [];
//$client为协程化的 GuzzleHttp\Client 对象
public $client;
public function __construct(private ClientFactory $clientFactory){
$this->client = $this->clientFactory->create($this->options);
}
//Guzzle HTTP客户端
public function guzzleHttp(){
try {
//POST请求的参数格式
$data = [
'form_params' => [
'field_name' => 'abc',
'other_field' => '123',
'nested_field' => [
'nested' => 'hello'
],
'connect_timeout' => 10, //连接超时时间
'timeout' => 30, //请求处理超时时间
]
];
//发起POST请求,方式一
$response = $this->client->post('https://xxx.xxx.xxx/api.php?c=test', $data);
//发起POST请求,方式二
$response = $this->client->request('POST', 'https://xxx.xxx.xxx/api.php?c=test', $data);
//发起GET请求
$response = $this->client->get('http://apis.juhe.cn/cxdq/brand?key=00e9df85141a48bea7669aff2026e5c3');
//获取响应状态码,成功200
$statusCode = $response->getStatusCode();
if ($response->getStatusCode() != 200) {
//请求失败
}
//获取消息正文
$body = $response->getBody();
//获取响应体(字符串形式)
$content = $body->getContents();
return $content;
}catch (\Exception $e){
return $e->getMessage();
}
}
//Guzzle Http客户端保存远程文件
public function guzzleSaveRemoteFile(){
//远程文件URL
$remoteUrl = 'https://xxx.com/api_image/demo.png';
//本地保存路径,BASE_PATH 常量返回项目在服务器的绝对路径,比如:/www/project/
$localPath = BASE_PATH . '/public/demo.png';
try {
//下载文件
$response = $this->client->get($remoteUrl, [
'sink' => $localPath //sink选项指定保存路径
]);
if ($response->getStatusCode() === 200) {
return ['status' => 'success', 'path' => $localPath]; //保存成功
} else {
return ['status' => 'error', 'message' => '文件下载失败'];
}
} catch (\Exception $e) {
return ['status' => 'error', 'message' => $e->getMessage()];
}
}
?>
有个比较微小的问题,当接口同时具备80和443端口时,也就是http和https都能访问,但http会强转到https,使用 Guzzle 可能会出现没有等到301或302状态出现时,即返回结果
这样会出现的问题是,post请求可能无法及时传递和接收参数,当然在 Guzze 中,它的说明是默认跟随rewrite,但实际测试却无法获取参数
这个问题也可能和nginx等配置有关,但出现这样的问题时,不妨检查一下接口中的http是否未加s