h5ai 是一个现代的HTTP网络服务器的文件索引器,它的运行需要64位 PHP 环境。目前的最新版本(0.29.2)去除了对32位版本 PHP 的支持,这意味着若该程序运行在32位的 PHP 环境下,受限于32位版本 PHP 的限制,程序将无法显示大小超过 2GB 的文件。
从 h5ai 的历史 issue 来看, h5ai 曾在一段时间内为32位的 PHP 进行了特别的适配,以确保不因为受到 PHP 环境的限制而无法正确显示大于 2GB 的文件。但该功能在后续的某一版本中被取消,并建议用户升级到64位。
尽管使用64位系统及程序是大势所趋,但不可否认的是仍有不少的服务器仍在运行着32位的系统和程序。不安装64位系统的原因主要是受到硬件的限制,例如本人正在使用的树莓派3b,只能安装32位的系统。
有没有什么办法可以让 h5ai 在32位的 PHP 上也能正确运行?当然可以。在 PHP 中, filesize
函数用于返回一个文件的大小,数据类型为整形。若 PHP 为32位且文件大于 2GB ,就会报错。在 PHP 官方文档关于该函数的说明中,已有评论指出可以使用 shell_exec
函数执行 stat -c%s /your/file/path
命令以正确获取文件大小。另外, h5ai 还使用了 is_file
用于判断一个路径是否为文件,使用 is_readable
判断文件或目录是否可读,但这两个函数在32位 PHP 下对大于 2GB 的文件查询时均会出错,不能返回正确结果。基于此,下面将给出解决方法。
编辑文件 /_h5ai/private/php/core/class-filesize.php
,搜索关键词 $size = @filesize($path);
,在其后面追加如下内容:
if ($size <= 0){
if (!(strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')) {
// 需要将 $path 用引号围起来避免文件名出现空格时命令执行失败
// 需要转换为 float 类型是因为默认的 string 类型会报错
// 也不能转为 int 因为其上限为 2147483647 = 2^31-1,无论文件多大都只会显示为 2GB
$size = (float)trim(shell_exec('stat -c%s "'.$path.'"'));
}else{
$fsobj = new COM("Scripting.FileSystemObject");
$f = $fsobj->GetFile($path);
$size = $f->Size;
}
}
随后,搜索 is_file($path)
,将其修改为 !is_dir($path)
,如下所示:
if (!is_dir($path)) {
return $this->php_filesize($path);
}
这样可以避免使用 is_file
函数产生的错误。
编辑文件 /_h5ai/private/php/core/class-context.php
,搜索 is_readable
,将其所在行注释掉:
// || (!is_readable($path . '/' . $name) && $this->query_option('view.hideIf403', false))
这一行代码的作用是判断文件或目录是否可读,权限是否受限,若可读则显示在 h5ai 中。但由于使用 is_readable
判断一大于 2GB 的文件时始终返回错误(认为其不可读),因此在此将其注释掉。这实际上不是最好的方法,仍然可以通过配合 shell_exec
达到判断的目的,但我懒得写了。
完成以上步骤后刷新 h5ai 页面可以看到大于 2GB 的文件可以出现了,文件大小也能正确显示,但缩略图仍不能显示,但问题不大,先挖个坑看看以后能不能解决这个问题。