最近更新: 2007-05-10

TWPUG問答 - 如何偵測URL資源是否存在

問: 如何偵測網路圖片是否存在?如http://www.example.com/xxx.png。並回傳結果。

如果僅需偵測是否存在,而不要下載整份文件。僅需要透過 HTTP 協定 (RFC2616)HEAD method 即可達成目的。依 HTTP 協定之狀態定義,文件存在時回應代碼 200 ,不存在時回應 404 。我們可以此作為回傳值。

<?php
function checkUrl($url) {
    preg_match('/^(?P<protocol>[a-z]+):\/\/(?P<hostname>[\w\._-]+)(?P<resource>\/.*)/',
        $url, $uriSet);
    $portMap = array('http' => 80, 'https' => 443);
    if (!isset($portMap[$uriSet['protocol']]))
        return false;
    else
        $port = $portMap[$uriSet['protocol']];
    $fh = fsockopen('tcp://'.$uriSet['hostname'], $port, $errno, $errstr, 30);
    if (!$fh) {
        //echo "$errstr ($errno)<br />\n";

        $rc = false;
    } else {
        $cmd = "HEAD {$uriSet['resource']} HTTP/1.1\r\n";
        $cmd .= "Host: www.example.com\r\n";
        $cmd .= "Connection: Close\r\n\r\n";

        fputs($fh, $cmd);
        $response = fgets($fh);
        list($h, $rc) = explode(' ', $response);
        while(!feof($fh))
            fgets($fh);
        fclose($fh);
        
    }
    return $rc;
}

echo checkUrl('http://www.google.com.tw/intl/en_com/images/logo_plain.png'), "\n";

echo checkUrl('http://www.google.com.tw/intl/en_com/images/logo_plain.xxx'), "\n";

?>

fsockopen()開啟TCP網路連線,送出 HTTP HEAD method 請求(第15-17行)。接著讀取伺服器回應,並解析狀態碼(第19-20行)。最後回傳結果。

相關文章
樂多舊網址: http://blog.roodo.com/rocksaying/archives/3215473.html

樂多舊回應
luvkarl@gmail.com(Ka-Yue) (#comment-10349019)
Thu, 10 May 2007 10:49:33 +0800
JavaScript have onerror event too.
未留名 (#comment-10353999)
Thu, 10 May 2007 17:07:32 +0800
Good question. 如果改由 JavaScript 進行偵測動作,就可以把偵測動作分派給 client 去做。這是一種 Ajax 的應用, See 如何偵測URL資源是否存在, Ajax way