首頁  >  文章  >  後端開發  >  php中比file_get_contents()更優的cURL的實例詳解

php中比file_get_contents()更優的cURL的實例詳解

黄舟
黄舟原創
2017-09-11 09:32:382529瀏覽

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_getinfo() 取得目前會話資訊 curl_errno()# 傳回最後一次的錯誤碼  curl_error() 傳回目前會話最後一次的錯誤字串 curl_close() 關閉cURL 會話
函數 說明
 curl_init()  初始化cURL 會話
 curl_setopt() # 設定cURL 選項
 curl_exec()
# 執行cURL 會話


#  其他函數#描述複製一個cURL 句柄和它的所有選項。 傳回轉義字串,對給定的字串進行URL編碼。 建立一個 CURLFile 物件。 #在 cURL 批次會話中加入單獨的curl句柄。 關閉一組 cURL 句柄。 執行目前 cURL 句柄的子連線。 如果設定了 CURLOPT_RETURNTRANSFER ,則傳回所取得的輸出的文字流。 取得目前解析的 cURL 的相關傳輸資訊。 傳回一個新 cURL 批次句柄。 移除 cURL 批次控制碼資源中的某個句柄資源。 等待所有 cURL 批次中的活動連線。 設定一個批次 cURL 傳輸選項。 傳回描述錯誤碼的字串文字。 暫停及恢復連線。 重設 libcurl 的會話句柄的所有選項。 為 cURL 傳輸會話批次設定選項。 關閉 cURL 共享句柄。 初始化 cURL 共享句柄。 設定一個共享句柄的 cURL 傳輸選項。 傳回錯誤代碼的字串描述。 解碼 URL 編碼後的字串。
函數
curl_copy_handle()
curl_escape()
curl_file_create()
curl_multi_add_handle()
curl_multi_close()
curl_multi_exec()
curl_multi_getcontent()
curl_multi_info_read()
curl_multi_init()
curl_multi_remove_handle() 
curl_multi_select()
curl_multi_setopt()
curl_multi_strerror()
curl_pause()
curl_reset()
curl_setopt_array()
curl_share_close()
curl_share_init()
curl_share_setopt()
curl_strerror()
curl_unescape()
######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 = &#39;http://www.baidu.com&#39;;
    // 初始化,获得一个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 = &#39;cURL error: &#39; . 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(&#39;php://input&#39;);
    echo $input;
?>

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

<?php
    $url = &#39;http://remoteserver.com/index.php&#39;;
    $data = array(
        &#39;fname&#39;=> &#39;Daniel&#39;,
        &#39;lname&#39; => &#39;Stenberg&#39;
    );

     // 初始化
    $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 =  &#39;cURL error: &#39; . 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[&#39;action&#39;];
    if($action == &#39;uploadImage&#39;){
        $name = $_FILES[&#39;file&#39;][&#39;name&#39;];
        $tmpname = $_FILES[&#39;file&#39;][&#39;tmp_name&#39;];
        
        // 保存到当前脚本所在目录
        move_uploaded_file($tmpname, dirname(__FILE__).&#39;/&#39;.$name);

        $error = $_FILES[&#39;file&#39;][&#39;error&#39;];
        switch ($error) {
            case 0: echo &#39;上传成功&#39;; break;
            case 1: echo &#39;文件大小超出 php.ini 限制&#39;; break;
            case 2: echo &#39;文件大小超出 表单 MAX_FILE_SIZE 限制&#39;; break;
            case 3: echo &#39;文件部分被上传&#39;; break;
            case 4: echo &#39;没有文件被上传&#39;; break;
            case 6: echo &#39;找不到临时文件夹&#39;; break;
            case 7: echo &#39;文件写入失败&#39;; break;
            default: $output = &#39;未知错误&#39;;
        }
    }
?>

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

<?php
    $url = &#39;http://remoteserver.com/index.php&#39;;
    $file = realpath(getcwd() . &#39;/test.jpg&#39;);
    $data = array(
        &#39;action&#39; => &#39;uploadImage&#39;,
        &#39;file&#39; => &#39;@&#39; . $file
    );
    if(version_compare(PHP_VERSION, &#39;5.6.0&#39;) > 0){
        $data[&#39;file&#39;] = 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 =  &#39;cURL error: &#39; . 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 = &#39;http://remoteserver.com/test.jpg&#39;;
    $file = &#39;./test.jpg&#39;;
    $fp = fopen($file, &#39;w&#39;);

    // 初始化
    $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 =  &#39;cURL error: &#39; . 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(
        &#39;http://www.baidu.com&#39;,
        &#39;http://www.qidian.com&#39;
    );
    $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,顯示「連線」的百度首頁和起點網首頁。

以上是php中比file_get_contents()更優的cURL的實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn