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

PHP cURL 實戰:模擬 GET/POST 請求微信接口獲取 Access Token 與發送客服消息

     編輯:PHP 綜合知識

前言

PHP cURL 是後端調用第三方 HTTP API 的利器。微信開發中,獲取 access_token(GET)、發送客服消息/模板消息(POST)均需通過 cURL 實現。本文提供兩個封裝良好、可直接用於生產的函數示例,涵蓋 HTTPS 處理、JSON 編解碼、錯誤處理等關鍵細節。

場景一:GET 獲取 Access Token

access_token 是調用所有微信高級接口的憑證,有效期 7200 秒。建議緩存到 Redis/文件/數據庫,避免頻繁請求觸發限流。

/**
 * 獲取微信 access_token
 * @return string|false access_token 或 false(失敗)
 */
function getAccessToken() {
    $appId     = 'YOUR_APPID';
    $appSecret = 'YOUR_APPSECRET';
    $url       = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appId}&secret={$appSecret}";
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);  // 生產環境建議配置 CA 憑證路徑
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);            // 連接超時 10 秒
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);      // DNS/連接建立超時 5 秒
    
    $response = curl_exec($ch);
    $errno    = curl_errno($ch);
    $error    = curl_error($ch);
    curl_close($ch);
    
    if ($errno) {
        error_log("cURL Error [{$errno}]: {$error} - URL: {$url}");
        return false;
    }
    
    $data = json_decode($response, true);
    if (isset($data['errcode'])) {
        error_log("WeChat API Error: {$data['errcode']} - {$data['errmsg']}");
        return false;
    }
    
    return $data['access_token'] ?? false;
}

場景二:POST 發送客服消息(圖文消息)

客服消息接口要求 JSON 格式 POST,支持文本、圖片、語音、視頻、圖文、菜單等類型。下面以發送「天氣圖文消息」為例。

/**

 * 發送客服圖文消息
 * @param string $openid 用戶 OpenID
 * @param string $access_token 有效憑證
 * @return array|false 微信返回結果或 false
 */
function sendNewsMessage($openid, $access_token) {
    $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={$access_token}";
    
    $postData = [
        'touser'  => $openid,
        'msgtype' => 'news',
        'news'    => [
            'articles' => [[
                'title'       => '今日天氣預報',
                'description' => '晴轉多雲 18~25°C,紫外線強,建議攜帶雨具防曬。',
                'url'         => 'https://www.weather.com.cn/weather/101010100.shtml',
                'picurl'      => 'https://example.com/assets/weather_sunny.jpg',
            ]],
        ],
    ];
    
    $jsonData = json_encode($postData, JSON_UNESCAPED_UNICODE);  // 中文不轉義
    
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json; charset=utf-8',
        'Content-Length: ' . strlen($jsonData),
    ]);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_TIMEOUT, 15);
    
    $response = curl_exec($ch);
    $errno    = curl_errno($ch);
    $error    = curl_error($ch);
    curl_close($ch);
    
    if ($errno) {
        error_log("cURL Error [{$errno}]: {$error}");
        return false;
    }
    
    return json_decode($response, true);
}

通用 cURL 封裝建議

實際項目中建議封裝一個 HttpClient 類,統一處理:

  • 超時配置(連接/讀寫/總超時)
  • HTTPS 證書驗證(生產環境必須開啟 CURLOPT_CAINFO)
  • 自動重試(指數退避、冪等接口)
  • 錯誤日誌記錄(請求 URL、參數、響應、耗時)
  • 支持代理、Keep-Alive、HTTP/2
class HttpClient {
    private $ch;
    private $defaultOptions = [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HEADER         => false,
        CURLOPT_TIMEOUT        => 15,
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_SSL_VERIFYPEER => true,   // 生產環境 true
        CURLOPT_CAINFO         => '/path/to/cacert.pem',  // CA 憑證路徑
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_MAXREDIRS      => 3,
        CURLOPT_ENCODING       => 'gzip,deflate',  // 支持壓縮
    ];
    
    public function __construct() {
        $this->ch = curl_init();
        curl_setopt_array($this->ch, $this->defaultOptions);
    }
    
    public function get(string $url, array $headers = []): ?array { /* ... */ }
    public function post(string $url, $data, array $headers = []): ?array { /* ... */ }
    public function __destruct() { curl_close($this->ch); }
}

常見坑點避坑指南

問題原因解決
cURL error 60: SSL certificate problem未配置 CA 憑證或證書過期設置 CURLOPT_CAINFO 指向有效 cacert.pem,或臨時關閉驗證(僅測試)
返回 errcode 40001: invalid credentialaccess_token 過期/錯誤/被刷新緩存 token 並提前刷新,失敗時重試獲取
POST 參數格式錯誤未設置 Content-Type: application/json手動添加 HTTPHEADER,或使用 CURLFile 上傳文件
中文亂碼json_encode 默認轉義 Unicode使用 JSON_UNESCAPED_UNICODE 參數

延伸閱讀

更多實戰技巧:PHP cURL 用法總結、PHP 微信開發技巧匯總、PHP 網絡編程技巧總結 等專題。

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