php中比file_get_contents()更優的cURL的執行個體詳解

來源:互聯網
上載者:User
PHP 可以使用 file_get_content() 函數抓取網頁內容,但卻無法進行更複雜的處理,譬如檔案的上傳或下載、 Cookie 操作等等。而 PHP 的 cURL 提供了這些功能。

一、cURL簡介

  cURL 是 PHP 的一個擴充庫。它可以與各種類型的伺服器、使用各種類型的協議進行串連和通訊。

  它目前支援 http、https、ftp、gopher、telnet、dict、file 和 ldap 協議,同時也支援 HTTPS 認證、HTTP POST、 FTP 上傳、代理、cookies 和 使用者名稱 + 密碼的認證等。

二、cURL函數庫

  常用函數

函數 描述
curl_init() 初始化 cURL 會話
curl_setopt() 設定 cURL 選項
curl_exec()
執行 cURL 會話
curl_getinfo() 擷取當前會話資訊
curl_errno() 返回最後一次的錯誤碼
curl_error() 返回當前會話最後一次的錯誤字串
curl_close() 關閉 cURL 會話


  其他函數

函數 描述
curl_copy_handle() 複製一個 cURL 控制代碼和它的所有選項。
curl_escape() 返迴轉義字串,對給定的字串進行URL編碼。
curl_file_create() 建立一個 CURLFile 對象。
curl_multi_add_handle() 向 cURL 批處理會話中添加單獨的curl控制代碼。
curl_multi_close() 關閉一組 cURL 控制代碼。
curl_multi_exec() 運行當前 cURL 控制代碼的子串連。
curl_multi_getcontent() 如果設定了 CURLOPT_RETURNTRANSFER ,則返回擷取的輸出的文字資料流。
curl_multi_info_read() 擷取當前解析的 cURL 的相關傳輸資訊。
curl_multi_init() 返回一個新 cURL 批處理控制代碼。
curl_multi_remove_handle() 移除 cURL 批處理控制代碼資源中的某個控制代碼資源。
curl_multi_select() 等待所有 cURL 批處理中的活動串連。
curl_multi_setopt() 設定一個批處理 cURL 傳輸選項。
curl_multi_strerror() 返回描述錯誤碼的字串文本。
curl_pause() 暫停及恢複串連。
curl_reset() 重設 libcurl 的交談控制代碼的所有選項。
curl_setopt_array() 為 cURL 傳輸會話大量設定選項。
curl_share_close() 關閉 cURL 共用控制代碼。
curl_share_init() 初始化 cURL 共用控制代碼。
curl_share_setopt() 設定一個共用控制代碼的 cURL 傳輸選項。
curl_strerror() 返回錯誤碼的字串描述。
curl_unescape() 解碼 URL 編碼後的字串。
curl_version() 擷取 cURL 版本資訊。


三、實現流程

1. 初始化 cURL 會話

2. 設定 cURL 選項

3. 執行 cURL 會話

4. 擷取 cURL 資訊和(或)錯誤資訊(這一步可以沒有)

5. 關閉 cURL 控制代碼

這裡面最複雜的是第 2 步,cURL 的設定選項有很多,下面會結合執行個體來瞭解。


四、執行個體1:GET請求

  GET 請求的流程就是 cURL 的一般流程。

  在本機伺服器 localserver.com 根目錄準備一個測試指令碼 index.php,內容如下:

<?php    $url = 'http://www.baidu.com';    // 初始化,獲得一個cURL控制代碼    $ch = curl_init();        // 設定選項    curl_setopt($ch, CURLOPT_URL, $url); // 請求URL    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //返回資料流,而不直接輸出    curl_setopt($ch, CURLOPT_HEADER, 0); // 無需響應的header頭        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); //連線逾時,秒為單位    // 執行並擷取返回內容    $output = curl_exec($ch);    if($output === false){        $output = 'cURL error: ' . curl_error($ch);    }    // 釋放 cURL 控制代碼資源    curl_close($ch);    print_r($output);?>

  瀏覽器訪問本機伺服器首頁 localserver.com/index.php,顯示百度首頁。

五、執行個體2. POST請求

  POST 請求需要設定兩個選項:

curl_setopt($ch, CURLOPT_POST, 1); // 表明POST請求curl_setopt($ch, CURLOPT_POSTFIELDS, $postData)); // POST提交資料

  先在遠程伺服器 remoteserver.com 根目錄準備一個用於接收的指令碼 index.php,內容如下:

<?php    $input = file_get_contents('php://input');    echo $input;?>

  然後在本機伺服器 localserver.com 根目錄來寫用於 POST 請求的指令碼 index.php,內容如下:

<?php    $url = 'http://remoteserver.com/index.php';    $data = array(        'fname'=> 'Daniel',        'lname' => 'Stenberg'    );     // 初始化    $ch = curl_init();        // 設定選項    curl_setopt($ch, CURLOPT_URL, $url);    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);    curl_setopt($ch, CURLOPT_HEADER, 0);    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);    curl_setopt($ch, CURLOPT_POST, 1); // POST請求    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); //POST資料。用http_build_query()轉換為“&”拼接的字串    // 執行並擷取返回內容    $output = curl_exec($ch);    if($output === false){        $output =  'cURL error: ' . curl_error($ch);    }    // 釋放 cURL 控制代碼資源    curl_close($ch);    print_r($output);?>

  瀏覽器訪問 localserver.com/index.php,顯示如下:

fname=Daniel&lname=Stenberg

