前言
在联合think-swoole+easywechat扩大应用的时候,须要思考curl兼容swoole携程问题,request兼容swoole框架,因为easywechat底层还是通过$_POST或者其余来获取申请参数。
还有就是好多的接口根本没有。须要本人写,因为这里装置的是5.0的版本。在6.0版本后easywecaht不在写操作接口的相干逻辑只提供了一些受权后的接口封装、申请封装、日志封装等等。集体还是感觉5.0版本够用了。而后就抉择了5.0的版本来开发。5.0版本中例如,直播这块的接口逻辑须要本人写点、企业微信进群配置这些等等。上面咱们就看具体的实例教程:

装置
装置think-swoole

composer require topthink/think-swoole

装置easywechat

composer require overtrue/wechat:~5.0 -vvv

应用前配置

请在app/AppService.php的boot办法内减少配置默认申请类

use Yurun\Util\Swoole\Guzzle\SwooleHandler; DefaultHandler::setDefaultHandler(SwooleHandler::class);

例如这里实例化一个企业微信相干的

use EasyWeChat\Work\Application;use Yurun\Util\Swoole\Guzzle\SwooleHandler;$type = 'user';$config=[    'corp_id'=>'',    'token'=>'',];//实例化企业微信$application[$type] = Factory::work($config);//这里是为了兼容swoole的curl携程$application[$type]['guzzle_handler'] = SwooleHandler::class;$request = request();//在swoole模式运行下,须要从think\request下获取申请信息,这一步非常重要$application[$type]->rebind('request', new Request($request->get(), $request->post(), [], [], [], $request->server(), $request->getContent()));$this->application[$type]->register(new ServiceProvider());

应用前这些配置都须要减少的。这里也能够封装成类来进行调用
为什么要用type来辨别实例化类型:
因为在企业微信下会有多种服务实例化对象,例如客户、自建利用、通讯录都会产生不同的实例化对象

构建企业微信服务首先革新下方才实例化的形式:

use crmeb\services\wechat\groupChat\ServiceProvider;use Yurun\Util\Swoole\Guzzle\SwooleHandler;use EasyWeChat\Work\Application;use Symfony\Component\HttpFoundation\Request;class Work extends BaseApplication{       /**     * @var WorkConfig     */    protected $config;    /**     * @var Application[]     */    protected $application = [];    /**     * @var string */    protected $configHandler;    /**     * @var string[]     */    protected static $property = [        'groupChat' => 'external_contact',          'groupChatWelcome' => 'external_contact_message_template'    ];    /**     * Work constructor.     */    public function __construct()    {            /** @var WorkConfig config */            $this->config = app()->make(WorkConfig::class);            $this->debug = DefaultConfig::value('logger');    }    /**     * 设置获取配置     * @param string $handler     * @return $this     */    public function setConfigHandler(string $handler)    {            $this->configHandler = $handler;            return $this;    }    /**     * @return Work     */    public static function instance()    {            return app()->make(static::class);    }    /**     * 获取实例化句柄     * @param string $type     * @return Application     */    public function application(string $type = WorkConfig::TYPE_USER){           $config = $this->config->all();            $config = array_merge($config, $this->config->setHandler($this->configHandler)->getAppConfig($type));            if (!isset($this->application[$type])) {                    $this->application[$type] = Factory::work($config);                    $this->application[$type]['guzzle_handler'] = SwooleHandler::class;                    $request = request();                    $this->application[$type]->rebind('request', new Request($request->get(), $request->post(), [], [], [], $request->server(), $request->getContent()));                    $this->application[$type]->register(new ServiceProvider());            }           return $this->application[$type];    }}

企业微信服务
这里阐明下,swoole外面尽量少用静态方法,而这里应用了的起因是,应用了app->make()实例化了以后类。

