真っ先に思いつくのはこういう実装でしょう。
function remote_filesize($url) {
if (false === $response = @file_get_contents($url)) {
return false;
}
return strlen($response);
}
しかしこのままだと巨大ファイルを相手にしたとき、サイズのみを知りたいのに延々とダウンロードで待たされるのは無駄な感じがしますよね。そこでヘッダーを取得したらレスポンスを待たずにブッチしちゃう get_headers 関数を利用します。処理は一瞬で終わるようになりますが、 Content-Length ヘッダーが返されていない場合には取得に失敗するという欠点はあります。
function remote_filesize($url) {
static $regex = '/^Content-Length: *+\K\d++$/im';
if (
!$list = @get_headers($url) or
!preg_match($regex, implode("\n", $list), $matches)
) {
return false;
}
return (int)$matches[0];
}
両方を組み合わせて効率よく確実に取得したい場合は以下のようにします。 http://
ストリームラッパーを使用したときに得られる $http_response_header という変数を利用します。この実装であればリモートファイルに対してもローカルファイルに対しても使うことが出来ますね。
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));
}