有沒有辦法在不下載文件的情況下獲取遠程文件http://my_url/my_file.txt的大小?PHP:無需下載文件即可獲得遠程文件大小
回答
找到東西這個here:
這裏得到一個遠程 文件大小的最佳方式(我發現)。請注意,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;
}
?>
用法:
$file_size = curl_get_file_size("http://stackoverflow.com/questions/2602612/php-remote-file-size-without-downloading-file");
當然。製作僅限標題的請求並查找Content-Length
標題。
因爲這個問題已經被標記 「PHP」 和 「捲曲」,我假設你知道如何在PHP中使用捲曲。
如果你設置了curl_setopt(CURLOPT_NOBODY, TRUE)
那麼你將發出一個HEAD請求,並且可能會檢查響應的「Content-Length」標題,這將只是標題。
試試這個代碼
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;
}
試試下面的函數獲取遠程文件大小
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;
}
這是唯一一個在Ubuntu Linux apache服務器上爲我工作的人。我在函數開始時不得不初始化$ size和$ status,否則按原樣工作。 – 2013-11-12 12:50:25
大多數答案在這裏使用任何捲曲或正在基礎上讀頭。但在某些情況下,您可以使用更簡單的解決方案。考慮關於filesize()
's docs on PHP.net的說明。你會發現有一個提示:「從PHP 5.0.0開始,這個函數也可以用於一些URL包裝器,參考Supported Protocols and Wrappers來確定哪些包裝器支持stat()系列的功能」。因此,如果您的服務器和PHP解析器配置正確,那麼您可以簡單地使用filesize()
函數,用完整的URL填充它,指向一個遠程文件,您希望獲得的大小,然後讓PHP完成所有的魔術。
最簡單和最有效的FPGA實現:
function remote_filesize($url) {
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];
}
return strlen(stream_get_contents($fp));
}
像魔術一樣工作。謝謝。 – rottenoats 2016-02-26 14:23:57
我不知道,但不能使用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;
在這個例子中,$ url的目標服務器可能利用get_headers來保持連接處於打開狀態,直到PHP進程超時(通過非常緩慢地返回頭部,而不足以讓連接失效)。由於整個PHP進程可能受FPM限制,因此當多個「用戶」同時訪問您的get_headers腳本時,這可能允許一種緩慢的洛里斯攻擊。 – 2016-10-12 16:14:00
如前所述幾次,要走的路是檢索與響應報頭的Content-Length
場信息。
但是,你要注意,
- 你探測服務器不一定實現了HEAD方法(!)
- 但絕對不需要手工手藝使用
fopen
或相似,甚至調用curl庫HEAD請求(再次,甚至可能不支持),PHP有get_headers()
時(記住:K.I.S.S.)
使用get_headers()
跟在K.I.S.S. principle和之後即使您正在探測的服務器不支持HEAD請求也能正常工作。
所以,這裏是我的版本(噱頭:返回人類可讀格式的大小;-)):
要點:https://gist.github.com/eyecatchup/f26300ffd7e50a92bc4d(捲曲和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
}
用法:
$url = 'http://download.tuxfamily.org/notepadplus/6.6.9/npp.6.6.9.Installer.exe';
echo getRemoteFilesize($url); // echoes "7.51 MiB"
附加說明: Content-Length標頭是可選的。因此,作爲一般解決方案它不是防彈!
這應該是被接受的答案。誠然,Content-Length是可選的,但它是獲得文件大小而不下載它的唯一方法 - 而'get_headers'是獲得'content-length'的最好方法。 – 2017-08-31 22:17:59
這是另一種方法,它可以與不支持HEAD
請求的服務器一起使用。
它使用cURL使用HTTP範圍標頭請求文件的第一個字節。
如果服務器支持範圍請求(大多數媒體服務器將會),那麼它將接收到具有資源大小的響應。
如果服務器沒有響應一個字節範圍,它會查找一個內容長度標頭來確定長度。
如果在範圍或內容長度標題中找到大小,傳輸將中止。如果未找到大小並且函數開始讀取響應主體,則傳輸將中止。
如果HEAD
請求導致405
方法不支持的響應,這可能是一種補充方法。
/**
* Try to determine the size of a remote file by making an HTTP request for
* a byte range, or look for the content-length header in the response.
* The function aborts the transfer as soon as the size is found, or if no
* length headers are returned, it aborts the transfer.
*
* @return int|null null if size could not be determined, or length of content
*/
function getRemoteFileSize($url)
{
$ch = curl_init($url);
$headers = array(
'Range: bytes=0-1',
'Connection: close',
);
$in_headers = true;
$size = null;
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2450.0 Iron/46.0.2450.0');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 0); // set to 1 to debug
curl_setopt($ch, CURLOPT_STDERR, fopen('php://output', 'r'));
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($curl, $line) use (&$in_headers, &$size) {
$length = strlen($line);
if (trim($line) == '') {
$in_headers = false;
}
list($header, $content) = explode(':', $line, 2);
$header = strtolower(trim($header));
if ($header == 'content-range') {
// found a content-range header
list($rng, $s) = explode('/', $content, 2);
$size = (int)$s;
return 0; // aborts transfer
} else if ($header == 'content-length' && 206 != curl_getinfo($curl, CURLINFO_HTTP_CODE)) {
// found content-length header and this is not a 206 Partial Content response (range response)
$size = (int)$content;
return 0;
} else {
// continue
return $length;
}
});
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($curl, $data) use ($in_headers) {
if (!$in_headers) {
// shouldn't be here unless we couldn't determine file size
// abort transfer
return 0;
}
// write function is also called when reading headers
return strlen($data);
});
$result = curl_exec($ch);
$info = curl_getinfo($ch);
return $size;
}
用法:
$size = getRemoteFileSize('http://example.com/video.mp4');
if ($size === null) {
echo "Could not determine file size from headers.";
} else {
echo "File size is {$size} bytes.";
}
PHP函數get_headers()
作品爲我檢查內容長度作爲
$headers = get_headers('http://example.com/image.jpg', TRUE);
$filesize = $headers['content-length'];
對我來說(使用nginx)標題是Content-Length – Pangamma 2017-09-19 18:11:58
一行最佳解決方案:
echo array_change_key_case(get_headers("http://.../file.txt",1))['content-length'];
PHP是太delicius
function urlsize($url):int{
return array_change_key_case(get_headers($url,1))['content-length'];
}
echo urlsize("http://.../file.txt");
- 1. 無需打開文件即可文件大小
- 2. 獲得在KB/MB PHP遠程文件大小/ GB格式
- 3. PHP,確定遠程文件的大小
- 4. PHP強制下載遠程文件
- 5. PHP - 笨下載遠程文件
- 6. 使用PHP下載遠程文件(2GB)
- 7. 下載遠程文件
- 8. 下載大量小文件
- 9. Jsp下載文件大小
- 10. 下載文件大小--JavaME
- 11. 獲得遠程文件的大小(不使用Content-Length字段)
- 12. solr查詢 - 無需掃描文件即可獲得結果
- 13. 使用文件大小讀取遠程文件大小
- 14. 在PHP中可靠下載大文件
- 15. 獲取遠程託管文件的文件大小
- 16. 使用PHP/cURL下載遠程文件:更強大一點
- 17. 如何通過使用PHP無需下載即可比較2個文件?
- 18. 如何讓人們無需解釋代碼即可下載.php文件?
- 19. 如何獲得遠程存儲的圖像文件的大小? (PHP)
- 20. 如何獲取多個文件下載的文件大小
- 21. 在android中下載文件之前獲取文件大小
- 22. 在通過HTTP下載文件之前獲取文件大小
- 23. 獲取文件請求的文件大小信息下載
- 24. 無需下載即可從遠程jpeg生成縮略圖
- 25. 如何在開始下載之前獲取遠程文件的大小?
- 26. 無法下載文件 - PHP
- 27. 用PHP覆蓋文件後無法獲得新的文件大小?
- 28. PHP強制下載遠程文件而無需通過我們的服務器
- 29. 以編程方式從遠程文件使用delphi獲取文件大小,然後下載它
- 30. Python ftplib在下載之前無法獲取文件的大小?
我讀的是較早的,不知道,如果內容長度指長度或文件大小 – dassouki 2010-04-08 18:59:45
好,如果該請求返回一個文件,請求大小*是*文件大小 – Gareth 2010-04-08 19:01:07
但請記住,在沒有內容長度的情況下,_can_可能是響應。 – VolkerK 2010-04-08 19:26:25