在 PHP 中,为什么 imagecreatefromjpeg "not a jpeg file" 更改为致命错误?

In PHP, why has imagecreatefromjpeg "not a jpeg file" changed to a fatal error?

我有一段较旧的代码试图加载图像文件。由于它不知道它是什么类型,因此代码会尝试所有类型:

$res = @imagecreatefromjpeg($sourceName);
if ( $res === false)
    $res = @imagecreatefromgif($sourceName);
if ( $res === false)
    $res = @imagecreatefrompng($sourceName);
if ( $res === false) {
    $err[] = 'Cannot load file as JPEG, GIF or PNG!';

这曾在很长一段时间内完美运行,但在最近一次服务器迁移后,它在使用 PNG 文件时停止运行(JPEG 文件运行良好)。调查显示第一行产生致命错误:

Fatal error: imagecreatefromjpeg(): gd-jpeg: JPEG library reports unrecoverable error: Not a JPEG file: starts with 0x89 0x50

由于该行具有错误抑制运算符,脚本简单地停止执行并returned HTTP 200 并返回空响应。

我不明白的是……怎么……怎么……为什么……从什么时候……嗯?

即使是 official documentation 也表示这些函数 return FALSE 无法加载文件时,@ 运算符的构造也显示在那里。我在网上找不到任何东西可以说 "not a JPEG file" 是致命错误。无论在哪里提到它,它都是一如既往的警告。为什么我现在收到致命错误?

我的PHP是5.6.30,GD什么都有。

我想我可以回答我自己的问题。这是一个已知的错误。看。 PHP 错误 #73514 and #73479. And actually the bug is in libgd, and has been reported there too. A fix was made last November, but still hasn't made it to a release. So, yeah... no luck. I'll try to use getimagesize() 而不是先确定类型,然后改用适当的函数。对于真正损坏的文件,这仍然无济于事,但确实如此。

问题是您的文件扩展名错误,根据第一个字节,它实际上是 PNG,而不是 JPG。我的解决方案是检测第一个字节并将文件重命名为 PNG:

$firstBytes = bin2hex(file_get_contents($tmp_name,false,null,0,2));
if ($firstBytes==8950) $_FILES['file']['name'].= '.png';