日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

PHP 的 cURL库快速入门文档

發布時間:2025/7/14 php 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PHP 的 cURL库快速入门文档 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者:Burak Guzel

原文鏈接:http://net.tutsplus.com/tutorials/php/techniques-and-resources-for-mastering-curl/

翻譯:笨活兒

cURL 是一個利用 URL 語法規定來傳輸文件和數據的工具,支持很多協議,如 HTTP、FTP、TELNET 等。最爽的是,PHP 也支持 cURL 庫。本文將介紹 cURL 的一些高級特性,以及在 PHP 中如何運用它。

?

為什么要用 cURL?

是的,我們可以通過其他辦法獲取網頁內容。大多數時候,我因為想偷懶,都直接用簡單的PHP函數:

12345 $content = file_get_contents("http://www.nettuts.com");// or$lines = file("http://www.nettuts.com");// orreadfile(http://www.nettuts.com);

不過,這種做法缺乏靈活性和有效的錯誤處理。而且,你也不能用它完成一些高難度任務——比如處理coockies、驗證、表單提交、文件上傳等等。

基本結構

在學習更為復雜的功能之前,先來看一下在 PHP 中建立 cURL 請求的基本步驟:

  • 初始化
  • 設置變量
  • 執行并獲取結果
  • 釋放 cURL 句柄
  • 12345678910111213 // 1. 初始化$ch = curl_init();// 2. 設置選項,包括URLcurl_setopt($ch, CURLOPT_URL, "http://www.nettuts.com");curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_HEADER, 0);// 3. 執行并獲取HTML文檔內容$output = curl_exec($ch);// 4. 釋放curl句柄curl_close($ch);

    第二步(也就是 curl_setopt() )最為重要,一切玄妙均在此。有一長串 cURL 參數可供設置,它們能指定 URL 請求的各個細節。要一次性全部看完并理解可能比較困難,所以今天我們只試一下那些更常用也更有用的選項。

    檢查錯誤

    你可以加一段檢查錯誤的語句(雖然這并不是必需的):

    123456 // ...$output = curl_exec($ch);if ($output === FALSE) { echo "cURL Error: " . curl_error($ch);}// ...

    請注意,比較的時候我們用的是“=== FALSE”,而非“== FALSE”。因為我們得區分 空輸出 和 布爾值 FALSE,后者才是真正的錯誤。

    獲取信息

    這是另一個可選的設置項,能夠在 cURL 執行后獲取這一請求的有關信息:

    12345 // ...curl_exec($ch);$info = curl_getinfo($ch);echo '獲取'. $info['url'] . '耗時'. $info['total_time'] . '秒';// ...

    返回的數組中包括了以下信息:

    “url” //資源網絡地址

    “content_type” //內容編碼

    “http_code” //HTTP狀態碼

    “header_size” //header的大小

    “request_size” //請求的大小

    “filetime” //文件創建時間

    “ssl_verify_result” //SSL驗證結果

    “redirect_count” //跳轉技術

    “total_time” //總耗時

    “namelookup_time” //DNS查詢耗時

    “connect_time” //等待連接耗時

    “pretransfer_time” //傳輸前準備耗時

    “size_upload” //上傳數據的大小

    “size_download” //下載數據的大小

    “speed_download” //下載速度

    “speed_upload” //上傳速度

    “download_content_length”//下載內容的長度

    “upload_content_length” //上傳內容的長度

    “starttransfer_time” //開始傳輸的時間

    “redirect_time”//重定向耗時

    基于瀏覽器的重定向

    在第一個例子中,我們將提供一段用于偵測服務器是否有基于瀏覽器的重定向的代碼。例如,有些網站會根據是否是手機瀏覽器甚至用戶來自哪個國家來重定向網頁。

    我們利用 CURLOPT_HTTPHEADER 選項來設定我們發送出的 HTTP 請求頭信息(http headers),包括 user agent 信息和默認語言。然后我們來看看這些特定網站是否會把我們重定向到不同的URL。

    12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 // test URLs$urls = array("http://www.cnn.com","http://www.mozilla.com","http://www.facebook.com");// test browsers$browsers = array("standard" => array ("user_agent" => "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 3.5.30729)","language" => "en-us,en;q=0.5"),"iphone" => array ("user_agent" => "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A537a Safari/419.3","language" => "en"),"french" => array ("user_agent" => "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; GTB6; .NET CLR 2.0.50727)","language" => "fr,fr-FR;q=0.5"));foreach ($urls as $url) {echo "URL: $urln";foreach ($browsers as $test_name => $browser) {$ch = curl_init();// set urlcurl_setopt($ch, CURLOPT_URL, $url);// set browser specific headerscurl_setopt($ch, CURLOPT_HTTPHEADER, array("User-Agent: {$browser['user_agent']}","Accept-Language: {$browser['language']}"));// we don't want the page contentscurl_setopt($ch, CURLOPT_NOBODY, 1);// we need the HTTP Header returnedcurl_setopt($ch, CURLOPT_HEADER, 1);// return the results instead of outputting itcurl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);$output = curl_exec($ch);curl_close($ch);// was there a redirection HTTP header?if (preg_match("!Location: (.*)!", $output, $matches)) {echo "$test_name: redirects to $matches[1]n";} else {echo "$test_name: no redirectionn";}}echo "nn";}

    首先,我們建立一組需要測試的URL,接著指定一組需要測試的瀏覽器信息。最后通過循環測試各種URL和瀏覽器匹配可能產生的情況。

    因為我們指定了cURL選項,所以返回的輸出內容則只包括HTTP頭信息(被存放于 $output 中)。利用一個簡單的正則,我們檢查這個頭信息中是否包含了“Location:”字樣。

    運行這段代碼應該會返回如下結果:

    用POST方法發送數據

    當發起 GET 請求時,數據可以通過“查詢字串”(query string)傳遞給一個URL。例如,在google中搜索時,搜索關鍵即為 URL 的查詢字串的一部分:

    http://www.google.com/search?q=nettuts

    這種情況下你可能并不需要 cURL 來模擬。把這個 URL 丟給“file_get_contents()”就能得到相同結果。

    不過有一些 HTML 表單是用 POST 方法提交的。這種表單提交時,數據是通過 HTTP 請求體(request body) 發送,而不是查詢字串。例如,當使用 CodeIgniter 論壇的表單,無論你輸入什么關鍵字,總是被 POST 到如下頁面:

    http://codeigniter.com/forums/do_search/

    你可以用 PHP 腳本來模擬這種 URL 請求。首先,新建一個可以接受并顯示 POST 數據的文件,我們給它命名為post_output.php:

    print_r($_POST);

    接下來,寫一段 PHP 腳本來執行 cURL 請求:

    12345678910111213 $url = "http://localhost/post_output.php";$post_data = array ( "foo" => "bar", "query" => "Nettuts", "action" => "Submit");$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);// 我們在POST數據哦!curl_setopt($ch, CURLOPT_POST, 1);// 把post的變量加上curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);$output = curl_exec($ch);curl_close($ch);echo $output;

    執行代碼后應該會得到以下結果:

    這段腳本發送一個 POST 請求給 post_output.php ,這個頁面 $_POST 變量并返回,我們利用 cURL 捕捉了這個輸出。

    文件上傳

    上傳文件和前面的 POST 十分相似。因為所有的文件上傳表單都是通過 POST 方法提交的。

    首先新建一個接收文件的頁面,命名為 upload_output.php:

    print_r($_FILES);

    以下是真正執行文件上傳任務的腳本:

    12345678910111213141516 $url = "http://localhost/upload_output.php";$post_data = array ( "foo" => "bar", // 要上傳的本地文件地址 "upload" => "@C:/wamp/www/test.zip");$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);$output = curl_exec($ch);curl_close($ch);echo $output;

    如果你需要上傳一個文件,只需要把文件路徑像一個 post 變量一樣傳過去,不過記得在前面加上@符號。執行這段腳本應該會得到如下輸出:

    cURL批處理(multi cURL

    cURL 還有一個高級特性——批處理句柄(handle)。這一特性允許你同時或異步地打開多個URL連接。

    下面是來自來自 php.net 的示例代碼:

    12345678910111213141516171819202122232425262728293031323334353637 // 創建兩個cURL資源$ch1 = curl_init();$ch2 = curl_init();// 指定URL和適當的參數curl_setopt($ch1, CURLOPT_URL, "http://lxr.php.net/");curl_setopt($ch1, CURLOPT_HEADER, 0);curl_setopt($ch2, CURLOPT_URL, "http://www.php.net/");curl_setopt($ch2, CURLOPT_HEADER, 0);// 創建cURL批處理句柄$mh = curl_multi_init();// 加上前面兩個資源句柄curl_multi_add_handle($mh,$ch1);curl_multi_add_handle($mh,$ch2);// 預定義一個狀態變量$active = null;// 執行批處理do { $mrc = curl_multi_exec($mh, $active);} while ($mrc == CURLM_CALL_MULTI_PERFORM);while ($active && $mrc == CURLM_OK) { if (curl_multi_select($mh) != -1) { do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); }}//關閉各個句柄curl_multi_remove_handle($mh, $ch1);curl_multi_remove_handle($mh, $ch2);curl_multi_close($mh);

    這里要做的就是打開多個 cURL 句柄并指派給一個批處理句柄。然后你就只需在一個 while 循環里等它執行完畢。

    這個示例中有兩個主要循環。第一個 do-while 循環重復調用 curl_multi_exec() 。這個函數是無隔斷(non-blocking)的,但會盡可能少地執行。它返回一個狀態值,只要這個值等于常量 CURLM_CALL_MULTI_PERFORM ,就代表還有一些刻不容緩的工作要做(例如,把對應 URL 的 http 頭信息發送出去)。也就是說,我們需要不斷調用該函數,直到返回值發生改變。

    而接下來的 while 循環,只在 $active 變量為 true 時繼續。這一變量之前作為第二個參數傳給了 curl_multi_exec() ,代表只要批處理句柄中是否還有活動連接。接著,我們調用 curl_multi_select() ,在活動連接(例如接受服務器響應)出現之前,它都是被“屏蔽”的。這個函數成功執行后,我們又會進入另一個 do-while 循環,繼續下一條URL。

    還是來看一看怎么把這一功能用到實處吧:

    WordPress 連接檢查器

    想象一下你有一個文章數目龐大的博客,這些文章中包含了大量外部網站鏈接。一段時間之后,因為這樣那樣的原因,這些鏈接中相當數量都失效了。要么是被和諧了,要么是整個站點都被功夫網了…

    我們下面建立一個腳本,分析所有這些鏈接,找出打不開或者 404 的網站/網頁,并生成一個報告。

    請注意,以下并不是一個真正可用的 WordPress 插件,僅僅是一段獨立功能的腳本而已,僅供演示,謝謝。

    好,開始吧。首先,從數據庫中讀取所有這些鏈接:

    12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 // CONFIG$db_host = 'localhost';$db_user = 'root';$db_pass = '';$db_name = 'wordpress';$excluded_domains = array('localhost', 'www.mydomain.com');$max_connections = 10;// initialize some variables$url_list = array();$working_urls = array();$dead_urls = array();$not_found_urls = array();$active = null;// connect to MySQLif (!mysql_connect($db_host, $db_user, $db_pass)) {die('Could not connect: ' . mysql_error());}if (!mysql_select_db($db_name)) {die('Could not select db: ' . mysql_error());}// get all published posts that have links$q = "SELECT post_content FROM wp_postsWHERE post_content LIKE '%href=%'AND post_status = 'publish'AND post_type = 'post'";$r = mysql_query($q) or die(mysql_error());while ($d = mysql_fetch_assoc($r)) {// get all links via regexif (preg_match_all("!href="(.*?)"!", $d['post_content'], $matches)) {foreach ($matches[1] as $url) {// exclude some domains$tmp = parse_url($url);if (in_array($tmp['host'], $excluded_domains)) {continue;}// store the url$url_list []= $url;}}}// remove duplicates$url_list = array_values(array_unique($url_list));if (!$url_list) {die('No URL to check');}

    我們首先配置好數據庫,一系列要排除的域名($excluded_domains),以及最大并發連接數($max_connections)。然后,連接數據庫,獲取文章和包含的鏈接,把它們收集到一個數組中($url_list)。

    下面的代碼有點復雜了,因此我將一小步一小步地詳細解釋:

    123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 // 1. 批處理器$mh = curl_multi_init();// 2. 加入需要批處理的 URLfor ($i = 0; $i < $max_connections; $i++) {add_url_to_multi_handle($mh, $url_list);}// 3. 初始化處理do {$mrc = curl_multi_exec($mh, $active);} while ($mrc == CURLM_CALL_MULTI_PERFORM);// 4. 主循環while ($active && $mrc == CURLM_OK) {// 5. 有活動鏈接if (curl_multi_select($mh) != -1) {// 6. 干活do {$mrc = curl_multi_exec($mh, $active);} while ($mrc == CURLM_CALL_MULTI_PERFORM);// 7. 是否有信息?if ($mhinfo = curl_multi_info_read($mh)) {// 意味著該鏈接正常結束// 8. 從 curl 句柄獲取信息$chinfo = curl_getinfo($mhinfo['handle']);// 9. 死鏈?if (!$chinfo['http_code']) {$dead_urls []= $chinfo['url'];// 10. 404?} else if ($chinfo['http_code'] == 404) {$not_found_urls []= $chinfo['url'];// 11. 還能用} else {$working_urls []= $chinfo['url'];}// 12. 移除句柄curl_multi_remove_handle($mh, $mhinfo['handle']);curl_close($mhinfo['handle']);// 13. 加入新 URL,干活if (add_url_to_multi_handle($mh, $url_list)) {do {$mrc = curl_multi_exec($mh, $active);} while ($mrc == CURLM_CALL_MULTI_PERFORM);}}}}// 14. 結束curl_multi_close($mh);echo "==Dead URLs==n";echo implode("n",$dead_urls) . "nn";echo "==404 URLs==n";echo implode("n",$not_found_urls) . "nn";echo "==Working URLs==n";echo implode("n",$working_urls);// 15. 向批處理器添加 URLfunction add_url_to_multi_handle($mh, $url_list) {static $index = 0;// 如果還有 URL 沒用if ($url_list[$index]) {// 新建 curl 句柄$ch = curl_init();// 配置 curlcurl_setopt($ch, CURLOPT_URL, $url_list[$index]);// 不想輸出返回內容curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);// 跟蹤重定向curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);// 不需要返回內容,節省帶寬和時間curl_setopt($ch, CURLOPT_NOBODY, 1);// 加入到批處理器中curl_multi_add_handle($mh, $ch);// 撥一下計數器,下次調用該函數就能添加下一個 url 了$index++;return true;} else {// 沒有新的URL需要處理了return false;}}

    下面解釋一下以上代碼。列表的序號對應著代碼注釋中的順序數字。

  • 新建一個批處理器。Created a multi handle.
  • 稍后我們將創建一個把URL加入批處理器的函數 add_url_to_multi_handle() 。每當這個函數被調用,就有一個新url被加入批處理器。一開始,我們給批處理器添加了10個URL(這一數字由 $max_connections 所決定)。
  • 運行 curl_multi_exec() 進行初始化工作是必須的,只要它返回 CURLM_CALL_MULTI_PERFORM 就還有事情要做。這么做主要是為了創建連接,它不會等待完整的URL響應。
  • 只要批處理中還有活動連接主循環就會一直持續。
  • curl_multi_select() 會一直等待,直到某個URL查詢產生活動連接。
  • cURL的活兒又來了,主要是獲取響應數據。
  • 檢查各種信息。當一個URL請求完成時,會返回一個數組。
  • 在返回的數組中有一個 cURL 句柄。我們利用其獲取單個cURL請求的相應信息。
  • 如果這是一個死鏈或者請求超時,不會返回http狀態碼。
  • 如果這個頁面找不到了,會返回404狀態碼。
  • 其他情況我們都認為這個鏈接是可用的(當然,你也可以再檢查一下500錯誤之類…)。
  • 從該批次移除這個cURL句柄,因為它已經沒有利用價值了,關了它!
  • 很好,現在可以另外加一個URL進來了。再一次地,初始化工作又開始進行…
  • 嗯,該干的都干了。關閉批處理器,生成報告。
  • 回過頭來看給批處理器添加新URL的函數。這個函數每調用一次,靜態變量 $index 就遞增一次,這樣我們才能知道還剩多少URL沒處理。
  • 我把這個腳本在我的博客上跑了一遍(測試需要,有一些錯誤鏈接是故意加上的),結果如下:

    另一些有用的cURL 選項

    HTTP 認證

    如果某個URL請求需要基于 HTTP 的身份驗證,你可以使用下面的代碼:

    1234567891011121314 $url = "http://www.somesite.com/members/";$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);// 發送用戶名和密碼curl_setopt($ch, CURLOPT_USERPWD, "myusername:mypassword");// 你可以允許其重定向curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);// 下面的選項讓 cURL 在重定向后// 也能發送用戶名和密碼curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, 1);$output = curl_exec($ch);curl_close($ch);

    FTP 上傳

    PHP 自帶有 FTP 類庫, 但你也能用 cURL

    1234567891011121314151617 // 開一個文件指針$file = fopen("/path/to/file", "r");// url里包含了大部分所需信息$url = "ftp://username:password@mydomain.com:21/path/to/new/file";$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);// 上傳相關的選項curl_setopt($ch, CURLOPT_UPLOAD, 1);curl_setopt($ch, CURLOPT_INFILE, $fp);curl_setopt($ch, CURLOPT_INFILESIZE, filesize("/path/to/file"));// 是否開啟ASCII模式 (上傳文本文件時有用)curl_setopt($ch, CURLOPT_FTPASCII, 1);$output = curl_exec($ch);curl_close($ch);

    翻墻術

    你可以用代理發起 cURL 請求:

    12345678910 $ch = curl_init();curl_setopt($ch, CURLOPT_URL,'http://www.example.com');curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);// 指定代理地址curl_setopt($ch, CURLOPT_PROXY, '11.11.11.11:8080');// 如果需要的話,提供用戶名和密碼curl_setopt($ch, CURLOPT_PROXYUSERPWD,'user:pass');$output = curl_exec($ch);curl_close ($ch);

    回調函數

    可以在一個 URL 請求過程中,讓 cURL 調用某指定的回調函數。例如,在內容或者響應下載的過程中立刻開始利用數據,而不用等到完全下載完。

    12345678910 $ch = curl_init();curl_setopt($ch, CURLOPT_URL,'http://net.tutsplus.com');curl_setopt($ch, CURLOPT_WRITEFUNCTION,"progress_function");curl_exec($ch);curl_close ($ch);function progress_function($ch,$str) { echo $str; return strlen($str);}

    這個回調函數必須返回字串的長度,不然此功能將無法正常使用。

    在 URL 響應接收的過程中,只要收到一個數據包,這個函數就會被調用。

    小結

    今天我們一起學習了 cURL 庫的強大功能和靈活的擴展性。希望你喜歡。下一次要發起 URL 請求時,考慮下 cURL 吧!

    轉載于:https://www.cnblogs.com/17too/archive/2010/12/22/1913341.html

    總結

    以上是生活随笔為你收集整理的PHP 的 cURL库快速入门文档的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。