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

PHP file_get_contents 抓取 HTTPS 失敗兩大解決方案:OpenSSL 擴展與 cURL 替代方案

     編輯:PHP 綜合知識

錯誤現象

Warning: file_get_contents(): failed to open stream: Invalid argument
in /path/to/script.php on line 16

原因:PHP 未啟用 OpenSSL 擴展,無法建立 TLS/SSL 連線。

方案一:啟用 OpenSSL 擴展(推薦,根治)

步驟 1:修改 php.ini

; 找到並取消註解
extension=php_openssl.dll  ; Windows
; 或
extension=openssl.so       ; Linux/macOS

步驟 2:重啟 Web 伺服器

# Apache
systemctl restart httpd
# 或
service apache2 restart

# Nginx + PHP-FPM
systemctl restart php-fpm

步驟 3:驗證



方案二:使用 cURL 替代(免配置、功能更強)

適用於無法修改 php.ini 的虛擬主機環境。

通用 HTTPS 請求函式

function httpsGet(string $url, array $options = []): string|false {
    $ch = curl_init();
    
    $defaults = [
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYPEER => false,  // 僅開發/測試環境使用
        CURLOPT_SSL_VERIFYHOST => false,  // 生產環境請設為 true 並配置 CA 憑證
        CURLOPT_TIMEOUT => 30,
        CURLOPT_CONNECTTIMEOUT => 10,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_MAXREDIRS => 5,
        CURLOPT_USERAGENT => 'PHP-cURL/' . phpversion(),
    ];
    
    curl_setopt_array($ch, $defaults + $options);
    
    $result = curl_exec($ch);
    $error = curl_error($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    
    curl_close($ch);
    
    if ($result === false) {
        error_log("cURL Error [$code]: $error for URL: $url");
        return false;
    }
    
    if ($code >= 400) {
        error_log("HTTP $code for URL: $url");
    }
    
    return $result;
}

// 使用
$html = httpsGet('https://api.example.com/data');
if ($html) {
    $data = json_decode($html, true);
}

進階:支援 POST、標頭、憑證驗證

function httpsRequest(string $url, string $method = 'GET', array $data = [], array $headers = []): string|false {
    $ch = curl_init($url);
    
    $options = [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CUSTOMREQUEST => $method,
        CURLOPT_SSL_VERIFYPEER => true,   // 生產環境必須驗證
        CURLOPT_CAINFO => '/path/to/cacert.pem', // CA 憑證包
        CURLOPT_TIMEOUT => 30,
    ];
    
    if ($method !== 'GET' && $data) {
        $options[CURLOPT_POSTFIELDS] = is_array($data) ? http_build_query($data) : $data;
    }
    
    if ($headers) {
        $options[CURLOPT_HTTPHEADER] = array_map(fn($k, $v) => "$k: $v", array_keys($headers), $headers);
    }
    
    curl_setopt_array($ch, $options);
    $result = curl_exec($ch);
    // ... 錯誤處理同前 ...
    curl_close($ch);
    return $result;
}

生產環境安全配置清單

  1. 必須驗證憑證:CURLOPT_SSL_VERIFYPEER => true
  2. 配置 CA 憑證包:下載 cacert.pem,設定 CURLOPT_CAINFO
  3. 驗證主機名:CURLOPT_SSL_VERIFYHOST => 2
  4. 禁用不安全協定:CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2
  5. 設定超時:避免連線卡死佔用資源

常見問題排查

錯誤原因解決
SSL certificate problemCA 憑證缺失/過期更新 cacert.pem、設定 CURLOPT_CAINFO
SSL connect errorTLS 版本不支援設定 CURLOPT_SSLVERSION
Operation timed out防火牆/網路不通檢查連線、增加超時
Protocol "https" not supportedOpenSSL 未編譯/載入重新編譯 PHP 或載入擴展

掌握這兩大方案,無論是有完整伺服器控制權的環境,還是受限的虛擬主機,都能可靠地處理 HTTPS 請求。生產環境務必啟用完整憑證驗證,保障資料傳輸安全。

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