正如人们已经发现的,当试图将文件加载到Imagick中,无论出于何种原因都无法处理时,它会抛出一个无法捕捉的异常。使用imagick处理未知图像
我创建使用readImageFile ICO文件,并试图加载它():
$image = new imagick();
$handle = fopen('icon.ico', 'rb');
$image->readImageFile($handle);
这将抛出:
PHP Fatal error: Uncaught exception 'ImagickException' with message 'no decode delegate for this image format `' @ error/constitute.c/ReadImage/501'
当我指定的图像将是一个ICO文件,它的工作原理。所以这段代码罚款运行:
$image = new imagick();
$image->setFormat('ICO');
$handle = fopen('icon.ico', 'rb');
$image->readImageFile($handle);
使用,而不是readImageFile READFILE,这显然是着眼于扩展,因为这个代码也运行正常:
$image = new imagick();
$image->readimage('icon.ico');
然而,当我重命名ICO文件图标jpg和运行这个:
$image = new imagick();
$image->readimage('icon.jpg');
它失败,出现以下错误:
PHP Fatal error: Uncaught exception 'ImagickException' with message 'Not a JPEG file: starts with 0x00 0x00 `icon.jpg' @ error/jpeg.c/JPEGErrorHandler/322'
下面的代码,但是,处理更名为icon.jpg罚款ICO文件:
$image = new imagick();
$image->setFormat('ICO');
$handle = fopen('icon.jpg', 'rb');
$image->readImageFile($handle);
显然处理的图像是不看的扩展,它可以是任何东西的最佳方式,但看在实际的文件中。 Imagick显然没有做到这一点。我们有PHP函数,如mime_content_type(),getimagesize()和finfo_buffer()(PHP.net推荐我认为)。但是他们会返回类似“image/x-icon”的东西,这是setFormat()函数不会采用的。
什么是最好的方式去做这件事?
不错,谢谢你的回复!不幸的是,这不仅仅是我需要允许的ICO文件,而是一大堆。我说服客户撰写白名单。我希望finfo_buffer足够安全。维护我自己的一大堆文件类型的4字节签名列表似乎并不理想。我只是希望Imagick不会因为无法检测到正确的文件类型而出现如此惊人的失败。 –
这可能是重新评估解决方案体系结构的时候了。您应该努力将原始文件名传递给'Imagick'。提升异常也很常见,所以应用程序应该能够期待和处理这种情况。 – emcconville
我不确定我可以信任原始文件名,因为我不信任我的用户。正如我从这个问题所理解的那样,当Imagemagick抛出一个致命的错误时,你无法做到这一点:https://stackoverflow.com/questions/28156447/how-do-i-catch-an-imagick-fatal -error-in-php –