如何从URL中检查文件是否存在

64

我需要检查远程服务器上是否存在特定文件。使用 is_file()file_exists() 无法实现。有没有什么快速简单的方法?


3
你可以使用这个函数 getimagesize("url"); 来获取图片的尺寸。 参考链接:http://php.net/manual/en/function.getimagesize.php - InventorX
8个回答

116

你不需要CURL来做这件事... 仅仅为了检查文件是否存在而言,这太过繁琐...

使用PHP的 get_headers

$headers=get_headers($url);

然后检查 $result[0] 是否包含 200 OK(这意味着文件存在)

用于检查 URL 是否有效的函数可能是这样的:

function UR_exists($url){
   $headers=get_headers($url);
   return stripos($headers[0],"200 OK")?true:false;
}

/* You can test a URL like this (sample) */
if(UR_exists("http://www.amazingjokes.com/"))
   echo "This page exists";
else
   echo "This page does not exist";

3
默认情况下,get_headers使用GET请求获取标头 - 因此,而不是使用curl请求的开销(不太确定指的是什么开销)- 会有一个浪费的获取无用body的GET请求 - 相反,可以使用HEAD请求仅接收标头。 - AD7six
3
我假设在内存中设置cURL会导致超负荷,我进行了比较这两种方法的测试,你是正确的:如果你加载了cURL库,使用接受的方法比get_headers快得多。我比较了所有三种提到的方法:cURL是最快的,然后是get_headers,然后是带有附加缺点的getimagesize,即getimagesize只会告诉你图像是否存在。 这是被要求的,所以它仍然是一个有效的答案,但不是非常通用。 - patrick
1
@ad7six 你确定 get_headers 请求的是 body 吗?顺便说一下,你可以通过流上下文覆盖 GET 请求: stream_context_set_default(['http' => ['method' => 'HEAD']]); $headers = get_headers('http://example.com'); - Toby
答案虽然旧,但非常有用。 - james Oduro
使用HEAD请求的示例,如@AD7six所述:https://www.php.net/manual/en/function.get-headers.php - Genki
如果$url是一个无效的URL,那么它将会导致错误。因此,在函数的开头,您可以使用以下代码来确保它有效:if(filter_var($url, FILTER_VALIDATE_URL) === FALSE) return false; - PouriaDiesel

85

你必须使用CURL

function does_url_exists($url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    if ($code == 200) {
        $status = true;
    } else {
        $status = false;
    }
    curl_close($ch);
    return $status;
}

你不需要使用CURL...这样会有太多的开销...请查看我的下面的答案(使用PHP的get_headers来实现!) - patrick
1
和其他的一样,它也是通过检查URL而不是文件本身来确定是否存在。echo is_url_exists('http://stackoverflow.com') ? 'Yes' : 'No'; 输出了 Yes - Mayeenul Islam
直到我添加了CURLOPT_FOLLOWLOCATION,true指令,这才对我起作用。 - Jonathan DS
函数名应该是 does_url_exists ;) - JuliSmz

21

你是不是想说 getimagesize?就像这里:http://uk1.php.net/getimagesize 如果是的话,文档中说它可以引用本地或远程文件。 - Todd
3
getimagesize 的开销太大了。如果你只想知道文件是否存在,可以使用 PHP 的 get_header 函数(查看我的回答)。 - patrick
它并不是很糟糕,但只适用于图像! - ganji
我赞同Patrick的看法,这不是一个解决方案,我希望没有太多人使用这种方法。 - ekerner
1
@herbert。这完全取决于这将被调用多少次以及有多少人将使用它... - patrick
显示剩余2条评论

13

嗨,根据我们在两个不同服务器之间的测试结果如下:

使用curl检查10个.png文件(每个大约5MB)平均需要5.7秒。 使用头文件检查相同内容的时间平均为7.8秒!

因此,在我们的测试中,如果您需要检查更大的文件,则curl要快得多!

我们的curl函数如下:

function remote_file_exists($url){
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    if( $httpCode == 200 ){return true;}
    return false;
}

这是我们的标题检查示例:

function UR_exists($url){
   $headers=get_headers($url);
   return stripos($headers[0],"200 OK")?true:false;
}

2
你可以使用函数 file_get_contents();
if(file_get_contents('https://example.com/example.txt')) {
    //File exists
}

4
这个函数会拖慢你的应用程序并增加 TTFB(首字节加载时间)。因此,永远不要使用这个函数。 - Senior PHP Developer
3
它会获取文件的所有内容...如果您想检查大文件,这将需要太多时间。 - Mahdi Youseftabar
如果URL错误,它也会破坏您的页面。我的意思是,在给定路径上不存在文件。 - Pratik Navapara

1
使用curl发送请求并查看是否返回404状态码。使用HEAD请求方法进行请求,以便仅返回头信息而不包含主体内容。

0
$file = 'https://picsum.photos/200/300';
$file_headers = @get_headers($file);
if($file_headers[0] == 'HTTP/1.1 404 Not Found') {
    $exists = false;
}
else {
    $exists = true;
} 

-1
    $headers = get_headers((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://" . $_SERVER[HTTP_HOST] . '/uploads/' . $MAIN['id'] . '.pdf');
    $fileExist = (stripos($headers[0], "200 OK") ? true : false);
    if ($fileExist) {
    ?>
    <a class="button" href="/uploads/<?= $MAIN['id'] ?>.pdf" download>скачать</a> 
    <? }
    ?>

3
欢迎来到Stack Overflow!请查看[答案]。请记住,当回答问题时,您不仅在回答给原帖作者,还要考虑未来的读者,尤其是回答9年前的问题时。因此,请[编辑]帖子并解释为什么这段代码有效。 - Adriaan

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