php 无需下载文件的远程文件大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2602612/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Remote file size without downloading file
提问by dassouki
Is there a way to get the size of a remote file http://my_url/my_file.txtwithout downloading the file?
有没有办法在不下载文件的情况下获取远程文件http://my_url/my_file.txt的大小?
回答by NebuSoft
Found something about this here:
在这里找到了一些东西:
Here's the best way (that I've found) to get the size of a remote file. Note that HEAD requests don't get the actual body of the request, they just retrieve the headers. So making a HEAD request to a resource that is 100MB will take the same amount of time as a HEAD request to a resource that is 1KB.
这是获取远程文件大小的最佳方法(我发现的)。请注意, HEAD 请求不会获取请求的实际正文,它们只是检索标头。因此,向 100MB 的资源发出 HEAD 请求所需的时间与向 1KB 资源发出 HEAD 请求所需的时间相同。
<?php
/**
* Returns the size of a file without downloading it, or -1 if the file
* size could not be determined.
*
* @param $url - The location of the remote file to download. Cannot
* be null or empty.
*
* @return The size of the file referenced by $url, or -1 if the size
* could not be determined.
*/
function curl_get_file_size( $url ) {
// Assume failure.
$result = -1;
$curl = curl_init( $url );
// Issue a HEAD request and follow any redirects.
curl_setopt( $curl, CURLOPT_NOBODY, true );
curl_setopt( $curl, CURLOPT_HEADER, true );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true );
curl_setopt( $curl, CURLOPT_USERAGENT, get_user_agent_string() );
$data = curl_exec( $curl );
curl_close( $curl );
if( $data ) {
$content_length = "unknown";
$status = "unknown";
if( preg_match( "/^HTTP\/1\.[01] (\d\d\d)/", $data, $matches ) ) {
$status = (int)$matches[1];
}
if( preg_match( "/Content-Length: (\d+)/", $data, $matches ) ) {
$content_length = (int)$matches[1];
}
// http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
if( $status == 200 || ($status > 300 && $status <= 308) ) {
$result = $content_length;
}
}
return $result;
}
?>
Usage:
用法:
$file_size = curl_get_file_size( "http://stackoverflow.com/questions/2602612/php-remote-file-size-without-downloading-file" );
回答by macki
Try this code
试试这个代码
function retrieve_remote_file_size($url){
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_NOBODY, TRUE);
$data = curl_exec($ch);
$size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
curl_close($ch);
return $size;
}
回答by eyecatchUp
As mentioned a couple of times, the way to go is to retrieve the information from the response header's Content-Lengthfield.
正如多次提到的,要走的路是从响应头的Content-Length字段中检索信息。
However, you should note that
但是,您应该注意的是
- the server you're probing not necessarily implements the HEAD method(!)
- there's absolutely no need to manually craft a HEAD request (which, again, might not even be supported) using
fopenor alike or even to invoke the curl library, when PHP hasget_headers()(remember: K.I.S.S.)
- 您正在探测的服务器不一定实现 HEAD 方法(!)
- 绝对不需要手动制作 HEAD 请求(同样,可能甚至不支持)使用
fopen或类似甚至调用 curl 库,当 PHP 有时get_headers()(记住:KISS)
Use of get_headers()follows the K.I.S.S. principleandworks even if the server you're probing does not support the HEAD request.
使用get_headers()遵循KISS 原则,即使您正在探测的服务器不支持 HEAD 请求也能正常工作。
So, here's my version (gimmick: returns human-readable formatted size ;-)):
所以,这是我的版本(噱头:返回人类可读的格式化大小;-)):
Gist: https://gist.github.com/eyecatchup/f26300ffd7e50a92bc4d(curl and get_headers version)
get_headers()-Version:
要点:https: //gist.github.com/eyecatchup/f26300ffd7e50a92bc4d(curl 和 get_headers 版本)
get_headers()-版本:
<?php
/**
* Get the file size of any remote resource (using get_headers()),
* either in bytes or - default - as human-readable formatted string.
*
* @author Stephan Schmitz <[email protected]>
* @license MIT <http://eyecatchup.mit-license.org/>
* @url <https://gist.github.com/eyecatchup/f26300ffd7e50a92bc4d>
*
* @param string $url Takes the remote object's URL.
* @param boolean $formatSize Whether to return size in bytes or formatted.
* @param boolean $useHead Whether to use HEAD requests. If false, uses GET.
* @return string Returns human-readable formatted size
* or size in bytes (default: formatted).
*/
function getRemoteFilesize($url, $formatSize = true, $useHead = true)
{
if (false !== $useHead) {
stream_context_set_default(array('http' => array('method' => 'HEAD')));
}
$head = array_change_key_case(get_headers($url, 1));
// content-length of download (in bytes), read from Content-Length: field
$clen = isset($head['content-length']) ? $head['content-length'] : 0;
// cannot retrieve file size, return "-1"
if (!$clen) {
return -1;
}
if (!$formatSize) {
return $clen; // return size in bytes
}
$size = $clen;
switch ($clen) {
case $clen < 1024:
$size = $clen .' B'; break;
case $clen < 1048576:
$size = round($clen / 1024, 2) .' KiB'; break;
case $clen < 1073741824:
$size = round($clen / 1048576, 2) . ' MiB'; break;
case $clen < 1099511627776:
$size = round($clen / 1073741824, 2) . ' GiB'; break;
}
return $size; // return formatted size
}
Usage:
用法:
$url = 'http://download.tuxfamily.org/notepadplus/6.6.9/npp.6.6.9.Installer.exe';
echo getRemoteFilesize($url); // echoes "7.51 MiB"
Additional note:The Content-Length header is optional. Thus, as a general solution it isn't bullet proof!
附加说明:Content-Length 标头是可选的。因此,作为一般解决方案,它不是防弹的!
回答by ceejayoz
Sure. Make a headers-only request and look for the Content-Lengthheader.
当然。发出仅标头请求并查找Content-Length标头。
回答by Sanchit Gupta
Php function get_headers()works for me to check the content-lengthas
Php 函数get_headers()适用于我检查内容长度为
$headers = get_headers('http://example.com/image.jpg', TRUE);
$filesize = $headers['content-length'];
For More Detail : PHP Function get_headers()
更多细节:PHP 函数 get_headers()
回答by Jake
I'm not sure, but couldn't you use the get_headers function for this?
我不确定,但是您不能为此使用 get_headers 函数吗?
$url = 'http://example.com/dir/file.txt';
$headers = get_headers($url, true);
if ( isset($headers['Content-Length']) ) {
$size = 'file size:' . $headers['Content-Length'];
}
else {
$size = 'file size: unknown';
}
echo $size;
回答by Jake
one line best solution :
一行最佳解决方案:
echo array_change_key_case(get_headers("http://.../file.txt",1))['content-length'];
php is too delicius
php 太美味了
function urlsize($url):int{
return array_change_key_case(get_headers($url,1))['content-length'];
}
echo urlsize("http://.../file.txt");
回答by mpyw
The simplest and most efficient implementation:
最简单有效的实现:
function remote_filesize($url, $fallback_to_download = false)
{
static $regex = '/^Content-Length: *+\K\d++$/im';
if (!$fp = @fopen($url, 'rb')) {
return false;
}
if (isset($http_response_header) && preg_match($regex, implode("\n", $http_response_header), $matches)) {
return (int)$matches[0];
}
if (!$fallback_to_download) {
return false;
}
return strlen(stream_get_contents($fp));
}
回答by Rahul Kaushik
Try the below function to get Remote file size
尝试使用以下功能获取远程文件大小
function remote_file_size($url){
$head = "";
$url_p = parse_url($url);
$host = $url_p["host"];
if(!preg_match("/[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*/",$host)){
$ip=gethostbyname($host);
if(!preg_match("/[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*/",$ip)){
return -1;
}
}
if(isset($url_p["port"]))
$port = intval($url_p["port"]);
else
$port = 80;
if(!$port) $port=80;
$path = $url_p["path"];
$fp = fsockopen($host, $port, $errno, $errstr, 20);
if(!$fp) {
return false;
} else {
fputs($fp, "HEAD " . $url . " HTTP/1.1\r\n");
fputs($fp, "HOST: " . $host . "\r\n");
fputs($fp, "User-Agent: http://www.example.com/my_application\r\n");
fputs($fp, "Connection: close\r\n\r\n");
$headers = "";
while (!feof($fp)) {
$headers .= fgets ($fp, 128);
}
}
fclose ($fp);
$return = -2;
$arr_headers = explode("\n", $headers);
foreach($arr_headers as $header) {
$s1 = "HTTP/1.1";
$s2 = "Content-Length: ";
$s3 = "Location: ";
if(substr(strtolower ($header), 0, strlen($s1)) == strtolower($s1)) $status = substr($header, strlen($s1));
if(substr(strtolower ($header), 0, strlen($s2)) == strtolower($s2)) $size = substr($header, strlen($s2));
if(substr(strtolower ($header), 0, strlen($s3)) == strtolower($s3)) $newurl = substr($header, strlen($s3));
}
if(intval($size) > 0) {
$return=intval($size);
} else {
$return=$status;
}
if (intval($status)==302 && strlen($newurl) > 0) {
$return = remote_file_size($newurl);
}
return $return;
}
回答by dkamins
Since this question is already tagged "php" and "curl", I'm assuming you know how to use Curl in PHP.
由于这个问题已经被标记为“php”和“curl”,我假设您知道如何在 PHP 中使用 Curl。
If you set curl_setopt(CURLOPT_NOBODY, TRUE)then you will make a HEAD request and can probably check the "Content-Length" header of the response, which will be only headers.
如果您设置,curl_setopt(CURLOPT_NOBODY, TRUE)那么您将发出 HEAD 请求,并且可能会检查响应的“Content-Length”标头,这将只是标头。

