乐趣区

关于thinkphp6:ThinkPHP6swooleeasywechat使用教程

前言
在联合 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 类外面事件类型

<?php

namespace 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

退出移动版