use think\Response;/** * 服务端 * @return Response * @throws BadRequestException * @throws InvalidArgumentException * @throws InvalidConfigException * @throws \ReflectionException */public static function serve(): Response{        $make = self::instance();        $make->application()->server->push($make->pushMessageHandler);       $response = $make->application()->server->serve();        return response($response->getContent());}首先设置pushMessageHandler类,关上app/AppService.php。在register办法中注册服务器相应事件类 ,例如app\listener\wechat\WorkListener 类引入use crmeb\services\wechat\config\HttpCommonConfig;use crmeb\services\wechat\config\LogCommonConfig;use crmeb\services\wechat\config\WorkConfig;use app\services\work\WorkConfigServices;public function register(){    //实例化企业微信配置    $this->app->bind(WorkConfig::class, function () {            return (new WorkConfig(new LogCommonConfig(), $this->app->make(HttpCommonConfig::class)))        ->setHandler(WorkConfigServices::class);    });    //企业微信    $this->app->bind(Work::class, function () {            return (new Work)->setPushMessageHandler(WorkListener::class)        ->setConfigHandler(WorkConfigServices::class);    });}

肯定要配置企业微信服务器相应的事件类WorkListener这里列举出WorkListener类外面事件类型

<?phpnamespace app\listener\wechat;use app\services\user\label\UserLabelServices;use app\services\work\WorkClientServices;use app\services\work\WorkDepartmentServices;use app\services\work\WorkGroupChatServices;use app\services\work\WorkMemberServices;use EasyWeChat\Kernel\Contracts\EventHandlerInterface;/** * 企业微信服务音讯解决 * Class WorkListener * @package app\listener\wechat */class WorkListener implements EventHandlerInterface{        public function handle($payload = null)        {                $response = null;                switch ($payload['MsgType']) {                        case 'event':                            switch ($payload['Event']) {                                    case 'change_contact'://通讯录事件                                            $this->changeContactEvent($payload);                                            break;                                    case 'change_external_chat'://客户群事件                                        $this->changeExternalChatEvent($payload);                                            break;                                    case 'change_external_contact'://客户事件                                            $this->externalContactEvent($payload);                                            break;                                    case 'change_external_tag'://客户标签事件                                            $this->changeExternalTagEvent($payload);                                            break;                                    case 'batch_job_result'://异步工作实现告诉                                            $this->batchJobResultEvent($payload);                                    break;                            }                            break;                    case 'text'://文本音讯                            break;                    case 'image'://图片音讯                            break;                    case 'voice'://语音音讯                            break;                    case 'video'://视频音讯                            break;                    case 'news'://图文音讯                            break;                case 'update_button'://模板卡片更新音讯                    break;                case 'update_template_card'://更新点击用户的整张卡片                    break;            }            return $response;        }        public function batchJobResultEvent(array $payload)        {                switch ($payload['JobType']) {                        case 'sync_user'://增量更新成员                                break;                        case 'replace_user'://全量笼罩成员                                break;                        case 'invite_user'://邀请成员关注                                break;                        case 'replace_party'://全量笼罩部门                                break;                }        }        /**         * 企业微信通讯录事件         * @param array $payload         * @return null         */        public function changeContactEvent(array $payload)       {                $response = null;                try {                        switch ($payload['ChangeType']) {                                case 'create_user'://新增成员事件                                                        break;                                case 'update_user'://更新成员事件                    break;                case 'delete_user'://删除成员事件                                                          break;                                case 'create_party'://新增部门事件                                                         break;                case 'update_party'://更新部门事件                                        break;                                case 'delete_party'://删除部门事件                                                          break;                                case 'update_tag'://标签成员变更事件                                        break;                        }            } catch (\Throwable $e) {                    \think\facade\Log::error([                                'message' => '企业微信通讯录事件产生谬误:' . $e->getMessage(),                                'payload' => $payload,                               'file' => $e->getFile(),                               'line' => $e->getLine()                        ]);                }                return $response;        }    /**     * 客户事件     * @param array $payload     * @return |null     */    public function externalContactEvent(array $payload)    {        $response = null;        try {            switch ($payload['ChangeType']) {                case 'add_external_contact'://增加企业客户事件                    /** @var WorkClientServices $make */                    $make = app()->make(WorkClientServices::class);                    $make->createClient($payload);                    break;                case 'edit_external_contact'://编辑企业客户事件                    /** @var WorkClientServices $make */                    $make = app()->make(WorkClientServices::class);                    $make->updateClient($payload);                    break;                case 'del_external_contact':                    /** @var WorkClientServices $make */                    $make = app()->make(WorkClientServices::class);                    $make->deleteClient($payload);                    break;                case 'add_half_external_contact'://内部联系人免验证增加成员事件                    break;                case 'del_follow_user'://删除跟进成员事件                    /** @var WorkClientServices $make */                    $make = app()->make(WorkClientServices::class);                    $make->deleteFollowClient($payload);                    break;                case 'transfer_fail'://客户接替失败事件                    break;            }        } catch (\Throwable $e) {            \think\facade\Log::error([                'message' => '客户事件产生谬误:' . $e->getMessage(),                'payload' => $payload,                'file' => $e->getFile(),                'line' => $e->getLine()            ]);        }        return $response;    }    /**     * 客户群事件     * @param array $payload     */    public function changeExternalChatEvent(array $payload)    {        try {            switch ($payload['ChangeType']) {                case 'create'://客户群创立事件                                       break;                case 'update'://客户群变更事件                                      break;                case 'dismiss'://客户群遣散事件                                      break;            }        } catch (\Throwable $e) {            \think\facade\Log::error([                'message' => $e->getMessage(),                'payload' => $payload,                'file' => $e->getFile(),                'line' => $e->getLine()            ]);        }    }    /**     * 客户标签事件     * @param array $payload     */    public function changeExternalTagEvent(array $payload)    {        switch ($payload['ChangeType']) {            case 'create'://企业客户标签创立事件                              break;            case 'update'://企业客户标签变更事件                              break;            case 'delete'://企业客户标签删除事件                              break;            case 'shuffle'://企业客户标签重排事件                break;        }    }}

上面提供了残缺的类
BaseApplication类

use crmeb\services\wechat\contract\BaseApplicationInterface;/** * Class BaseApplication * @package crmeb\services\wechat */abstract class BaseApplication implements BaseApplicationInterface{        //app端        const APP = 'app';        //h5端、公众端        const WEB = 'web';        //小程序端        const MINI = 'mini';        //开发平台        const OPEN = 'open';        //pc端        const PC = 'pc';    /**         * 拜访端         * @var string         */        protected $accessEnd;        /**         * @var array         */        protected static $property = [];        /**         * @var string         */        protected $pushMessageHandler;        /**         * Debug         * @var bool         */        protected $debug = true;        /**         * 设置音讯解决类         * @param string $handler         * @return $this         */        public function setPushMessageHandler(string $handler)        {                $this->pushMessageHandler = $handler;                return $this;        }        /**         * 设置拜访端         * @param string $accessEnd         * @return $this         */        public function setAccessEnd(string $accessEnd)    {        if (in_array($accessEnd, [self::APP, self::WEB, self::MINI])) {            $this->accessEnd = $accessEnd;                }                return $this;        }    /**         * 主动获取拜访端         * @param \think\Request $request         * @return string         */        public function getAuthAccessEnd(\think\Request $request)       {        if (!$this->accessEnd) {                        try {                                if ($request->isApp()) {                                        $this->accessEnd = self::APP;                                } else if ($request->isPc()) {                                        $this->accessEnd = self::PC;                                } else if ($request->isWechat() || $request->isH5()) {                                        $this->accessEnd = self::WEB;                                } else if ($request->isRoutine()) {                                        $this->accessEnd = self::MINI;                                } else {                                    $this->accessEnd = self::WEB;                            }                        } catch (\Throwable $e) {                                $this->accessEnd = self::WEB;                        }                }                return $this->accessEnd;        }        /**         * 记录谬误日志         * @param \Throwable $e         */        protected static function error(\Throwable $e)        {                static::instance()->debug && \think\facade\Log::error([                        'error' => $e->getMessage(),                        'line' => $e->getLine(),                    '    file' => $e->getFile()                ]);        }        /**         * 申请日志         * @param string $message         * @param $request         * @param $response         */        protected static function logger(string $message, $request, $response)        {                $debug = static::instance()->debug;                if ($debug)         {                            \think\facade\Log::info([                                    'message' => $message,                                    'request' => json_encode($request),                                    'response' => json_encode($response)                            ]);                }        }        /**         * @param $name         * @param $arguments         * @return mixed         */        public static function __callStatic($name, $arguments)        {                if (in_array($name, array_keys(static::$property))) {                        $name = static::$property[$name];                        return static::instance()->application()->{$name};                }                throw new WechatException('办法不存在');       }}BaseApplicationInterface接口类namespace crmeb\services\wechat\contract;/** * Interface BaseApplicationInterface * @package crmeb\services\wechat\contract */interface BaseApplicationInterface{        /**         * @return mixed         */        public static function instance();        /**         * @return mixed         */        public function application();}

最初
如果你感觉这篇文章对你有点用的话,麻烦请给咱们的开源我的项目点点star:http://github.crmeb.net/u/defu不胜感激 !

收费获取源码地址:http://www.crmeb.com

PHP学习手册:https://doc.crmeb.com

技术交换论坛:https://q.crmeb.com