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

PHP 微信公眾號開發:消息自動回復核心原理與文本/圖片消息處理實戰

     編輯:PHP 相關知識

微信消息交互流程

  1. 用戶發送消息 → 微信服務器
  2. 微信服務器將消息封裝為 XML → POST 到開發者配置的 URL
  3. 開發者服務器解析 XML、處理業務邏輯 → 組裝回復 XML → 直接 echo 輸出
  4. 微信服務器將回復推送給用戶

核心難點解析

Q1: 為什麼用 $GLOBALS['HTTP_RAW_POST_DATA'] 而非 $_POST?

$_POST 只能解析 application/x-www-form-urlencoded 或 multipart/form-data 格式。微信推送的是 XML 數據包 (Content-Type: text/xml 或 application/xml),PHP 不會自動填充 $_POST。
$GLOBALS['HTTP_RAW_POST_DATA'] (PHP 5.6+ 棄用) 或 file_get_contents('php://input') (推薦) 可獲取原始 POST 數據體。

Q2: simplexml_load_string() 關鍵參數詳解

$xmlObj = simplexml_load_string($xmlString, 'SimpleXMLElement', LIBXML_NOCDATA);
  • SimpleXMLElement:返回對象類型,支援屬性式訪問 $obj->Content。
  • LIBXML_NOCDATA:將 CDATA 節點內容直接作為文本節點,避免得到 SimpleXMLElement 對象需再轉字符串。

完整實作:文本消息自動回復

<?php
define('TOKEN', 'weixin');

$wechat = new Wechat();
$wechat->valid();

class Wechat {
    public function valid() {
        $echoStr = $_GET['echostr'] ?? '';
        
        // 首次驗證:原樣返回 echostr
        if ($this->checkSignature() && $echoStr) {
            echo $echoStr;
            exit;
        }
        
        // 正常消息處理
        $this->responseMsg();
    }

    private function checkSignature(): bool {
        $signature = $_GET['signature'] ?? '';
        $timestamp = $_GET['timestamp'] ?? '';
        $nonce     = $_GET['nonce'] ?? '';
        $token     = TOKEN;

        $tmpArr = [$token, $timestamp, $nonce];
        sort($tmpArr, SORT_STRING);
        $tmpStr = implode($tmpArr);
        $tmpStr = sha1($tmpStr);

        return $tmpStr === $signature;
    }

    public function responseMsg() {
        // 1. 獲取原始 XML
        $postStr = file_get_contents('php://input'); // 推薦方式
        if (empty($postStr)) {
            exit('');
        }

        // 2. 解析 XML
        $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
        if (!$postObj) {
            error_log('XML 解析失敗: ' . $postStr);
            exit('');
        }

        $fromUser   = (string)$postObj->FromUserName;
        $toUser     = (string)$postObj->ToUserName;
        $msgType    = strtolower((string)$postObj->MsgType);
        $content    = trim((string)$postObj->Content);
        $time       = time();

        // 3. 回復模板
        $template = "<xml>
    <ToUserName><![CDATA[%s]]></ToUserName>
    <FromUserName><![CDATA[%s]]></FromUserName>
    <CreateTime>%s</CreateTime>
    <MsgType><![CDATA[%s]]></MsgType>
    <Content><![CDATA[%s]]></Content>
</xml>";

        // 4. 業務邏輯
        if ($msgType !== 'text') {
            $replyType = 'text';
            $replyContent = '我只能處理文本消息哦~';
        } elseif (empty($content)) {
            $replyType = 'text';
            $replyContent = '請輸入一些內容吧!';
        } else {
            $replyType = 'text';
            $replyContent = '你說了:' . $content;
        }

        // 5. 輸出回復
        echo sprintf($template, $fromUser, $toUser, $time, $replyType, $replyContent);
    }
}
?>

完整實作:圖片消息自動回復

<?php
// ... valid() 與 checkSignature() 同前 ...

public function responseMsg() {
    $postStr = file_get_contents('php://input');
    if (empty($postStr)) exit('');

    $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
    $fromUser = (string)$postObj->FromUserName;
    $toUser   = (string)$postObj->ToUserName;
    $msgType  = strtolower((string)$postObj->MsgType);
    $time     = time();

    $template = "<xml>
    <ToUserName><![CDATA[%s]]></ToUserName>
    <FromUserName><![CDATA[%s]]></FromUserName>
    <CreateTime>%s</CreateTime>
    <MsgType><![CDATA[%s]]></MsgType>
    <Content><![CDATA[%s]]></Content>
</xml>";

    if ($msgType !== 'image') {
        $replyType = 'text';
        $replyContent = '請發送圖片消息。';
    } else {
        $picUrl  = (string)$postObj->PicUrl;
        $mediaId = (string)$postObj->MediaId;
        
        if (empty($picUrl)) {
            $replyContent = '未獲取到圖片鏈接。';
        } else {
            $replyContent = "收到圖片!\n鏈接:{$picUrl}\nMediaId:{$mediaId}";
        }
        $replyType = 'text';
    }

    echo sprintf($template, $fromUser, $toUser, $time, $replyType, $replyContent);
}
?>

XML 消息結構速查

消息類型關鍵節點
文本Content
圖片PicUrl, MediaId
語音MediaId, Format, Recognition (語音識別結果)
視頻MediaId, ThumbMediaId
地理位置Location_X, Location_Y, Scale, Label
鏈接Title, Description, Url
事件Event (subscribe/unsubscribe/CLICK/VIEW/SCAN/LOCATION...), EventKey

生產環境必備加固

  • 響應超時:微信要求 5 秒內響應,耗時邏輯必須異步處理(隊列/異步任務),先返回「收到」或空串。
  • 簽名驗證:checkSignature() 必須在處理前調用,防止偽造請求。
  • 日誌記錄:記錄所有進出 XML,便於排查。
  • 加密模式:生產環境建議啟用「安全模式」(AES 加密),使用 WXBizMsgCrypt 解密/加密。
  • 去重:利用 MsgId 防止重複處理。

掌握 XML 解析、回復模板、業務分發這三大核心,即可快速構建微信公眾號自動回復機器人,進階可接入圖靈/NLP/客服系統實現智能對話。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved