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

PHP cURL 擴展安裝配置全攻略:從報錯到調通新浪登錄 SDK

     編輯:PHP 相關知識

現象:調用 curl_init() 報「Call to undefined function」

新浪/微博/支付寶等開放平台 SDK 依賴 cURL 實現 HTTPS 請求、表單提交、Cookie 管理、憑證驗證。PHP 默認未啟用 cURL 擴展,需手動配置。

cURL 能做什麼?為什麼比 file_get_contents() 強?

能力file_get_contentscURL
HTTP 方法僅 GETGET/POST/PUT/DELETE/PATCH/HEAD...
請求頭控制極其有限完全自定義
Cookie 管理手動拼接自動存儲/發送/持久化
SSL/TLS基本支持憑證驗證、客戶端證書、TLS 版本控制
超時控制僅 default_socket_timeout連接/執行/名稱解析分別設置
多請求並發不支持curl_multi_* 異步並發
進度回調無上傳/下載進度實時回調
代理支持有限HTTP/HTTPS/SOCKS4/5 全支持

分步啟用指南(Windows + Apache + PHP 8.x)

步驟 1:定位正確的 php.ini

<?php phpinfo(); ?>

在瀏覽器查看 Loaded Configuration File 路徑(如 C:\Apache24\bin\php.ini),不是 PHP 安裝目錄下的 php.ini!

步驟 2:啟用擴展

; php.ini 中搜索並取消註釋
extension=curl

PHP 7.2+ 無需具體 php_curl.dll,統一用 extension=curl。

步驟 3:複製依賴 DLL(關鍵步驟,漏這步最容易失敗)

將 PHP 安裝目錄下以下文件複製到 Apache 的 bin 目錄(如 C:\Apache24\bin\)或系統 PATH 目錄:

  • libcrypto-*.dll(OpenSSL 加密庫)
  • libssl-*.dll(OpenSSL SSL 庫)
  • libssh2.dll(SFTP/SCP 支持,可選)
  • nghttp2.dll(HTTP/2 支持,可選)

注意:不要複製到 C:\Windows\System32!會污染系統環境,導致版本衝突。

步驟 4:重啟 Apache 並驗證

httpd.exe -k restart
# 或服務管理器重啟 Apache2.4

再次訪問 phpinfo(),搜索「cURL support → enabled」。

步驟 5:代碼驗證

<?php
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => 'https://httpbin.org/get',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 10,
    CURLOPT_SSL_VERIFYPEER => true,  // 生產必須開啟
    CURLOPT_CAINFO         => __DIR__ . '/cacert.pem', // 指定 CA 憑證包
]);
$response = curl_exec($ch);
if ($response === false) {
    throw new RuntimeException('cURL 錯誤: ' . curl_error($ch), curl_errno($ch));
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

var_dump(json_decode($response, true));
?>

Linux (Ubuntu/CentOS) 一鍵安裝

# Ubuntu/Debian
sudo apt update && sudo apt install php8.2-curl
sudo systemctl restart php8.2-fpm nginx

# CentOS/RHEL/Rocky/Alma
sudo dnf install php-curl  # 或 php82-php-curl (Remi 源)
sudo systemctl restart php-fpm nginx

新浪登錄 SDK 實戰配置

<?php
// 完整的 cURL 選項模板,適配新浪/微博 OAuth
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => 'https://api.weibo.com/oauth2/access_token',
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => http_build_query([
        'client_id'     => 'YOUR_APP_KEY',
        'client_secret' => 'YOUR_APP_SECRET',
        'grant_type'    => 'authorization_code',
        'redirect_uri'  => 'https://your.com/callback',
        'code'          => $_GET['code'],
    ]),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 15,
    CURLOPT_CONNECTTIMEOUT => 5,
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_SSL_VERIFYHOST => 2,
    CURLOPT_CAINFO         => __DIR__ . '/cacert.pem', // 必須!
    CURLOPT_USERAGENT      => 'YourApp/1.0 (+https://your.com)',
    CURLOPT_HTTPHEADER     => [
        'Accept: application/json',
        'Content-Type: application/x-www-form-urlencoded',
    ],
    // 可選:Cookie 持久化(多步驟 OAuth 需要)
    CURLOPT_COOKIEJAR      => sys_get_temp_dir() . '/weibo_cookie.txt',
    CURLOPT_COOKIEFILE     => sys_get_temp_dir() . '/weibo_cookie.txt',
]);

$response = curl_exec($ch);
if ($response === false) {
    error_log('新浪 OAuth cURL 錯誤: ' . curl_error($ch));
    // 降級處理或拋出異常
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$result = json_decode($response, true);
if ($httpCode !== 200 || empty($result['access_token'])) {
    throw new RuntimeException('獲取 access_token 失敗: ' . ($result['error_description'] ?? '未知錯誤'));
}
// 存儲 $result['access_token']、$result['expires_in']、$result['uid']
?>

必備:CA 憑證包 cacert.pem

cURL 驗證 HTTPS 服務器憑證需要信任根憑證。下載最新版:

wget https://curl.se/ca/cacert.pem -O /etc/ssl/certs/cacert.pem
# 或 PHP 目錄
wget https://curl.se/ca/cacert.pem -O /usr/local/php/cacert.pem

在 php.ini 全局配置:

curl.cainfo = /etc/ssl/certs/cacert.pem
openssl.cafile = /etc/ssl/certs/cacert.pem

常見錯誤排查表

錯誤信息原因解決
SSL certificate problem: unable to get local issuer certificate缺少 CA 憑證包配置 CURLOPT_CAINFO 或 curl.cainfo
Could not resolve hostDNS 解析失敗檢查服務器 DNS、/etc/resolv.conf、防火牆
Connection timed out網絡不通/防火牆攔截檢查安全組、iptables、目標 IP 端口通達性
Protocol "https" not supportedcURL 編譯無 OpenSSL重裝 php-curl、確保 libssl 存在
cURL error 60同 SSL 憑證問題同上

進階:cURL 多請求並發(批量調用 API)

<?php
function multiCurl(array $urls, int $maxConcurrent = 10): array {
    $mh = curl_multi_init();
    $handles = [];
    $results = [];
    
    foreach ($urls as $i => $url) {
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 10,
            CURLOPT_SSL_VERIFYPEER => true,
            CURLOPT_CAINFO => '/etc/ssl/certs/cacert.pem',
        ]);
        curl_multi_add_handle($mh, $ch);
        $handles[$i] = $ch;
        
        // 控制並發數
        if (count($handles) >= $maxConcurrent) {
            $results = array_merge($results, executeMulti($mh, $handles));
            $handles = [];
        }
    }
    if ($handles) $results = array_merge($results, executeMulti($mh, $handles));
    curl_multi_close($mh);
    return $results;
}

function executeMulti($mh, &$handles): array {
    $running = null;
    do { curl_multi_exec($mh, $running); } while ($running);
    $results = [];
    foreach ($handles as $i => $ch) {
        $results[$i] = [
            'content' => curl_multi_getcontent($ch),
            'http_code' => curl_getinfo($ch, CURLINFO_HTTP_CODE),
            'error' => curl_error($ch),
        ];
        curl_multi_remove_handle($mh, $ch);
        curl_close($ch);
    }
    return $results;
}
?>

總結

  1. phpinfo() 定位 php.ini 是第一步,別改錯文件
  2. 複製 OpenSSL DLL 到 Apache bin 目錄 是 Windows 下的核心避坑點
  3. 生產環境必須啟用 SSL 驗證並配置 CA 憑證,切勿 CURLOPT_SSL_VERIFYPEER => false
  4. 新浪等 OAuth 流程 需正確設置 CURLOPT_POSTFIELDS、Content-Type、Cookie 持久化
  5. 高併發場景 使用 curl_multi_* 或 Swoole/ReactPHP 異步客戶端

配好 cURL,PHP 對接任何 HTTP API 都不再是夢魘!

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