使用yii2-httpclient做公众号接口时候的一个坑
本帖发布于 1个月前

简单点说是yii2的Json::encode的问题。

大家知道我有一个yii2的微信sdk开源扩展正在开发中,使用了yii2官方的http客户端库yii2-httpclient,一直都不错,今天在开发设置用户备注名时发现了一个问题,接口可以提交但是就是出现乱码。

alt

找原因的过程就不说了,最后定位到yii2-httpclient的 vendor/yiisoft/yii2-httpclient/JsonFormatter.php 文件上,它负责把我们传递的参数数组转化为json格式。

问题出在如下代码

// JsonFormatter.php
public $encodeOptions = 0;

public function format(Request $request)
{
    $request->getHeaders()->set('Content-Type', 'application/json; charset=UTF-8');
    if (($data = $request->getData()) !== null) {
        $request->setContent(Json::encode($request->getData(), $this->encodeOptions));
    }
    return $request;
}

代码中使用 Json::encode($request->getData(), $this->encodeOptions) 将参数格式化为json,但是它传入了第二个参数 $this->encodeOptions,在JsonFormatter类中$encodeOptions为0,因此对于参数数组中的中文会被编码。

而微信的设置用户备注名接口需要传递不被编码的json串,那怎么办那???

我们只需要自己定义一个JsonFormatter类就好了

在这里我们一起熟悉如何为yii2-httpclient自定义一个formatter。

我也给它起名叫JsonFormatter

// yii2-wx/src/helpers/JsonFormatter.php
<?php

namespace abei2017\wx\helpers;

class JsonFormatter extends \yii\httpclient\JsonFormatter {

    public $encodeOptions = 256;
}

我让它继承于yii2-httpclient的JsonFormatter类了,然后自己指定一个$encodeOptions值,这样调用我自己定义的JsonFormatter::format方法的时候自然$encodeOptions就是256了。

接下来就开始使用

//  首先添加这个formatter类并且起一个名字
$this->httpClient->formatters = ['uncodeJson'=>'abei2017\wx\helpers\JsonFormatter'];

//  在使用yii2-httpclient生成请求的时候,人为设置format为uncodeJson
$response = $this->httpClient->createRequest()
    ->setUrl(self::API_UPDATE_REMARK_URL."?access_token={$this->accessToken}")
    ->setMethod('post')
    ->setData(['openid'=>$openId,'remark'=>$remark])
    ->setFormat('uncodeJson')->send();

是不是很简单,当然如果你定义的formatter和yii2-httpclient已经存在的没有任何关系,应该至少现实其FormatterInterface接口。

填坑完毕。

参考文献

让Json更懂中文(JSON_UNESCAPED_UNICODE)

微信扫码访问小程序版
本作品采用署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可 。
北哥小报

扫码关注我的订阅号,不定时推送除了代码外的事情,比如时间管理、书单等。

yii2
7 篇帖子