It seems that the problem extends beyond and despite Edilson's report, I noticed that it is not in every environment or PHP version that this will work well or necessarily necessarily.
On an x64 system, a file larger than 4GB returned a positive value, but it was not the file size, ie did not work:
sprintf("%u", filesize($file))
Even though it is in an x64 environment and PHP5 being compiled for x64, it still will not be 100% x64, actually it is x86_x64 in Windows (in PHP7 things worked a little better).
The problem is not well with PHP necessarily, but it is due to PHP5 working with 32bit and even 64bit will have a limitation, so what I needed was something that works well almost independent of the environment, I do not need to do calculations with value, I just needed to know the size of a file, I came up with these solutions:
Native system software
This solution will depend on stat
being available on Linux and Mac OSX and BSD servers for example, I do not know if it is something that works on all platforms, for Windows I used this SOen
Something like:
The script looks like this:
<?php
function filesizealternativo($arquivo)
{
if (is_file($arquivo) === false) {
return false;
}
$arqarg = escapeshellarg(realpath($arquivo));
if (strcasecmp(substr(PHP_OS, 0, 3), 'WIN') === 0) {
$command = 'for %F in (' . $arqarg . ') do @echo %~zF';
} else {
$command = 'stat -c %s ' . $arqarg;
}
$resposta = shell_exec($command);
if ($resposta === null) {
return false;
}
$resposta = trim($resposta);
if (is_numeric($resposta)) {
return $resposta;
}
return false;
}
$a = filesizealternativo('arquivogrande.7z');
var_dump($a);
Using the file: /// protocol with PHP
The problem of using stat
is the compatibility of some servers and dependencies, there are also some servers that block the shell_exec
, exec
, system
, etc functions, so I ran a test with CURL and file://
( link ), the result was very functional:
function filesizealternativo2($arquivo)
{
if (is_file($arquivo) === false) {
return false;
}
$arquivo = realpath(preg_replace('#^file:#', '', $arquivo));
$ch = curl_init('file://' . ltrim($arquivo, '/'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //Faz o retorno ser salvo na variável
curl_setopt($ch, CURLOPT_HEADER, 1); //Faz retornar os headers
curl_setopt($ch, CURLOPT_NOBODY, 1); //Evita retornar o corpo
$headers = curl_exec($ch);
curl_close($ch);
$ch = null;
//Com preg_match extraímos o tamanho retornado de Content-Length
if (preg_match('#(^c|\sc)ontent\-length:(\s|)(\d+)#i', $headers, $matches) > 0) {
return $matches[3];
}
return false;
}
$a = filesizealternativo2('arquivogrande.7z');
var_dump($a);
In this way the only dependency will be the Curl extension, which is usually already enabled on many servers.