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

微信公眾平台 PHP 開發入門:CI 框架整合、消息回覆、事件處理、資料庫互動完整範例

     編輯:PHP 綜合知識

微信公眾號開發核心在於接收 XML 訊息、解析類型、組裝回覆 XML。本文以 CodeIgniter 3 框架為載體,提供完整控制器實作:Token 驗證、文本/圖片/語音訊息回覆、圖文訊息、隨機笑話查詢資料庫、菜單式關鍵字路由。程式碼結構清晰,可直接部署至 SAE/一般伺服器,適合快速原型與教學參考。

控制器完整代碼 application/controllers/Welcome.php

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

define('TOKEN', 'your_token_here'); // 需與微信後台設定一致

class Welcome extends CI_Controller {

    public function index()
    {
        // 1. Token 驗證 (微信伺服器配置時呼叫)
        $this->verifySignature();

        // 2. 處理用戶訊息
        $this->responseMsg();
    }

    /** 簽名驗證 */
    private function verifySignature()
    {
        $signature = $_GET['signature'] ?? '';
        $timestamp = $_GET['timestamp'] ?? '';
        $nonce = $_GET['nonce'] ?? '';
        $echostr = $_GET['echostr'] ?? '';

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

        if ($tmpStr === $signature) {
            echo $echostr; // 原樣返回 echostr 完成驗證
            exit;
        }
    }

    /** 訊息處理主流程 */
    public function responseMsg()
    {
        $postStr = $GLOBALS['HTTP_RAW_POST_DATA'] ?? file_get_contents('php://input');
        if (empty($postStr)) return;

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

        // 文本訊息模板
        $textTpl = "<xml>
            <ToUserName><![CDATA[%s]]></ToUserName>
            <FromUserName><![CDATA[%s]]></FromUserName>
            <CreateTime>%s</CreateTime>
            <MsgType><![CDATA[text]]></MsgType>
            <Content><![CDATA[%s]]></Content>
        </xml>";

        // 圖文訊息模板
        $newsTpl = "<xml>
            <ToUserName><![CDATA[%s]]></ToUserName>
            <FromUserName><![CDATA[%s]]></FromUserName>
            <CreateTime>%s</CreateTime>
            <MsgType><![CDATA[news]]></MsgType>
            <ArticleCount>2</ArticleCount>
            <Articles>
                <item>
                    <Title><![CDATA[%s]]></Title>
                    <Description><![CDATA[%s]]></Description>
                    <PicUrl><![CDATA[%s]]></PicUrl>
                    <Url><![CDATA[%s]]></Url>
                </item>
                <item>
                    <Title><![CDATA[%s]]></Title>
                    <Description><![CDATA[%s]]></Description>
                    <PicUrl><![CDATA[%s]]></PicUrl>
                    <Url><![CDATA[%s]]></Url>
                </item>
            </Articles>
        </xml>";

        // 圖片回覆模板
        $imageTpl = "<xml>
            <ToUserName><![CDATA[%s]]></ToUserName>
            <FromUserName><![CDATA[%s]]></FromUserName>
            <CreateTime>%s</CreateTime>
            <MsgType><![CDATA[image]]></MsgType>
            <Image><MediaId><![CDATA[%s]]></MediaId></Image>
        </xml>";

        switch ($msgType) {
            case 'text':
                $keyword = trim((string)$postObj->Content);
                switch ($keyword) {
                    case '1': // 隨機笑話
                        $sql = 'SELECT content FROM jokes ORDER BY RAND() LIMIT 1';
                        $row = $this->db->query($sql)->row();
                        $contentStr = $row ? $row->content : '暫無笑話';
                        break;
                    case '2': // 顯示 OpenID
                        $contentStr = 'Your OpenID: ' . $fromUsername;
                        break;
                    case '3': // 圖文訊息
                        $resultStr = sprintf($newsTpl,
                            $fromUsername, $toUsername, $time,
                            '百度', '', 'https://www.baidu.com/img/bdlogo.gif', 'https://www.baidu.com',
                            'Google', '', '', 'https://www.google.com'
                        );
                        echo $resultStr;
                        exit;
                    case '4':
                        $contentStr = '功能開發中...';
                        break;
                    default: // 選單提示
                        $contentStr = "回覆數字選擇服務:\n1 隨機笑話\n2 獲取 OpenID\n3 圖文訊息\n4 開發中...";
                        break;
                }
                if ($msgType === 'text' && $keyword !== '3') {
                    echo sprintf($textTpl, $fromUsername, $toUsername, $time, $contentStr);
                }
                break;

            case 'image':
                $mediaId = (string)$postObj->MediaId;
                echo sprintf($imageTpl, $fromUsername, $toUsername, $time, $mediaId);
                break;

            case 'voice':
                $contentStr = '收到語音,暂不支援識別。';
                echo sprintf($textTpl, $fromUsername, $toUsername, $time, $contentStr);
                break;

            case 'event':
                $event = (string)$postObj->Event;
                if ($event === 'subscribe') {
                    $contentStr = '歡迎關注!回覆 1-4 體驗功能。';
                    echo sprintf($textTpl, $fromUsername, $toUsername, $time, $contentStr);
                }
                break;

            default:
                echo 'success';
                break;
        }
    }
}

關鍵技術點解析

環節說明注意事項
Token 驗證微信伺服器配置時發送 GET 請求,需原樣返回 echostr驗證通過後才會轉發用戶訊息
原始資料讀取$GLOBALS['HTTP_RAW_POST_DATA'] 或 file_get_contents('php://input')SAE 環境建議用後者
XML 解析simplexml_load_string(..., 'SimpleXMLElement', LIBXML_NOCDATA)LIBXML_NOCDATA 將 CDATA 直接轉為字串屬性
回覆格式必須為標準 XML,內容用 CDATA 區塊CreateTime 為 Unix 時間戳
被動回覆時效5 秒內必須回覆,否則微信顯示「該公眾號暫時無法提供服務」耗時操作需改用客服介面/異步隊列
資料庫查詢CI $this->db->query() 返回結果集笑話表需預先建立

資料庫結構 jokes 表

CREATE TABLE `jokes` (
  `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `content` TEXT NOT NULL,
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

部署檢查清單

[ ] 微信公眾平台 → 開發 → 基本配置:URL 指向控制器 index(), Token 一致
[ ] 伺服器開放 80/443 埠,支援 HTTP/HTTPS
[ ] PHP 開啟 simplexml、pdo_mysql、curl 擴充套件
[ ] CI 配置 database.php 連線資料庫
[ ] 測試:關注公眾號 → 發送 "1" → 應收到隨機笑話
[ ] 開啟開發者模式查看錯誤日誌

進階擴充方向

  1. 客服介面:突破 5 秒限制,主動推送訊息。
  2. 素材管理:上傳永久圖文/圖片/視頻,獲取 media_id 回覆。
  3. 模板訊息:服務通知、訂單狀態變更。
  4. 網頁授權:OAuth2.0 獲取用戶詳細資訊。
  5. 框架遷移:Laravel (EasyWeChat)、Yii2、ThinkPHP 皆有成熟 SDK。

總結

微信公眾號開發本質是 XML 進、XML 出 的無狀態 HTTP 介面。掌握 Token 驗證、訊息類型分發、模板組裝、資料庫互動 四大核心,即可快速構建功能豐富的公眾號應用。本範例以 CI 3 為載體,邏輯可無縫移植至任何 PHP 框架或原生 PHP。

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