正如人們已經發現的,當試圖將文件加載到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 –