首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 微信公眾平台開發 SDK 核心類:Wechat 完整實現

     編輯:PHP 綜合知識

類職責

  • 驗證服務器簽名(Token 驗證)
  • 接收並解析微信推送 XML 消息
  • 提供統一回復接口(文本/圖片/語音/視頻/音樂/圖文)
  • XML 安全構建(CDATA 區塊防注入)

完整類代碼

<?php
class Wechat {
    private $data = [];

    public function __construct($token) {
        if (!$this->auth($token)) exit;
        if (!empty($_GET['echostr'])) exit($_GET['echostr']); // 首次驗證

        try {
            $xml = file_get_contents("php://input");
            $xml = new SimpleXMLElement($xml);
            foreach ($xml as $key => $value) {
                $this->data[$key] = strval($value);
            }
        } catch (Exception $e) {
            // 非 XML 或解析失敗,靜默忽略
        }
    }

    public function request() {
        return $this->data;
    }

    public function response($content, $type = 'text', $flag = 0) {
        // 基礎字段
        $this->data = [
            'ToUserName'   => $this->data['FromUserName'],
            'FromUserName' => $this->data['ToUserName'],
            'CreateTime'   => time(),
            'MsgType'      => $type,
        ];

        // 類型特定字段
        $this->$type($content);

        $this->data['FuncFlag'] = $flag;

        // 輸出 XML
        $xml = new SimpleXMLElement('');
        $this->data2xml($xml, $this->data);
        exit($xml->asXML());
    }

    private function text($content) {
        $this->data['Content'] = $content;
    }

    private function music($music) {
        list($this->data['Music']['Title'],
             $this->data['Music']['Description'],
             $this->data['Music']['MusicUrl'],
             $this->data['Music']['HQMusicUrl']) = $music;
    }

    private function news($news) {
        $articles = [];
        foreach ($news as $key => $value) {
            list($articles[$key]['Title'],
                 $articles[$key]['Description'],
                 $articles[$key]['PicUrl'],
                 $articles[$key]['Url']) = $value;
            if ($key >= 9) break; // 最多 10 條
        }
        $this->data['ArticleCount'] = count($articles);
        $this->data['Articles'] = $articles;
    }

    private function data2xml($xml, $data, $item = 'item') {
        foreach ($data as $key => $value) {
            is_numeric($key) && $key = $item;
            if (is_array($value) || is_object($value)) {
                $child = $xml->addChild($key);
                $this->data2xml($child, $value, $item);
            } else {
                if (is_numeric($value)) {
                    $xml->addChild($key, $value);
                } else {
                    $child = $xml->addChild($key);
                    $node = dom_import_simplexml($child);
                    $node->appendChild($node->ownerDocument->createCDATASection($value));
                }
            }
        }
    }

    private function auth($token) {
        if (empty($_GET['signature'])) return false;
        $tmp = [$_GET['timestamp'], $_GET['nonce'], $token];
        sort($tmp, SORT_STRING);
        return sha1(implode($tmp)) === $_GET['signature'];
    }
}

使用範例:簡單自動回復

<?php
require 'Wechat.php';
$wechat = new Wechat('YOUR_TOKEN');
$msg = $wechat->request();

if ($msg['MsgType'] === 'text') {
    $keyword = trim($msg['Content']);
    $reply = "你發送了:{$keyword}";
    $wechat->response($reply);
}
// 其他類型同理:$wechat->response($musicArr, 'music'); 等

消息類型對照

MsgType$content 結構說明
textstring純文本
image['MediaId']圖片媒體ID
voice['MediaId']語音媒體ID
video['MediaId','Title','Description']視頻
music['Title','Description','MusicUrl','HQMusicUrl']音樂
news[[Title,Desc,PicUrl,Url], ...]圖文,最多10條

擴展建議

  • 接入 PSR-3 Logger 記錄收發日誌
  • 使用 FastRoute 或自定義路由分發不同消息類型到 Handler 類
  • 引入 Redis 鎖 防止並發重複處理(微信重試機制)
  • 異步任務:耗時操作推入隊列,立即回復「收到」,後台處理完再客服消息推送
  • 加密模式:encrypt_type=aes 時需解密 Encrypt 字段,回復時加密
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved