- v1.0.7(含)版本上兼容hyperf2和3版本。
- easywechat6用symfony/http-client相关组件,替换了之前4,5等版本的Guzzle请求组件,Symfony Http Client在常驻内存的服务中使用时,HttpClient会因为多个协程共用而报错。 pengxuxu/hyperf-easywechat6包使用hyperf的ClassMap替换了InteractWithHttpClient中的HttpClient对象实例,使得不同协程为不同的请求实例,同一协程上下文中获取到的为同一请求实例。
<?php
declare(strict_types=1);
namespace App\Controller;
use EasyWeChat\Kernel\HttpClient\RequestUtil;
use Symfony\Component\HttpClient\HttpClient as SymfonyClient;
class IndexController extends AbstractController
{
public function index()
{
$user = $this->request->input('user', 'Hyperf');
$method = $this->request->getMethod();
$client = SymfonyClient::create(RequestUtil::formatDefaultOptions([]));
go(function () use ($client) {
$client->request('GET', 'http://www.baidu.com/');
});
go(function () use ($client) {
$client->request('GET', 'http://www.baidu.com/');
});
return [
'method' => $method,
'message' => "Hello {$user}.",
];
}
}
在swoole>=4.7.0且开启native curl修改常量SWOOLE_HOOK_ALL,共用一个HttpClient情况下,报错信息:
PHP Fatal error: Uncaught Swoole\Error: cURL is executing, cannot be operated in /data/project/hyperf-skeleton/vendor/symfony/http-client/Response/CurlResponse.php:366
-
pengxuxu/hyperf-easywechat6包用hyperf的容器获得Hyperf\HttpServer\Contract\RequestInterface对应的Hyperf\HttpServer\Request,替换了easywechat6中的同样基于PSR-7规范request;获得Psr\SimpleCache\CacheInterface对应的缓存类,替换easywechat6中同样基于PSR-16规范的cache。
-
在替换request前,判断当前协程是否存在服务端请求,避免了在hyperf的定时任务、命令行等,使用外观获取对应Application时出现的错误,比如在定时任务中只需要获取请求getClient()发送模板消息请求等场景。
$app = new Application($config); if (\Hyperf\Context\Context::get(ServerRequestInterface::class) && method_exists($app, 'setRequest')) { $app->setRequest(ApplicationContext::getContainer()->get(\Hyperf\HttpServer\Contract\RequestInterface)); } if (method_exists($app, 'setCache')) { $app->setCache(ApplicationContext::getContainer()->get(\Psr\SimpleCache\CacheInterface::class) }
-
建议使用Swoole 4.7.0 及以上版本,并且开启 native curl 选项。easywechat4,5版本使用的是Guzzle,该组件默认使用Curl,如果开启navie curl,并修改常量 define('SWOOLE_HOOK_FLAGS', SWOOLE_HOOK_ALL | SWOOLE_HOOK_CURL),就不用替换Guzzle中的handler。easywechat6则使用symfony/http-client包,它会根据当前环境,按CurlHttpClient(Curl,如果安装了curl扩展),AmpHttpClient(Amp HTTP/2 Support)和NativeHttpClient(Stream)的顺序返回http客户端。 拿hyperf官方 Hyperf\Guzzle\CoroutineHandler handler举例来说,这个handler里会new一个继承自Swoole\Coroutine\Http\Client 的协程客户端HttpClient,这个就解释了上面提到的HttpClient会因为多个协程共用而报错和easywechat4,5版本如果换guzzle handler后无需再classmap替换。
-
建议安装easywechat6.11.1(>=)以上版本,从该版本开始加入了主动请求和异步通知的验签。
微信 SDK for Hyperf, 基于 w7corp/easywechat
composer require pengxuxu/hyperf-easywechat6
- 发布配置文件
php ./bin/hyperf.php vendor:publish pengxuxu/hyperf-easywechat6
- 修改应用根目录下的
config/autoload/wechat.php
中对应的参数即可。 - 每个模块基本都支持多账号,默认为
default
。
接收普通消息例子:
Router::addRoute(['GET', 'POST', 'HEAD'], '/wechat', 'App\Controller\WeChatController@serve');
注意:一定是
Router::addRoute
, 因为微信服务端认证的时候是GET
, 接收用户消息时是POST
! 然后创建控制器WeChatController
:
<?php
declare(strict_types=1);
namespace App\Controller;
use EasyWeChat\Kernel\Exceptions\BadRequestException;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\Kernel\Exceptions\RuntimeException;
use Pengxuxu\HyperfWechat\EasyWechat;
use Pengxuxu\HyperfWechat\Helper;
use Hyperf\HttpServer\Contract\ResponseInterface;
class WeChatController
{
/**
* 处理微信的请求消息
*
* @return ResponseInterface
* @throws BadRequestException
* @throws InvalidArgumentException
* @throws RuntimeException;
*/
public function serve()
{
$app = EasyWechat::officialAccount();
$server = $app->getServer();
$server->with(function ($message, \Closure $next) {
return '谢谢关注!';
// 你的自定义逻辑
// return $next($message);
});
// 一定要用Helper::Response去转换
return Helper::Response($server->serve());
}
}
use Pengxuxu\HyperfWechat\EasyWechat;
$officialAccount = EasyWechat::officialAccount(); // 公众号
$pay = EasyWechat::pay(); // 微信支付
$miniApp = EasyWechat::miniApp(); // 小程序
$openPlatform = EasyWechat::openPlatform(); // 开放平台
$work = EasyWechat::work(); // 企业微信
$openWork = EasyWechat::openWork(); // 企业微信开放平台
// 均支持传入配置账号名称以及配置
EasyWeChat::officialAccount('foo',[]); // `foo` 为配置文件中的名称,默认为 `default`。`[]` 可覆盖账号配置
//...
更多 SDK 的具体使用请参考:https://easywechat.com
MIT