我正在嘗試編寫一個工具來檢查代理服務器是否啓動並可供使用。到目前爲止,我已經在下面的類中提出了兩種方法(我刪除了對這個問題是多餘的setter和getters)。檢測代理服務器是否可用的最佳方法是什麼?
第一種方法使用cURL
並嘗試通過代理請求一個頁面,第二個工具使用fsockopen
並試圖打開到代理的連接。
class ProxyList {
/**
* You could set this to localhost, depending on your environment
* @var string The URL that the proxy validation method will use to check proxies agains
* @see ProxyList::validate()
*/
const VALIDATION_URL = "http://m.www.yahoo.com/robots.txt";
const TIMEOUT = 3;
private static $valid = array(); // Checked and valid proxies
private $proxies = array(); // An array of proxies to check
public function validate($useCache=true) {
$mh = curl_multi_init();
$ch = null;
$handles = array();
$delay = count($this->proxies) * 10000;
$running = null;
$proxies = array();
$response = null;
foreach ($this->proxies as $p) {
// Using the cache and the proxy already exists? Skip the rest of this crap
if ($useCache && !empty(self::$valid[$p])) {
$proxies[] = $p;
continue;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_URL, self::VALIDATION_URL);
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, true);
curl_setopt($ch, CURLOPT_PROXY, $p);
curl_setopt($ch, CURLOPT_NOBODY, true); // Also sets request method to HEAD
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, self::TIMEOUT);
curl_multi_add_handle($mh, $ch);
$handles[$p] = $ch;
}
// Execute the multi-handle
do {
curl_multi_exec($mh, $running);
usleep($delay);
} while ($running);
// Get the results of the requests
foreach ($handles as $proxy => $ch) {
$status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
// Great success
if ($status >= 200 && $status < 300) {
self::$valid[$proxy] = true;
$proxies[] = $proxy;
}
else {
self::$valid[$proxy] = false;
}
// Cleanup individual handle
curl_multi_remove_handle($mh, $ch);
}
// Cleanup multiple handle
curl_multi_close($mh);
return $this->proxies = $proxies;
}
public function validate2($useCache=true) {
$proxies = array();
foreach ($this->proxies as $proxy) {
// Using the cache and the proxy already exists? Skip the rest of this crap
if ($useCache && !empty(self::$valid[$proxy])) {
$proxies[] = $proxy;
continue;
}
list($host, $post) = explode(":", $proxy);
if ($conn = @fsockopen($host, $post, $errno, $error, self::TIMEOUT)) {
self::$valid[$proxy] = true;
$proxies[] = $proxy;
fclose($conn);
} else {
self::$valid[$proxy] = false;
}
}
return $this->proxies = $proxies;
}
}
到目前爲止,我更喜歡cURL
方法,因爲它可以讓我像fsockopen
一次檢查代理的大批量並行,這是邪惡的快,而不是一個。
我還沒有做很多與代理工作,所以我很難判斷這些方法是否足以驗證代理是否可用,或者是否有更好的方法使我缺失。
哇,夥計,漂亮的圖片! – 2010-01-30 09:00:54
哈哈,謝謝 – 2010-01-30 09:07:01