PHP獲取遠(yuǎn)程網(wǎng)頁(yè)內(nèi)容有多種方式,例如用自帶的file_get_contents、fopen等函數(shù)。
<?php
echo file_get_contents("http://blog.s135.com/abc.php");
?>
但是,在DNS輪詢等負(fù)載均衡中,同一域名,可能對(duì)應(yīng)多臺(tái)服務(wù)器,多個(gè)IP。假設(shè)blog.s135.com被DNS解析到72.249.146.213、72.249.146.214、72.249.146.215三個(gè)IP,用戶每次訪問(wèn)blog.s135.com,系統(tǒng)會(huì)根據(jù)負(fù)載均衡的相應(yīng)算法訪問(wèn)其中的一臺(tái)服務(wù)器。
上周做一個(gè)視頻項(xiàng)目時(shí),就碰到這樣一類需求:需要依次訪問(wèn)每臺(tái)服務(wù)器上的一個(gè)PHP接口程序(假設(shè)為abc.php),查詢這臺(tái)服務(wù)器的傳輸狀態(tài)。
這時(shí)就不能直接用file_get_contents訪問(wèn)http://blog.s135.com/abc.php了,因?yàn)樗赡芤恢敝貜?fù)訪問(wèn)某一臺(tái)服務(wù)器。
而采用依次訪問(wèn)http://72.249.146.213/abc.php、http://72.249.146.214/abc.php、http://72.249.146.215/abc.php的方法,在這三臺(tái)服務(wù)器上的Web Server配有多個(gè)虛擬主機(jī)時(shí),也是不行的。
通過(guò)設(shè)置本地hosts也不行,因?yàn)閔osts不能設(shè)置多個(gè)IP對(duì)應(yīng)同一個(gè)域名。
那就只有通過(guò)PHP和HTTP協(xié)議來(lái)實(shí)現(xiàn):訪問(wèn)abc.php時(shí),在header頭中加上blog.s135.com域名。于是,我寫了下面這個(gè)PHP函數(shù):
<?php
/************************
* 函數(shù)用途:同一域名對(duì)應(yīng)多個(gè)IP時(shí),獲取指定服務(wù)器的遠(yuǎn)程網(wǎng)頁(yè)內(nèi)容
* 創(chuàng)建時(shí)間:2008-12-09
* 創(chuàng)建人:張宴(blog.s135.com)
* 參數(shù)說(shuō)明:
* $ip 服務(wù)器的IP地址
* $host 服務(wù)器的host名稱
* $url 服務(wù)器的URL地址(不含域名)
* 返回值:
* 獲取到的遠(yuǎn)程網(wǎng)頁(yè)內(nèi)容
* false 訪問(wèn)遠(yuǎn)程網(wǎng)頁(yè)失敗
************************/
function HttpVisit($ip, $host, $url)
{
$errstr = '';
$errno = '';
$fp = fsockopen ($ip, 80, $errno, $errstr, 90);
if (!$fp)
{
return false;
}
else
{
$out = "GET {$url} HTTP/1.1\r\n";
$out .= "Host:{$host}\r\n";
$out .= "Connection: close\r\n\r\n";
fputs ($fp, $out);
while($line = fread($fp, 4096)){
$response .= $line;
}
fclose( $fp );
//去掉Header頭信息
$pos = strpos($response, "\r\n\r\n");
$response = substr($response, $pos + 4);
return $response;
}
}
//調(diào)用方法:
$server_info1 = HttpVisit("72.249.146.213", "blog.s135.com", "/abc.php");
$server_info2 = HttpVisit("72.249.146.214", "blog.s135.com", "/abc.php");
$server_info3 = HttpVisit("72.249.146.215", "blog.s135.com", "/abc.php");
?>