PHP URL检查可用性

4
我想检查我的数据库中是否有可用的url。我选择fopen,但是我从我的数据库测试30行,这将花费近20秒的时间。有没有什么方法可以使它更有效率?谢谢。
<?php
$start_t = microtime(true); 
//connect database and select query
while ($row = mysql_fetch_array($result)){
//$url = 'http://www.google.com'; //not test from database, but a google.com, one url will cost 0.49 seconds.
$url = $row['url'];
$res = @fopen($url, "r "); 
if($res){
    echo $row['url'].' yes<br />';
}else{
    echo $row['url']. ' no<br />';
}   
}
$end_t = microtime(true);
$totaltime = $end_t-$start_t;
echo "<br />".$totaltime." s";
?>

如果您想检查DNS是否正常或服务器是否在线,可以使用Rakesh的代码片段。要检查内容的可用性,可以使用curl(请参见karim79的答案)或get_headers(请参见yes123的答案)。 - CSchulz
4个回答

3

尝试使用fsockopen代替fopen,因为它更快。

<?php

$t = microtime(true);

$valid = @fsockopen("www.google.com", 80, $errno, $errstr, 30);

echo (microtime(true)-$t);

if (!$valid) {
   echo "Failure";
} else {
   echo "Success";
}
?>

输出:

0.0013298988342285

@Rakesh,速度很快。但是无论是http://www.google.com还是http://google.com,它们都返回“失败”? - yuli chika
@Yuli 像 @yes123 一样,我犯了个错误。通常情况下,在 fsockopen 调用中应该只使用主机名,而不是 URL。在实际的 HTTP 标头中,您需要提供 URI(不包括主机/端口)。 - Rakesh Sankar
太好了。我也看了php.net/manual/en/function.fsockopen.php,移动了http head。谢谢。 - yuli chika

2

您可以尝试使用带有CURLOPT_NOBODY选项的CURL,该选项使用HTTP HEAD方法并避免下载整个页面:

$ch = curl_init($row['url']);

curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$retcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

// 400 means not found, 200 means found.
curl_close($ch);

从CURLOPT_NOBODY 文档中:

设置为TRUE以从输出中排除正文。然后将请求方法设置为HEAD。将其更改为FALSE不会将其更改为GET。


谢谢。这将节省20%的时间。但不仅仅是返回400200,还要查看302等等。这并不容易。 - yuli chika

1

你不能这样加速。

我猜你正在连接30个不同的URL,20秒已经是一个很好的时间了。

此外,我建议你使用file_get_contents来检索HTML。
或者如果你需要知道头响应,请使用get_headers();

如果你想加快进程,只需生成更多进程。每个进程将获取tot个URL。

补充说明

还有不要忘记伟大的Zend_HTTP_Client();,非常适合这样的任务。


file_get_contentsget_headers 一样,消耗更多资源。尝试获取 http://www.google.com 的内容,需要花费 1+ 秒钟 的时间。 - yuli chika
从没说过它会更便宜。 - dynamic

1
尝试批量URL检查,即以10或20个为单位进行检查。
Curl Multi Exec.

http://semlabs.co.uk/journal/object-oriented-curl-class-with-multi-threading

使用CURL选项进行NOBODY和HEADER ONLY,以便响应更快。

还要记得为curl设置TIMEOUT,否则一个坏的网址可能会花费太多时间。

我在20秒内进行了50个URL检查。

希望能有所帮助。


谢谢推荐新的类,但它将需要10秒钟的时间。 - yuli chika

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接