php請求遠程url內容有兩個方法fopen/file_get_contents和curl。
1,fopen/file_get_contents與curl的差異
(1)fopen /file_get_contents 每次請求都會重新做DNS查詢,並不對DNS信息進行緩存。但是CURL會自動對DNS信息進行緩存。對同一域名下的網頁或者圖片的請求只需要一次DNS查詢。這大大減少了DNS查詢的次數。所以CURL的性能比fopen /file_get_contents 好很多。
(2)fopen /file_get_contents在請求HTTP時,使用的是http_fopen_wrapper,不會keeplive。而curl卻可以。這樣在多次請求多個鏈接時,curl效率會好一些。
(3)curl可以模擬多種請求,例如:POST數據,表單提交等,用戶可以按照自己的需求來定制請求。而fopen / file_get_contents只能使用get方式獲取數據。
2,如果遠程服務器關閉,file_get_contents處理方法,可以參考這篇文章,http://www.cnblogs.com/scofi/articles/3607529.html
公司里有經常有這樣的業務,需要調用第三方公司提供的HTTP接口,在把接口提供的信息顯示到網頁上,代碼是這樣寫的: file_get_contents("http://example.com/") 。
|
1
2
3
4
5
6
7
8
9
|
$opts
=
array
(
'http'
=>
array
(
'method'
=>
"GET"
,
'timeout'
=>10,
)
);
$context
= stream_context_create(
$opts
);
$html
=
file_get_contents
(
'http://www.example.com'
, false,
$context
);
echo
$html
;
|
代碼中的timeout就是file_get_contents讀取url的超時時間。
上篇說到我們說到設置file_get_contents超時時間用到了 stream_context_create方法,那么這個方法到底是什么呢?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<?php
$data
=
array
(
"name"
=>
'test_name'
,
"content"
=>
'test_con'
);
$data
= http_build_query(
$data
);
$opts
=
array
(
'http'
=>
array
(
'method'
=>
"POST"
,
'header'
=>
"Content-type: application/x-www-form-urlencoded\r\n"
.
"Content-length:"
.
strlen
(
$data
).
"\r\n"
.
"Cookie: foo=bar\r\n"
.
"\r\n"
,
'content'
=>
$data
,
)
);
$cxContext
= stream_context_create(
$opts
);
$sFile
=
file_get_contents
(
"http://127.0.0.1/reponse.php"
, false,
$cxContext
);
echo
$sFile
;
?>
|
reponse.php被請求的頁面:
|
1
2
3
4
|
<?php
var_dump(
$_POST
);
var_dump(
$_COOKIE
);
?>
|
運行之后的結果為:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<?php
$url
=
'http://www.example.com'
;
//初始化一個 cURL 對象
$ch
= curl_init();
//設置你需要抓取的URL
curl_setopt(
$ch
, CURLOPT_URL,
$url
);
// 設置cURL 參數,要求結果保存到字符串中還是輸出到屏幕上。
curl_setopt(
$ch
, CURLOPT_RETURNTRANSFER, 1);
//是否獲得跳轉后的頁面
curl_setopt(
$ch
, CURLOPT_FOLLOWLOCATION, 1);
$data
= curl_exec(
$ch
);
curl_close(
$ch
);
echo
$data
;
?>
|
(2)使用curl。post獲取數據
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<?php
function
curl_post(
$url
,
$arr_data
){
$post_data
= http_build_query(
$url_data
);
$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_POSTFLELDS,
$post_data
);
$data
= curl_exec(
$ch
);
curl_close(
$ch
);
echo
$data
;
}
$arr_post
=
array
(
'name'
=>
'test_name'
,
'age'
=> 1
);
curl_post(
"http://www.explame.com/"
,
$arr_post
);
?>
|
(3)使用代理抓取頁面,什么要使用代理進行抓取呢?以google為例吧,如果去抓google的數據,短時間內抓的很頻繁的話,你就抓取不到了。google對你的ip地址做限制這個時候,你可以換代理重新抓。
|
1
2
3
4
5
6
7
8
9
10
11
12
|
<?php
$ch
= curl_init();
curl_setopt(
$ch
, CURLOPT_URL,
"http://google.com"
);
curl_setopt(
$ch
, CURLOPT_HEADER, false);
curl_setopt(
$ch
, CURLOPT_RETURNTRANSFER, 1);
//是否通過http代理來傳輸
curl_setopt(
$ch
, CURLOPT_HTTPPROXYTUNNEL, TRUE);
curl_setopt(
$ch
, CURLOPT_PROXY, 125.21.23.6:8080);
//url_setopt($ch, CURLOPT_PROXYUSERPWD, 'user:password');如果要密碼的話,加上這個
$result
=curl_exec(
$ch
);
curl_close(
$ch
);
?>
|
(4)繼續保持本站session調用,在實現用戶同步登錄的情況下需要共享session,如果要繼續保持本站的session,那么要把sessionid放到http請求中。
|
1
2
3
4
5
6
7
8
9
10
11
|
<?php
$session_str
= session_name().
'='
.session_id().
'; path=/; domain=.explame.com'
;
session_write_close();
//將數據寫入文件並且結束session
$ch
= curl_init();
curl_setopt(
$ch
, CURLOPT_URL,
$url
);
curl_setopt(
$ch
, CURLOPT_HEADER, false);
curl_setopt(
$ch
, CURLOPT_RETURNTRANSFER, 1);
curl_setopt(
$ch
, CURLOPT_COOKIE,
$session_str
);
$ret
= curl_exec(
$ch
);
curl_close(
$ch
);
?>
|
