Yii2 Client类实现通用REST API调用及POST参数设置问题
基于Yii2 Client类实现统一REST API调用方案
1. 实现POST请求的postFields参数传递
Yii2的yii\httpclient\Client没有单独的setPostFields方法,但可以通过设置请求体实现相同效果,根据数据格式不同有两种处理方式:
方式一:表单格式(application/x-www-form-urlencoded)
如果$postFields是键值对数组,直接赋值给请求的formParams属性:
use yii\httpclient\Client; public function callApi($method, $action, $headers = [], $data = [], $postFields = []) { $client = new Client(); $request = $client->createRequest() ->setMethod($method) ->setUrl($action) ->setHeaders($headers); // 处理GET等请求的查询参数 if (!empty($data)) { $request->setData($data); } // 处理POST请求的postFields if ($method === 'POST' && !empty($postFields)) { // 自动设置Content-Type为application/x-www-form-urlencoded $request->setFormParams($postFields); } $response = $request->send(); return $response->isOk ? $response->data : $response->getContent(); }
方式二:JSON格式(application/json)
如果需要发送JSON格式的POST数据,使用setJsonBody方法:
// 替换POST处理部分 if ($method === 'POST' && !empty($postFields)) { $request->setJsonBody($postFields); }
如果要支持多种格式,可以新增参数指定格式,或根据$postFields类型自动判断。
2. 统一调用方案优化建议
- 参数简化:合并
$data和$postFields,根据请求方法自动区分:GET/HEAD等用参数作为查询串,POST/PUT等作为请求体,减少冗余参数。 - 客户端复用:不要每次调用都新建
Client实例,将其作为类属性初始化一次,提升性能。 - 异常处理:用
try-catch包裹请求发送逻辑,捕获网络错误、超时等异常并抛出自定义异常,便于上层处理。 - 日志记录:添加请求日志,记录请求方法、URL、参数和响应结果,方便排查问题。
优化后的示例:
class ApiClient { private $client; public function __construct() { $this->client = new Client([ 'baseUrl' => 'https://your-api-base-url.com', 'timeout' => 10, ]); } public function call($method, $action, $params = [], $headers = [], $format = Client::FORMAT_JSON) { $request = $this->client->createRequest() ->setMethod($method) ->setUrl($action) ->setHeaders($headers); $method = strtoupper($method); if (in_array($method, ['GET', 'HEAD', 'DELETE'])) { $request->setData($params); } else { switch ($format) { case Client::FORMAT_FORM_URLENCODED: $request->setFormParams($params); break; case Client::FORMAT_JSON: $request->setJsonBody($params); break; case Client::FORMAT_XML: $request->setXmlBody($params); break; } } try { $response = $request->send(); Yii::info("API Request: {$method} {$action} | Params: " . json_encode($params) . " | Response: " . $response->getContent(), 'api'); if (!$response->isOk) { throw new \Exception("API Request Failed: {$response->statusCode} - {$response->getContent()}"); } return $response->data; } catch (\Exception $e) { Yii::error("API Error: {$e->getMessage()}", 'api'); throw $e; } } }
curl_setopt_array参数与Yii2 Request类的对应关系
Yii2的yii\httpclient\Request底层基于curl实现,常见参数对应关系如下:
| curl_setopt参数 | Yii2 Request对应方式 |
|---|---|
CURLOPT_URL | setUrl($url) 或Client的baseUrl配置 |
CURLOPT_HTTPHEADER | setHeaders($headers),传入键值对数组,如['Content-Type' => 'application/json'] |
CURLOPT_POST | setMethod('POST') |
CURLOPT_POSTFIELDS | setFormParams($params)(表单格式)或setJsonBody($params)(JSON格式)等 |
CURLOPT_TIMEOUT | Client配置中的timeout属性,如new Client(['timeout' => 10]) |
CURLOPT_SSL_VERIFYPEER | Client配置中的sslVerifyPeer属性,设为false关闭证书验证 |
CURLOPT_FOLLOWLOCATION | Client配置中的followLocation属性,设为true开启自动跳转 |
CURLOPT_RETURNTRANSFER | Yii2默认返回响应内容,通过$response->getContent()获取 |
如果需要设置更底层的curl参数,可通过Client的transportConfig直接传递:
$client = new Client([ 'transportConfig' => [ 'options' => [ CURLOPT_PROXY => 'http://proxy.example.com:8080', CURLOPT_PROXYUSERPWD => 'user:pass', ], ], ]);
内容的提问来源于stack exchange,提问作者rosecabbagedragon
相关产品推荐
相关产品推荐

