快速開始
在我們已經成功安裝完成 EasySwoole WeChat SDK
組件后,就可以很快地開始使用它了,當然你還是有必要明白 PHP
的基本知識,如命名空間等,我這里就不贅述了。
接下來我們以完成 服務器端驗證
與 接收響應用戶發送的消息
為例來演示,首先我們有必要先了解一下微信交互的運行流程:
具體交互流程如下:
+-----------------+ +---------------+
+----------+ | | POST/GET/PUT | |
| | ------------------> | | -------------------> | |
| user | | wechat server | | your server |
| | < - - - - - - - - - | | | |
+----------+ | | <- - - - - - - - - - | |
+-----------------+ +---------------+
其實我們要做的就是圖中 微信服務器把用戶消息轉到我們的自有服務器(虛線返回部分) 后的處理過程。
服務端驗證
在微信接入開始有一個 "服務器驗證" 的過程,這一步其實就是 微信服務器 向 我們服務器 發起一個請求(上圖實線部分),傳了一個名稱為 echostr
的字符串過來,我們只需要原樣返回就好了。
作為開發者,你應該知道,微信后臺只能填寫一個服務器地址,所以 服務器驗證 與 消息的接收與回復,都在這一個鏈接內完成交互。
考慮到這些,我們已經把驗證這一步給封裝到 SDK
里了,你可以完全忽略這一步。
下面我們來配置一個基本的服務端,這里假設我們自己的服務器域名叫 easyswoolewechat.com
,并且我們在服務端已經安裝好了一個 EasySwoole
框架,或者我們在服務器上準備一個文件 server.php
(使用原生 Swoole
實現,下文只提供偽代碼)。
使用 EasySwoole
框架配置服務端驗證
以下為了演示,我們只在 App\HttpController\Index
控制器類下進行編碼實現配置服務端驗證,用戶可自行選擇其他控制器類進行編碼實現。
在服務器的 EasySwoole
框架的 HTTP
服務的 控制器
中來配置一個基本的服務端:
配置主服務為 HTTP
服務,然后我們可以在 App\HttpController\Index
控制器類下編寫 server
方法,編寫如下代碼實現服務端驗證:
<?php
namespace App\HttpController;
use EasySwoole\Http\AbstractInterface\Controller;
use EasySwoole\WeChat\Factory;
class Index extends Controller
{
public function server()
{
$config = [
// 微信公眾平臺后臺的 appid
'appId' => 'wxefe41fdeexxxxxx',
// 微信公眾平臺后臺配置的 Token
'token' => 'dczmnau31ea9nzcnxxxxxxxxx',
// 微信公眾平臺后臺配置的 EncodingAESKey
'aesKey' => 'easyswoole'
];
$officialAccount = Factory::officialAccount($config);
$server = $officialAccount->server;
/** @var \Psr\Http\Message\ServerRequestInterface $psr7Request */
$psr7Request = $this->request();
/**
* @var \Psr\Http\Message\ResponseInterface $replyResponse
* forceValidate() 表示啟用請求驗證,以確保請求來自微信發送。默認不啟用驗證
* serve() 會解析本次請求后回調之前注冊的事件(包括 AES 解密和解析 XML)
* serve() 接受一個顯式實現了 \Psr\Http\Message\ServerRequestInterface 的 request 對象
*/
$replyResponse = $server->forceValidate()->serve($psr7Request);
/**
* $replyResponse 是一個顯式實現了 PSR-7 的對象,用戶只需要處理該對象即可正確響應給微信
* 下面是一個使用 EasySwoole 的響應方法
*/
$this->response()->withStatus($replyResponse->getStatusCode());
/**
* PSR-7 的 Header 并不是單純的 k => v 結構
*/
foreach ($replyResponse->getHeaders() as $name => $values) {
$this->response()->withHeader($name, implode(", ", $values));
}
$this->response()->write($replyResponse->getBody()->__toString());
}
}
使用原生 Swoole
配置服務端驗證
server.php
的實現形式我就以原生 Swoole
的 http_server
來啟動一個服務,偽代碼內容如下:
<?php
use EasySwoole\WeChat\Factory;
require_once __DIR__ . '/vendor/autoload.php';
$http = new Swoole\Http\Server('0.0.0.0', 9501);
$http->on('request', function (\Swoole\Http\Request $request, \Swoole\Http\Response $response) {
$config = [
// 微信公眾平臺后臺的 appid
'appId' => 'wxefe41fdeexxxxxx',
// 微信公眾平臺后臺配置的 Token
'token' => 'dczmnau31ea9nzcnxxxxxxxxx',
// 微信公眾平臺后臺配置的 EncodingAESKey
'aesKey' => 'easyswoole'
];
$officialAccount = Factory::officialAccount($config);
$server = $officialAccount->server;
// 此處為實現了 \Psr\Http\Message\ServerRequestInterface 的 request 對象
/** @var \Psr\Http\Message\ServerRequestInterface $psr7Request */
$psr7Request = new XxxReuest($request); // 偽代碼
/**
* @var \Psr\Http\Message\ResponseInterface $replyResponse
* forceValidate() 表示啟用請求驗證,以確保請求來自微信發送。默認不啟用驗證
* serve() 會解析本次請求后回調之前注冊的事件(包括 AES 解密和解析 XML)
* serve() 接受一個顯式實現了 \Psr\Http\Message\ServerRequestInterface 的 request 對象
*/
$replyResponse = $server->forceValidate()->serve($psr7Request);
/**
* $replyResponse 是一個顯式實現了 PSR-7 的對象,用戶只需要處理該對象即可正確響應給微信
* 下面是一個原生 swoole 的響應方法
*/
$response->status($replyResponse->getStatusCode());
/**
* PSR-7 的 Header 并不是單純的 k => v 結構
*/
foreach ($replyResponse->getHeaders() as $name => $values) {
$response->header($name, implode(", ", $values));
}
// 將響應輸出到客戶端
$response->write($replyResponse->getBody()->__toString());
});
$http->start();
上述
$psr7Request
請用戶參考 PSR-7 標準自行實現Psr\Http\Message\ServerRequestInterface
接口。
注意:安全模式下請一定要配置 aesKey
。
很簡單,一個服務端帶驗證功能的代碼已經完成,當然我們沒有對消息做處理,別著急,后面我們再講。
我們先來分析上面的代碼:
<?php
// 引入我們的主項目工廠類
use EasySwoole\WeChat\Factory;
// 一些配置
$config = [...];
// 使用配置來初始化一個公眾號應用實例
$officialAccount = Factory::officialAccount($config);
// 得到一個 Server\Guard $server 實例
$server = $officialAccount->server;
// 構造 實現了 \Psr\Http\Message\ServerRequestInterface 的 request 對象
// 此處為實現了 \Psr\Http\Message\ServerRequestInterface 的 request 對象
/** @var \Psr\Http\Message\ServerRequestInterface $psr7Request */
$psr7Request = new XxxReuest($request); // 偽代碼
// 得到一個實現了 `Psr\Http\Message\ResponseInterface` 接口的 response 響應實例對象
$replyReponse = $server->forceValidate()->serve($psr7Request);
### 構建 Swoole 響應給到客戶端
// 設置響應 HTTP 狀態碼
$response->status($replyResponse->getStatusCode());
// 設置響應頭 Header
foreach ($replyResponse->getHeaders() as $name => $values) {
$response->header($name, implode(", ", $values));
}
// 將響應輸出到客戶端
$response->write($replyResponse->getBody()->__toString());
最后這一行我有必要詳細講一下:
- 我們的
$server->forceValidate()->serve($psr7Request);
就是執行服務端業務了,那么它的返回值是一個實現了Psr\Http\Message\ResponseInterface
接口的實例對象。 - 我這里是直接調用了
Swoole
原生的響應方法write()
。在一些的Swoole
相關的框架中,你可以直接拿到$replyResponse
實例對象進行相關的操作,然后輸出到客戶端即可。在EasySwoole
中,可以直接使用上文示例的方法操作即可輸出到客戶端。
OK,有了上面的代碼,那么請你按 微信官方的接入指引 在公眾號后臺完成配置并啟用,并相應修改上面的 $config
的相關配置。
URL
就是我們的 http://easyswoolewechat.com/server
,這里我是舉例哦,你可不要填寫我的域名。由于我使用的是 Swoole
的 9501
端口提供服務,請用戶自行進行反向代理配置,具體如何配置反向代理請看 EasySwoole 反向代理。
請一定要將微信后臺的開發者模式 ”啟用” !!!!!!看到紅色 “停用” 才真正的是啟用了。最后,請不要用瀏覽器訪問這個地址,它是給微信服務器訪問的,不是給人訪問的。
接收 & 回復用戶消息
上述完成服務端驗證通過后,接下來我們就來試一下接收消息吧。
在剛剛上文代碼最后一行使用 $this->response()->write($replyResponse->getBody()->__toString());
(在 EasySwoole
框架中響應) 或 使用 $response->write($replyResponse->getBody()->__toString());
(原生 Swoole
響應); 在前面,現在我們調用 $officialAccount->server
的 push()
方法來注冊一個消息處理器,這里用到了 PHP 閉包
的知識,如果你不熟悉趕緊補課去。
EasySwoole
中App\HttpController\Index.php
實現:
<?php
namespace App\HttpController;
use EasySwoole\Http\AbstractInterface\Controller;
use EasySwoole\WeChat\Factory;
class Index extends Controller
{
public function server()
{
// 這里省略
$server = $officialAccount->server;
/** 注冊消息事件回調 */
$server->push(function (\EasySwoole\WeChat\Kernel\Contracts\MessageInterface $message) {
return new \EasySwoole\WeChat\Kernel\Messages\Text("您好!歡迎使用 EasySwoole WeChat!");
});
$psr7Request = $this->request();
/** @var \Psr\Http\Message\ResponseInterface $replyResponse */
$replyResponse = $server->forceValidate()->serve($psr7Request);
$this->response()->withStatus($replyResponse->getStatusCode());
foreach ($replyResponse->getHeaders() as $name => $values) {
$this->response()->withHeader($name, implode(", ", $values));
}
// 將響應輸出到客戶端
$this->response()->write($replyResponse->getBody()->__toString());
}
}
原生
Swoole
中單獨實現server.php
:
<?php
use EasySwoole\WeChat\Factory;
require_once __DIR__ . '/vendor/autoload.php';
// 這里省略
$http->on('request', function (\Swoole\Http\Request $request, \Swoole\Http\Response $response) {
// 這里省略
$server = $officialAccount->server;
/** 注冊消息事件回調 */
$server->push(function (\EasySwoole\WeChat\Kernel\Contracts\MessageInterface $message) {
return new \EasySwoole\WeChat\Kernel\Messages\Text("您好!歡迎使用 EasySwoole WeChat!");
});
/** @var \Psr\Http\Message\ServerRequestInterface $psr7Request */
$psr7Request = new XxxReuest($request); // 偽代碼
$replyResponse = $server->forceValidate()->serve($psr7Request);
$response->status($replyResponse->getStatusCode());
foreach ($replyResponse->getHeaders() as $name => $values) {
$response->header($name, implode(", ", $values));
}
// 將響應輸出
$response->write($replyResponse->getBody()->__toString());
});
// 這里省略
OK,打開你的微信客戶端,向你的公眾號發送任意一條消息,你應該會收到回復:您好!歡迎使用 EasySwoole WeChat!
。
如果您沒有收到回復,但是看到了 “你的公眾號暫時無法提供服務”,好,那檢查一下你的日志吧,日志在哪兒?我們的配置里寫了日志路徑了(sys_get_temp_dir() . '/wechat.log'
)。沒有這個文件?看看權限。
一個基本的服務端驗證就完成了。
總結
所有的應用服務都通過主入口 EasySwoole\WeChat\Factory
類來創建:
<?php
use EasySwoole\WeChat\Factory;
// 公眾號
$officialAccount = Factory::officialAccount($config);
// 小程序
$miniProgram = Factory::miniProgram($config);
// 開放平臺
$openPlatform = Factory::openPlatform($config);
// 企業微信
$work = Factory::work($config);
最后
希望您在使用本 SDK
的時候如果您發現 SDK
的不足,歡迎提交 PR
或者給我們 提建議 & 報告問題。