cURL是一個(gè)利用URL語法規(guī)定來傳輸文件和數(shù)據(jù)的工具拦焚,支持很多協(xié)議和選項(xiàng)怜奖,如HTTP浑测、FTP、TELNET等歪玲,能提供URL請求相關(guān)的各種細(xì)節(jié)信息迁央。最爽的是,PHP也支持cURL
庫滥崩。
本文將介紹 cURL 的一些高級特性岖圈,以及在php中如何運(yùn)用它。
是的钙皮,我們可以通過其他辦法獲取網(wǎng)頁內(nèi)容蜂科。大多數(shù)時(shí)候,我因?yàn)橄胪祽卸烫酰贾苯佑煤唵蔚腜HP的file_get_contents()函數(shù):
$content = file_get_contents("http://www.awaimai.com");$lines = file("http://www.awaimai.com");readfile(http://www.awaimai.com);
不過导匣,這種做法缺乏靈活性和有效的錯(cuò)誤處理。而且慌烧,你也不能用它完成一些高難度任務(wù)逐抑,比如處理:coockies、驗(yàn)證屹蚊、表單提交、文件上傳等等进每。
首先汹粤,我們得先要確定 PHP 是否開啟了這個(gè)庫,你可以通過使用phpinfo()函數(shù)來得到這一信息田晚。如果在網(wǎng)頁上看到下面的輸出嘱兼,那么表示cURL 庫已開啟。
如果curl沒有開啟贤徒,那么就需要開啟這個(gè)庫芹壕。如果是在Windows平臺下汇四,那么非常簡單,你需要改一改php.ini文件的設(shè)置踢涌,找到php_curl.dll通孽,并取消前面的分號注釋就行了。如下所示:
# 取消下面的注釋extension=php_curl.dll
如果是Linux服務(wù)器睁壁,需要重新編譯 PHP背苦,編譯時(shí)在configure命令上加上--with-curl參數(shù)。
在學(xué)習(xí)更為復(fù)雜的功能之前潘明,先來看一下在 PHP 中建立 cURL 請求的基本步驟:
初始化
設(shè)置選項(xiàng)
執(zhí)行并獲取結(jié)果
釋放cURL句柄
實(shí)現(xiàn)代碼如下:
// 1. 初始化$ch = curl_init();// 2. 設(shè)置選項(xiàng)curl_setopt($ch, CURLOPT_URL,"http://www.awaimai.com");// 設(shè)置要抓取的頁面地址curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);// 抓取結(jié)果直接返回(如果為0行剂,則直接輸出內(nèi)容到頁面)curl_setopt($ch, CURLOPT_HEADER,0);// 不需要頁面的HTTP頭// 3. 執(zhí)行并獲取HTML文檔內(nèi)容,可用echo輸出內(nèi)容$output = curl_exec($ch);// 4. 釋放curl句柄curl_close($ch);
第二步(也就是curl_setopt())最為重要钳降,一切玄妙均在此厚宰。有一長串cURL參數(shù)可供設(shè)置,它們能指定URL請求的各個(gè)細(xì)節(jié)遂填。要一次性全部看完并理解可能比較困難铲觉,所以今天我們只試一下那些更常用也更有用的選項(xiàng)。
你可以在cur_exec()后加一段檢查錯(cuò)誤的語句(雖然這并不是必需的):
$output = curl_exec($ch);if($output ===FALSE) {echo"cURL Error: ". curl_error($ch);}
請注意城菊,比較的時(shí)候我們用的是===
FALSE备燃,而非==FALSE。因?yàn)槲覀兊脜^(qū)分空輸出和布爾值FALSE凌唬,后者才是真正的錯(cuò)誤并齐。
利用curl_getinfo()能夠在cURL執(zhí)行后獲取請求的有關(guān)信息,當(dāng)然客税,這也是一個(gè)可選的設(shè)置項(xiàng)况褪,:
curl_exec($ch);$info= curl_getinfo($ch);echo'獲取'.$info['url'] .'耗時(shí)'.$info['total_time'] .'秒';
返回的數(shù)組中包括了以下信息:
url//資源網(wǎng)絡(luò)地址
content_type//內(nèi)容編碼
http_code//HTTP狀態(tài)碼
header_size//header的大小
request_size//請求的大小
filetime//文件創(chuàng)建時(shí)間
ssl_verify_result//SSL驗(yàn)證結(jié)果
redirect_count//跳轉(zhuǎn)技術(shù)
total_time//總耗時(shí)
namelookup_time//DNS查詢耗時(shí)
connect_time//等待連接耗時(shí)
pretransfer_time//傳輸前準(zhǔn)備耗時(shí)
size_upload//上傳數(shù)據(jù)的大小
size_download//下載數(shù)據(jù)的大小
speed_download//下載速度
speed_upload//上傳速度
download_content_length//下載內(nèi)容的長度
upload_content_length//上傳內(nèi)容的長度
starttransfer_time//開始傳輸?shù)臅r(shí)間
redirect_time//重定向耗時(shí)
在第一個(gè)例子中,我們將提供一段用于偵測服務(wù)器是否有基于瀏覽器的重定向的代碼更耻。例如测垛,有些網(wǎng)站會根據(jù)是否是手機(jī)瀏覽器甚至用戶來自哪個(gè)國家來重定向網(wǎng)頁。
我們利用CURLOPT_HTTPHEADER選項(xiàng)來設(shè)定發(fā)送出的HTTP請求頭信息(httpheaders)秧均,包括useragent信息和默認(rèn)語言食侮。然后看看這些特定網(wǎng)站是否會把我們重定向到不同的URL。
// 測試用的URL$urls =array("http://www.bbc.com","http://www.baidu.com","http://www.ubuntu.com");// 測試用的瀏覽器信息$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($urlsas$url) {echo"URL: $urln
";foreach($browsersas$test_name => $browser) {? ? ? ? ? ? ? ? $ch = curl_init();// 設(shè)置 urlcurl_setopt($ch, CURLOPT_URL, $url);// 設(shè)置瀏覽器的特定headercurl_setopt($ch, CURLOPT_HTTPHEADER,array("User-Agent: {$browser['user_agent']}","Accept-Language: {$browser['language']}"));// 頁面內(nèi)容我們并不需要curl_setopt($ch, CURLOPT_NOBODY,1);// 只需返回HTTP headercurl_setopt($ch, CURLOPT_HEADER,1);// 返回結(jié)果目胡,而不是輸出它c(diǎn)url_setopt($ch, CURLOPT_RETURNTRANSFER,1);? ? ? ? ? ? ? ? $output = curl_exec($ch);? ? ? ? ? ? ? ? curl_close($ch);// 有重定向的HTTP頭信息嗎?if(preg_match("!Location: (.*)!", $output, $matches)) {echo"$test_name: redirects to $matches[1]n
";? ? ? ? ? ? ? ? }else{echo"$test_name: no redirectionn
";? ? ? ? ? ? ? ? }? ? ? ? }echo"nn
";}
首先锯七,我們建立一組需要測試的URL,接著指定一組需要測試的瀏覽器信息誉己。最后通過循環(huán)測試各種URL和瀏覽器匹配可能產(chǎn)生的情況眉尸。
因?yàn)槲覀冎付薈URLOPT_NOBODY選項(xiàng),所以返回的輸出內(nèi)容則只包括HTTP頭信息(被存放于$output中)。利用一個(gè)簡單的正則噪猾,我們檢查這個(gè)頭信息中是否包含了Location:字樣霉祸。
運(yùn)行這段代碼應(yīng)該會返回如下結(jié)果:
URL: http://www.bbc.comstandard: no redirectioniphone: no redirectionfrench: no redirectionURL: http://www.baidu.comstandard: redirects to https://www.baidu.com/iphone: no redirectionfrench: redirects to https://www.baidu.com/URL: http://www.ubuntu.comstandard: redirects to http://www.ubuntu.com/index_kyliniphone: redirects to http://www.ubuntu.com/index_kylinfrench: redirects to http://www.ubuntu.com/index_kylin
當(dāng)發(fā)起 GET 請求時(shí),數(shù)據(jù)可以通過“查詢字串”(Query String)傳遞給一個(gè)URL袱蜡。例如丝蹭,在必應(yīng)(鑒于Google
需要翻墻,用 Bing 代替)中搜索時(shí)戒劫,搜索關(guān)鍵即為 URL 的查詢字串的一部分:
http://www.bing.com?q=awaimai.com
這種情況下你可能并不需要 cURL 來模擬半夷。把這個(gè)URL丟給file_get_contents()就能得到相同結(jié)果。
不過有一些HTML表單是用 POST 方法提交的迅细。這種表單提交時(shí)巫橄,數(shù)據(jù)是通過 HTTP請求體(requestbody)發(fā)送,而不是查詢字串茵典。例如湘换,當(dāng)使用ThinkPHP網(wǎng)站的搜索功能時(shí),無論輸入什么關(guān)鍵字统阿,總是被 POST到如下頁面:
http://www.thinkphp.cn/Search/
你可以用 PHP 腳本來模擬這種 URL 請求彩倚。首先,新建一個(gè)可以接受并顯示POST數(shù)據(jù)的文件扶平,我們給它命名為post_output.php帆离,腳本內(nèi)容為:
print_r($_POST);
接下來,寫一段 PHP 腳本來執(zhí)行 cURL 請求:
$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數(shù)據(jù)哦结澄!curl_setopt($ch, CURLOPT_POST,1);// 加上POST變量curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);$output = curl_exec($ch);curl_close($ch);echo$output;
執(zhí)行代碼后應(yīng)該會得到以下結(jié)果:
Array(? ? [foo] => bar? ? [query] => Nettuts? ? [action] => Submit)
這段腳本發(fā)送一個(gè) POST 請求給post_output.php哥谷,這個(gè)頁面$_POST變量并返回,我們利用cURL捕捉了這個(gè)輸出麻献。
上傳文件和前面的POST十分相似们妥。因?yàn)樗械奈募蟼鞅韱味际峭ㄟ^POST方法提交的。首先新建一個(gè)接收文件的頁面勉吻,命名為upload_output.php监婶,頁面內(nèi)容:
print_r($_FILES);
以下是真正執(zhí)行文件上傳任務(wù)的腳本,命名為upload.php齿桃,內(nèi)容:
$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;
如果你需要上傳一個(gè)文件惑惶,只需要把文件路徑賦給upload,作為POST變量傳過去短纵,不過記得在前面加上@符號集惋。執(zhí)行這段腳本應(yīng)該會得到類似如下輸出:
Array(? ? [upload] =>Array([name] => test.zip[type] => application/octet-stream[tmp_name] => C:Windowsphp1BB4.tmp[error] =>0[size] =>487235))
cURL批處理(multicURL)
cURL還有一個(gè)高級特性:批處理句柄(handle)。這一特性允許你同時(shí)或異步地打開多個(gè)URL連接踩娘。下面是來自來自php.net的示例代碼:
// 創(chuàng)建兩個(gè)cURL資源$ch1 = curl_init();$ch2 = curl_init();// 指定URL和適當(dāng)?shù)膮?shù)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);// 創(chuàng)建cURL批處理句柄$mh = curl_multi_init();// 加上前面兩個(gè)資源句柄curl_multi_add_handle($mh, $ch1);curl_multi_add_handle($mh, $ch2);// 預(yù)定義一個(gè)狀態(tài)變量$active =null;// 執(zhí)行批處理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);? ? }}// 關(guān)閉各個(gè)句柄curl_multi_remove_handle($mh, $ch1);curl_multi_remove_handle($mh, $ch2);curl_multi_close($mh);
這里要做的就是打開多個(gè) cURL 句柄并指派給一個(gè)批處理句柄。然后你就只需在一個(gè)while循環(huán)里等它執(zhí)行完畢。
這個(gè)示例中有兩個(gè)主要循環(huán)养渴。第一個(gè)do-while循環(huán)重復(fù)調(diào)用curl_multi_exec()雷绢。這個(gè)函數(shù)是無隔斷(non-blocking)的,但會盡可能少地執(zhí)行理卑。它返回一個(gè)狀態(tài)值翘紊,只要這個(gè)值等于常量CURLM_CALL_MULTI_PERFORM,就代表還有一些刻不容緩的工作要做(例如藐唠,把對應(yīng)URL的http頭信息發(fā)送出去)帆疟。也就是說,我們需要不斷調(diào)用該函數(shù)宇立,直到返回值發(fā)生改變踪宠。
而接下來的while循環(huán),只在$active變量為true時(shí)繼續(xù)妈嘹。這一變量之前作為第二個(gè)參數(shù)傳給了curl_multi_exec()柳琢,代表只要批處理句柄中是否還有活動連接。接著润脸,我們調(diào)用curl_multi_select()柬脸,在活動連接(例如接受服務(wù)器響應(yīng))出現(xiàn)之前,它都是被“屏蔽”的毙驯。這個(gè)函數(shù)成功執(zhí)行后倒堕,我們又會進(jìn)入另一個(gè)do-while循環(huán),繼續(xù)下一條URL爆价。
還是來看一看怎么把這一功能用到實(shí)處吧:
想象一下你有一個(gè)文章數(shù)目龐大的博客垦巴,這些文章中包含了大量外部網(wǎng)站鏈接。一段時(shí)間之后允坚,因?yàn)檫@樣那樣的原因魂那,這些鏈接中相當(dāng)數(shù)量都失效了。要么是被和諧了稠项,要么是整個(gè)站點(diǎn)都被功夫網(wǎng)了…
我們下面建立一個(gè)腳本涯雅,分析所有這些鏈接,找出打不開或者404的網(wǎng)站/網(wǎng)頁展运,并生成一個(gè)報(bào)告活逆。
請注意,以下并不是一個(gè)真正可用的WordPress插件拗胜,僅僅是一段獨(dú)立功能的腳本而已蔗候,僅供演示,謝謝埂软。
好锈遥,開始吧。首先,從數(shù)據(jù)庫中讀取所有這些鏈接:
// 配置 MySQL 數(shù)據(jù)庫$db_host ='localhost';$db_user ='root';$db_pass ='';$db_name ='wordpress';$excluded_domains =array('localhost','www.mydomain.com');$max_connections =10;// 初始化一些變量$url_list =array();$working_urls =array();$dead_urls =array();$not_found_urls =array();$active =null;// 連到 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());}// 找出所有含有鏈接的文章$sql ="SELECT post_content FROM wp_posts
WHERE post_content LIKE '%href=%'
AND post_status = 'publish'
AND post_type = 'post'";$res = mysql_query($sql)ordie(mysql_error());while($d = mysql_fetch_assoc($res)) {// 用正則匹配鏈接if(preg_match_all("!href="(.*?)"!", $d['post_content'], $matches)) {foreach($matches[1]as$url) {// 剔除排除的域名$tmp = parse_url($url);if(in_array($tmp['host'], $excluded_domains)) {continue;? ? ? ? ? ? ? ? ? ? ? ? }// 保存 URL$url_list []= $url;? ? ? ? ? ? ? ? }? ? ? ? }}// 移除重復(fù)鏈接$url_list = array_values(array_unique($url_list));if(!$url_list) {die('No URL to check');}
我們首先配置好數(shù)據(jù)庫所灸,一系列要排除的域名($excluded_domains)丽惶,以及最大同時(shí)連接數(shù)量($max_connections)。然后爬立,連接數(shù)據(jù)庫钾唬,獲取文章和包含的鏈接,把它們收集到一個(gè)數(shù)組中($url_list)侠驯。
下面的代碼有點(diǎn)復(fù)雜了抡秆,因此我將一小步一小步地詳細(xì)解釋:
// 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. 主循環(huán)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)) {// 意味著該連接正常結(jié)束// 8. 從curl句柄獲取信息$chinfo = curl_getinfo($mhinfo['handle']);// 9. 死鏈么吟策?if(!$chinfo['http_code']) {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? $dead_urls []= $chinfo['url'];// 10. 404了?}elseif($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";echoimplode("n",$dead_urls) ."nn";echo"==404 URLs==n";echoimplode("n",$not_found_urls) ."nn";echo"==Working URLs==n";echoimplode("n",$working_urls);// 15. 向批處理器添加urlfunctionadd_url_to_multi_handle($mh, $url_list){static$index =0;// 如果還剩url沒用if($url_list[$index]) {// 新建curl句柄$ch = curl_init();// 配置urlcurl_setopt($ch, CURLOPT_URL, $url_list[$index]);// 不想輸出返回的內(nèi)容curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);// 重定向到哪兒我們就去哪兒curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);// 不需要內(nèi)容體,能夠節(jié)約帶寬和時(shí)間curl_setopt($ch, CURLOPT_NOBODY,1);// 加入到批處理器中curl_multi_add_handle($mh, $ch);// 撥一下計(jì)數(shù)器踊挠,下次調(diào)用該函數(shù)就能添加下一個(gè)url了$index++;returntrue;? ? ? ? }else{// 沒有新的URL需要處理了returnfalse;? ? ? ? }}
下面解釋一下以上代碼乍桂。列表的序號對應(yīng)著代碼注釋中的順序數(shù)字。
新建一個(gè)批處理句柄效床。
稍后我們將創(chuàng)建一個(gè)把URL加入批處理器的函數(shù)add_url_to_multi_handle()睹酌。每當(dāng)這個(gè)函數(shù)被調(diào)用,就有一個(gè)新url被加入批處理器剩檀。一開始憋沿,我們給批處理器添加了10個(gè)URL(這一數(shù)字由$max_connections所決定)。
運(yùn)行curl_multi_exec()進(jìn)行初始化工作是必須的沪猴,只要它返回CURLM_CALL_MULTI_PERFORM就還有事情要做辐啄。這么做主要是為了創(chuàng)建連接,它不會等待完整的URL響應(yīng)运嗜。
只要批處理中還有活動連接主循環(huán)就會一直持續(xù)壶辜。
curl_multi_select()會一直等待,直到某個(gè)URL查詢產(chǎn)生活動連接担租。
cURL的活兒又來了砸民,主要是獲取響應(yīng)數(shù)據(jù)。
檢查各種信息奋救。當(dāng)一個(gè)URL請求完成時(shí)岭参,會返回一個(gè)數(shù)組。
在返回的數(shù)組中有一個(gè) cURL 句柄尝艘。我們利用其獲取單個(gè) cURL 請求的相應(yīng)信息演侯。
如果這是一個(gè)死鏈或者請求超時(shí),不會返回http狀態(tài)碼背亥。
如果這個(gè)頁面找不到了秒际,會返回404狀態(tài)碼悬赏。
其他情況我們都認(rèn)為這個(gè)鏈接是可用的(當(dāng)然,你也可以再檢查一下500錯(cuò)誤之類…)程癌。
從該批次移除這個(gè) cURL 句柄舷嗡,因?yàn)樗呀?jīng)沒有利用價(jià)值了,關(guān)了它嵌莉!
很好,現(xiàn)在可以另外加一個(gè)URL進(jìn)來了捻脖。再一次地锐峭,初始化工作又開始進(jìn)行…
嗯,該干的都干了可婶。關(guān)閉批處理器沿癞,生成報(bào)告。
回過頭來看給批處理器添加新 URL的函數(shù)矛渴。這個(gè)函數(shù)每調(diào)用一次椎扬,靜態(tài)變量$index就遞增一次,這樣我們才能知道還剩多少URL沒處理具温。
我把這個(gè)腳本在我的博客上跑了一遍(測試需要蚕涤,有一些錯(cuò)誤鏈接是故意加上的),共檢查約40個(gè)URL铣猩,只耗費(fèi)兩秒不到揖铜。當(dāng)需要檢查更加大量的URL時(shí),其省心省力的效果可想而知达皿!如果你同時(shí)打開10個(gè)連接天吓,還能再快上10倍!另外峦椰,你還可以利用cURL批處理的無隔斷特性龄寞,來處理大量URL請求,而不會阻塞你的Web腳本汤功。
如果某個(gè)URL請求需要基于 HTTP 的身份驗(yàn)證物邑,你可以使用下面的代碼:
$url ="http://www.somesite.com/members/";$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);// 發(fā)送用戶名和密碼curl_setopt($ch, CURLOPT_USERPWD,"myusername:mypassword");// 你可以允許其重定向curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);// 下面的選項(xiàng)讓 cURL 在重定向后// 也能發(fā)送用戶名和密碼curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH,1);$output = curl_exec($ch);curl_close($ch);
PHP 自帶有FTP 類庫,但你也能用 cURL:
// 打開一個(gè)文件指針$file = fopen("/path/to/file","r");$size = filesize("/path/to/file");// 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);// 上傳相關(guān)的選項(xiàng)curl_setopt($ch, CURLOPT_UPLOAD,1);curl_setopt($ch, CURLOPT_INFILE, $file);curl_setopt($ch, CURLOPT_INFILESIZE, $size);// 是否開啟ASCII模式 (上傳文本文件時(shí)有用)curl_setopt($ch, CURLOPT_FTPASCII,1);$output = curl_exec($ch);curl_close($ch);
你可以用代理發(fā)起 cURL 請求:
$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,'username:password');$output = curl_exec($ch);curl_close ($ch);
可以在一個(gè)URL請求過程中拂封,讓
cURL調(diào)用某指定的回調(diào)函數(shù)。例如鹦蠕,在內(nèi)容或者響應(yīng)下載的過程中冒签,立刻開始利用數(shù)據(jù),而不用等到完全下載完钟病。
$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);functionprogress_function($ch, $str){echo$str;returnstrlen($str);}
這個(gè)回調(diào)函數(shù)必須返回字串的長度萧恕,不然此功能將無法正常使用刚梭。在URL響應(yīng)接收的過程中,只要收到一個(gè)數(shù)據(jù)包票唆,這個(gè)函數(shù)就會被調(diào)用朴读。
更多信息請關(guān)注千鋒PHP,千鋒論壇