7.3 与 7.2 上的 finfo 相当慢

finfo considerably slower on 7.3 vs. 7.2

我注意到在从 php 7.2 迁移到 7.3 后,文件浏览器小部件的加载时间要长得多。

通常需要不到一秒的操作花费了相当长的时间。启用 slowlog 后,我使用 finfo 将问题追溯到 MIME 查找。恢复到 7.2 后问题得到解决。

这是我创建的一个简单测试来说明问题:

#!/bin/bash
set -e

ITERS=${1:-1000}

echo "Testing finfo over $ITERS iterations"
for VER in '7.2' '7.3'; do
        echo ---
        echo "Testing PHP $VER"
        docker run -i \
                -e "ITERS=${ITERS}" \
                php:${VER}-cli-alpine php <<'EOF'
<?php
$iters = $_ENV["ITERS"];

$start = microtime(true);
for ($i = 1; $i <= $iters; $i++){
  $finfo = new finfo(FILEINFO_MIME);
  $type = $finfo->file("/bin/sh");
  unset($finfo);
}
$ttl = microtime(true) - $start;
echo "Took: $ttl\n";
?>
EOF
done

这是 运行 在具有 3 个 CPU 的 prestine DigitalOcean droplet 上的结果:

root@phptest:~# ./test.sh 1000
Testing finfo over 1000 iterations
---
Testing PHP 7.2
Took: 1.2104759216309
---
Testing PHP 7.3
Took: 2.4543979167938

7.3 测试用了两倍多的时间。我已经 运行 在许多系统上进行了此测试,并且在所有情况下我都看到 运行 时间增加了 7.3 的 30% 或更多;在某些情况下更多。这是在具有更多负载且只有 2 个 CPU 的 Droplet 上进行的相同测试 运行(这是我第一次遇到问题的机器;您可以看到原因):

% ./test.sh 100
Testing finfo over 100 iterations
---
Testing PHP 7.2
Took: 0.10123181343079
---
Testing PHP 7.3
Took: 34.721122980118

这种放缓的原因可能是什么,我应该使用什么 configuration/optimizations 吗?

finfo 严重依赖 PCRE,在 7.3 中他们更新了 PCRE 库。我在更新日志中找不到任何其他可能影响到这种程度的更改。

如果是这种情况,您无能为力,只能恢复到 7.2 或使用不同的方法来识别 mime 类型;或者使用另一个安全向量——finfo 实际上很容易被愚弄,所以这不是一个很好的解决方案。有关更深入(和粗暴)的讨论和示例,请参阅 PHP file upload: mime or extension based verification?