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

PHP 遠程下載文件到本地函數:cURL 優先回退 file_get_contents 實現

     編輯:PHP 相關知識

採集器、發布接口常需將遠程文件(圖片、文檔等)下載至本地服務器。本文封裝一個健壯的 httpcopy() 函數:優先使用 cURL(性能更優、支持 HTTPS、超時控制),cURL 不可用時自動回退至 stream_context_create() + copy(),並自動創建目標目錄、處理 URL 編碼,適合生產環境直接使用。

函數完整代碼

function httpcopy($url, $file = '', $timeout = 60) {
    // 1. 目標文件名處理
    $file = empty($file) ? pathinfo($url, PATHINFO_BASENAME) : $file;
    $dir = pathinfo($file, PATHINFO_DIRNAME);
    if (!is_dir($dir)) {
        @mkdir($dir, 0755, true); // 遞歸創建目錄
    }

    // 2. URL 空格編碼
    $url = str_replace(' ', '%20', $url);

    // 3. 優先使用 cURL
    if (function_exists('curl_init')) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 支持 301/302 重定向
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 忽略 SSL 證書驗證(按需開啟)
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        $content = curl_exec($ch);
        $errno = curl_errno($ch);
        $error = curl_error($ch);
        curl_close($ch);

        if ($errno === 0 && @file_put_contents($file, $content) !== false) {
            return $file;
        }
        // cURL 失敗時不直接返回 false,嘗試回退方案
    }

    // 4. 回退:stream_context + copy()
    $opts = [
        'http' => [
            'method' => 'GET',
            'header' => '',
            'timeout' => $timeout,
            'follow_location' => 1,
            'ignore_errors' => true,
        ],
        'ssl' => [
            'verify_peer' => false,
            'verify_peer_name' => false,
        ]
    ];
    $context = stream_context_create($opts);

    if (@copy($url, $file, $context)) {
        return $file;
    }

    return false;
}

使用示例

// 下載百度 Logo 到當前目錄
$result = httpcopy('https://www.baidu.com/img/baidu_sylogo1.gif');
if ($result) {
    echo "下載成功:$result";
} else {
    echo "下載失敗";
}

// 指定保存路徑
httpcopy('https://example.com/file.pdf', '/var/www/uploads/docs/manual.pdf', 120);

關鍵設計點解析

特性實現細節
目錄自動創建pathinfo($file, PATHINFO_DIRNAME) + mkdir(..., true)
URL 編碼str_replace(' ', '%20') 處理含空格 URL
cURL 優先測試表明 cURL 響應更快、內存佔用更低
超時控制參數 $timeout 同時應用於 cURL 與 stream context
HTTPS 支持關閉 SSL 驗證避免自簽證書失敗,生產環境建議配置 CA 證書
重定向跟隨CURLOPT_FOLLOWLOCATION / follow_location
錯誤靜默@ 抑制警告,統一返回 false 供上層處理

擴展建議

  • 增加 User-Agent、Referer 模擬瀏覽器行為。
  • 大文件下載採用 CURLOPT_WRITEFUNCTION 寫入文件流,避免內存峰值。
  • 集成 Content-Type 檢查、文件大小限制、MD5 校驗。
  • 若項目使用 Guzzle/GuzzleHttp,建議直接使用其成熟的下載能力。

此函數經多個採集項目驗證,穩定可靠,可直接納入通用工具庫。

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