Code Monkey home page Code Monkey logo

hyperf-easywechat6's Introduction

Notice

  • 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(>=)以上版本,从该版本开始加入了主动请求和异步通知的验签

hyperf-easywechat6

微信 SDK for Hyperf, 基于 w7corp/easywechat

安装

composer require pengxuxu/hyperf-easywechat6 

配置

  1. 发布配置文件
php ./bin/hyperf.php vendor:publish pengxuxu/hyperf-easywechat6
  1. 修改应用根目录下的 config/autoload/wechat.php 中对应的参数即可。
  2. 每个模块基本都支持多账号,默认为 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

License

MIT

hyperf-easywechat6's People

Contributors

pengxuxu avatar

Stargazers

avrilko avatar  avatar 李云龙 avatar  avatar 简 avatar  avatar  avatar  avatar ALan Leung avatar cocoliu avatar Terran avatar jiangslee avatar  avatar

Watchers

 avatar

Forkers

chahualao

hyperf-easywechat6's Issues

调用接口报错

$api = $app->getClient();
        $response = $api->postJson('/cgi-bin/menu/create', [
            [
                "type"=> "view",
                "name"=> "xxx",
                "key"=> "https://xxx.com"
            ]
        ]);

会出现下面这个错误
Fatal error: Allowed memory size of 1073741824 bytes exhausted (tried to allocate 803213312 bytes) in /home/www/xxx/runtime/container/proxy/App_Controller_WechatController.proxy.php on line 41
[2023-05-22 23:39:03 *360474.3] ERROR php_swoole_server_rshutdown() (ERRNO 503): Fatal error: Allowed memory size of 1073741824 bytes exhausted (tried to allocate 803213312 bytes) in /home/www/xxx/runtime/container/proxy/App_Controller_WechatController.proxy.php on line 41
[2023-05-22 23:39:03 $360466.0] WARNING Server::check_worker_exit_status(): worker(pid=360474, id=3) abnormal exit, status=255, signal=0

请教一下 公众号模板消息发送

$app = EasyWechat::officialAccount();
$result = $app->template_message->send([
'touser' => 'xxx2Yc-nvKbQTvZrc',
'template_id' => 'xxxxAHtUg2mAn7_RfYZJRSiX3-pTM',
'url' => 'http://xxx.com/',
'data' => [
'first' => array('value' => '尊敬的XXX,您好!', 'color' => "#FF0000"),
'keyword1' => array('value' => '公司', 'color' => '#FF0000'),
'keyword2' => array('value' => '12345', 'color' => '#FF0000'),
'keyword3' => array('value' => '100元', 'color' => '#FF0000'),
'keyword4' => array('value' => '2023年2月5日 18:36', 'color' => '#FF0000'),
'remark' => array('value' => '感谢您对持!', 'color' => '#FF0000')
]
]);

提示 template_message 没有这个方法

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.