六、執行個體3. 上傳檔案

  cURL 上傳檔案的思路是:在檔案路徑的前面添加"@"符號,並裝在請求欄位裡實現上傳。後台可以通過 $_FILES 擷取上傳檔案資訊。但 PHP5.6 以後,廢除了"@"符號,可以使用 CURLFile 類實現上傳。

  先在遠程伺服器 remoteserver.com 根目錄準備一個用於接收的指令碼 index.php,內容如下:

<?php    $action = $_POST['action'];    if($action == 'uploadImage'){        $name = $_FILES['file']['name'];        $tmpname = $_FILES['file']['tmp_name'];                // 儲存到當前指令碼所在目錄        move_uploaded_file($tmpname, dirname(__FILE__).'/'.$name);        $error = $_FILES['file']['error'];        switch ($error) {            case 0: echo '上傳成功'; break;            case 1: echo '檔案大小超出 php.ini 限制'; break;            case 2: echo '檔案大小超出 表單 MAX_FILE_SIZE 限制'; break;            case 3: echo '檔案部分被上傳'; break;            case 4: echo '沒有檔案被上傳'; break;            case 6: echo '找不到臨時檔案夾'; break;            case 7: echo '檔案寫入失敗'; break;            default: $output = '未知錯誤';        }    }?>

   然後在本機伺服器 localserver.com 根目錄準備一個圖片檔案 test.jpg 和 cURL 上傳指令碼 index.php, 指令碼內容如下:

<?php    $url = 'http://remoteserver.com/index.php';    $file = realpath(getcwd() . '/test.jpg');    $data = array(        'action' => 'uploadImage',        'file' => '@' . $file    );    if(version_compare(PHP_VERSION, '5.6.0') > 0){        $data['file'] = new CURLFile($file);    }        // 初始化    $ch = curl_init();        // 設定選項    curl_setopt($ch, CURLOPT_URL, $url);    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);    curl_setopt($ch, CURLOPT_HEADER, 0);    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);    curl_setopt($ch, CURLOPT_POST, 1);    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);    // 執行並擷取返回內容    $output = curl_exec($ch);    if($output === false){        $output =  'cURL error: ' . curl_error($ch);    }    // 釋放 cURL 控制代碼資源    curl_close($ch);    print_r($output);?>

  瀏覽器訪問 localserver.com/index.php,顯示如下:

上傳成功

  查看遠程伺服器根目錄,發現多了一張剛才上傳的圖片。

七、執行個體4. 下載檔案

  cURL 下載檔案的一個思路是:設定 cURL 選項 CURLOPT_FILE 為一個檔案指標,以此將請求的資源檔關聯到一個檔案流裡,這個檔案流一般是 fopen()函數的傳回值。使用檔案流將遠程檔案寫到本地,可以避免寫(下載)大檔案時可能的記憶體出錯。

  在本機伺服器 localserver.com 根目錄來寫測試指令碼 index.php,內容如下:

<?php    $url = 'http://remoteserver.com/test.jpg';    $file = './test.jpg';    $fp = fopen($file, 'w');    // 初始化    $ch = curl_init();    // 設定選項    curl_setopt($ch, CURLOPT_URL, $url);    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);    curl_setopt($ch, CURLOPT_HEADER, 0);    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);    curl_setopt($ch, CURLOPT_FILE, $fp); // 用於傳輸的檔案流,預設是STDOUT    // 執行並擷取返回內容    $output = curl_exec($ch);    if($output === false){        $output =  'cURL error: ' . curl_error($ch);    }    // 擷取已下載大小    $size_download = curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD);    // 釋放資源    fclose($fp);    curl_close($ch);     if ($size_download && $size_download == filesize($file)) {        echo "下載成功";    } else {        echo "下載失敗或不完整";    }   ?>

  瀏覽器訪問 localserver.com/index.php,顯示如下:

下載成功

  查看本機伺服器根目錄,發現下載到了遠端圖片。 

八、執行個體5. 批處理

  cURL 有一個批處理控制代碼,通過開啟多個 cURL 控制代碼,並將這些控制代碼綁定到一個批處理控制代碼,然後在迴圈中依次處理每個 cURL 串連,可以實現非同步批處理,類似“多線程”。

  在本機伺服器 localserver.com 根目錄來寫測試指令碼 index.php,內容如下:

<?php    $urls = array(        'http://www.baidu.com',        'http://www.qidian.com'    );    $count = count($urls);    $ch = array();    // 建立批處理cURL控制代碼    $mh = curl_multi_init();    // 初始化每個cURL,並設定選項,綁定給批處理控制代碼    for ($i = 0; $i < $count; $i++) {        $ch[$i] = curl_init();        curl_setopt($ch[$i], CURLOPT_URL, $urls[$i]);        curl_setopt($ch[$i], CURLOPT_RETURNTRANSFER, 1);        curl_setopt($ch[$i], CURLOPT_HEADER, 0);        curl_setopt($ch[$i], CURLOPT_CONNECTTIMEOUT, 30);        curl_multi_add_handle($mh, $ch[$i]);    }    // 執行批處理    $running = null;    do {        usleep(10000); // 延遲0.01秒,單位為百萬分之一秒        curl_multi_exec($mh, $running); // 非同步實現批處理,類似“多線程”    } while($running > 0);    // 擷取每個cURL的響應    $res = array();    for ($i = 0; $i < $count; $i++) {        $res[$i] = curl_multi_getcontent($ch[$i]);    }    // 關閉全部控制代碼    for ($i = 0; $i < $count; $i++) {        curl_multi_remove_handle($mh, $ch[$i]);    }    curl_multi_close($mh);    print_r($res);?>

  瀏覽器訪問 localserver.com/index.php,顯示“串連”的百度首頁和起點網首頁。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.