Last active
May 2, 2020 14:46
-
-
Save imbyc/3c9ae8a5b02e596cb7ee15aa67040251 to your computer and use it in GitHub Desktop.
[获取远程文件大小] https://blog.cooldev.cn/3042595489.html #remote-filesize #PHP #远程文件大小
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* 获取远程文件大小 | |
* @param $url | |
* @return int|null | |
*/ | |
function getRemoteFileSize($url) | |
{ | |
$size = null; | |
$timeout = 5; | |
// 尝试使用HEAD方式请求 | |
$opts = ['http' => ['method' => 'HEAD', 'header' => ['Connection: close'], 'timeout' => $timeout]]; | |
$headers = @get_headers($url, 1, stream_context_create($opts)); | |
// 访问不通直接返回; | |
if ($headers === false) return $size; | |
// 寻找 Content-Length (绝大多数到这里都会出结果) | |
if (isset($headers['Content-Length'])) { | |
$cl = $headers['Content-Length']; | |
return (int)(is_array($cl) ? array_pop($cl) : $cl); | |
} | |
// 没有Content-Length,看是否支持提交 Range请求头,寻找 Content-Range | |
if (isset($headers['Accept-Ranges']) && $headers['Accept-Ranges'] == 'bytes') { | |
$opts = ['http' => ['method' => 'GET', 'header' => ['Range: bytes=0-1', 'Connection: close'], 'timeout' => $timeout]]; | |
$headers = @get_headers($url, 1, stream_context_create($opts)); | |
if (isset($headers['Content-Range'])) { | |
list(, $size) = explode('/', $headers['Content-Range'], 2); | |
return (int)$size; | |
} | |
} | |
// fallback | |
// 上面都行不通使用curl,相当于下载但是不写入文件,不会出现file_get_contents的内存超出 | |
// 但如果远程文件很大,会执行很长时间,通过浏览器请求会触发超时 | |
$ch = curl_init(); | |
curl_setopt_array($ch, array( | |
CURLOPT_URL => $url, | |
CURLOPT_HEADER => false, | |
CURLOPT_RETURNTRANSFER => true, | |
CURLOPT_FOLLOWLOCATION => true, | |
CURLOPT_NOPROGRESS => false | |
)); | |
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, function ($curl, $dltotal, $dlnow, $ultotal, $ulnow) use (&$size) { | |
$size = $dlnow; | |
}); | |
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($curl, $data) { | |
return strlen($data); | |
}); | |
curl_exec($ch); | |
curl_close($ch); | |
return (int)$size; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment