我拼凑了一个检查链接的课程。它有效,但速度很慢:
该类基本上解析HTML字符串并返回href和src属性的所有无效链接。以下是我如何使用它:
$class = new Validurl(array('html' => file_get_contents('http://google.com')));
$invalid_links = $class->check_links();
print_r($invalid_links);
HTML有很多链接,它变得非常慢,我知道它必须通过每个链接并遵循它,但也许有经验的人可以给我一些关于如何加快它的指示。
以下是代码:
class Validurl{
private $html = '';
public function __construct($params){
$this->html = $params['html'];
}
public function check_links(){
$invalid_links = array();
$all_links = $this->get_links();
foreach($all_links as $link){
if(!$this->is_valid_url($link['url'])){
array_push($invalid_links, $link);
}
}
return $invalid_links;
}
private function get_links() {
$xml = new DOMDocument();
@$xml->loadHTML($this->html);
$links = array();
foreach($xml->getElementsByTagName('a') as $link) {
$links[] = array('type' => 'url', 'url' => $link->getAttribute('href'), 'text' => $link->nodeValue);
}
foreach($xml->getElementsByTagName('img') as $link) {
$links[] = array('type' => 'img', 'url' => $link->getAttribute('src'));
}
return $links;
}
private function is_valid_url($url){
if ((strpos($url, "http")) === false) $url = "http://" . $url;
if (is_array(@get_headers($url))){
return true;
}else{
return false;
}
}
}
答案 0 :(得分:2)
首先,当你可以直接迭代getElementsByTagName()的结果时,我不会将链接和图像推送到数组中,然后遍历数组。你必须为< a>做两次。和< img>标签,但是如果你将检查逻辑分成一个函数,你只需要为每一轮调用它。
其次,get_headers()很慢,基于PHP manual page的评论。您应该以某种方式使用cUrl(在comment on the same page中找到):
function get_headers_curl($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
$r = curl_exec($ch);
$r = split("\n", $r);
return $r;
}
更新:,是的,某种缓存也可以提供帮助,例如:一个SQLITE数据库,其中包含一个用于链接和结果的表,您可以像每天一样清除该数据库。
答案 1 :(得分:0)
您可以缓存结果(在DB中,例如:键值存储),以便您的验证器假定如果链接有效,它将在24小时或一周或类似的情况下有效。