今天我发现一个神奇的问题,有一个文件获取不到文件大小
但是解压和右键完全没有问题,不是磁盘问题
于是我手动stat了一下,好家伙,居然是负的
/mnt $ php -r "print_r(stat('18no.zip'));"
Array
(
[dev] => 2048
[ino] => 228
[mode] => 33206
[nlink] => 1
[uid] => 0
[gid] => 0
[rdev] => 0
[size] => -2008364745
[atime] => 1716639595
[mtime] => 1716104887
[ctime] => 1716639573
[blksize] => 4096
[blocks] => 12854640
)
负的?我忽然想到了PHP官网的说明
整型数 int 的字长和平台有关,尽管通常最大值是大约二十亿(32 位有符号)。64 位平台下的最大值通常是大约 9E18。 PHP 不支持无符号的 int。int 值的字长可以用常量 PHP_INT_SIZE来表示, 最大值可以用常量 PHP_INT_MAX 来表示, 最小值可以用常量 PHP_INT_MIN 表示。
明白了,超过PHP_INT_MAX
被解释成负数了,那么怎么办呢?
有一个变通的办法,使用blocks
(分配的 512 字节块数)代替size
可惜Windows端不能用(64位的)
[dev] => 82248709
[ino] => 8796093022436
[mode] => 33206
[nlink] => 1
[uid] => 0
[gid] => 0
[rdev] => 0
[size] => 6581569847
[atime] => 1716639595
[mtime] => 1716104887
[ctime] => 1716104887
[blksize] => -1
[blocks] => -1
解决问题可以使用单位制,这样就无关CPU的
if($stat['size'] > 0){
foreach (['B','KB','MB','GB','TB','PB'] as $i => $unit)
if($stat['size'] / 1024 ** $i < 800){
$size = round($stat['size'] / 1024 ** $i,1) . $unit;
break;
}
}elseif($stat['blocks'] > 0){
foreach (['B','KB','MB','GB','TB','PB'] as $i => $unit)
if($stat['blocks'] / 1024 ** $i < 2){
$size = round(($stat['size'] / 1024 ** $i) * 512,1) . $unit;
break;
}
}else{
$size = '-';
}
成功!!!
/mnt $ php test.php
6.1GB
本文由 zlh 创作,采用 知识共享署名4.0 国际许可协议进行许可。
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。