You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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_URLsetUrl($url) 或Client的baseUrl配置
CURLOPT_HTTPHEADERsetHeaders($headers),传入键值对数组,如['Content-Type' => 'application/json']
CURLOPT_POSTsetMethod('POST')
CURLOPT_POSTFIELDSsetFormParams($params)(表单格式)或setJsonBody($params)(JSON格式)等
CURLOPT_TIMEOUTClient配置中的timeout属性,如new Client(['timeout' => 10])
CURLOPT_SSL_VERIFYPEERClient配置中的sslVerifyPeer属性,设为false关闭证书验证
CURLOPT_FOLLOWLOCATIONClient配置中的followLocation属性,设为true开启自动跳转
CURLOPT_RETURNTRANSFERYii2默认返回响应内容,通过$response->getContent()获取

如果需要设置更底层的curl参数,可通过Client的transportConfig直接传递:

$client = new Client([
    'transportConfig' => [
        'options' => [
            CURLOPT_PROXY => 'http://proxy.example.com:8080',
            CURLOPT_PROXYUSERPWD => 'user:pass',
        ],
    ],
]);

内容的提问来源于stack exchange,提问作者rosecabbagedragon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 11:17:19