PHP语言中的jpg魔术,是指在一些特定情况下,PHP的图片处理函数会将JPG文件文本部分中的一些二进制信息误判为图像数据,从而导致图片出错或根本无法上传和展示。这会给开发者带来很多麻烦,因此我们需要认真研究这一问题,并应对解决。
渐进式图片编码是常见的JPG图片文件编码方式。其特征是图片数据依次逐个扫描和传输,在起初的数据传输中,图片可能只能显示出大体轮廓和色彩,待数据传输完毕后再显示完整细节。在PHP处理JPEG图片时,我们需要注意到渐进式编码对图片二进制数据的组织方式。如果图片传输还未完全结束,PHP会根据已传数据的长度去处理整个图片。然而由于图片还未完全传输完成,在信息不完整的情况下PHP的处理函数容易误判部分二进制信息为图像数据,使图片出现问题。需要解决这一问题,我们可以主动过滤掉这些可能出错的二进制信息。
处理方案中,我们可以使用PHP自带的getimagesize()函数进行图片格式监测,确认图片类型后筛选合法的jpg类型图片。此外,我们也可以使用exif_read_data()函数读取图片文件元数据,确认图片是否是合法渐进式JPG,并删除其中存储的图像数据信息。下面的代码片段实例了如何使用getimagesize()排除不合法图片类型:
<?php $image_info = getimagesize($image_path); if ($image_info === false || $image_info['mime'] !== 'image/jpeg') { // 跳过不合法类型的图片 continue; } ?>除了图片合法性检测和数据过滤,我们还可以配置php.ini中的相关选项来让PHP更好地应对jpg魔术问题。具体做法包括: 1. 将imagecreatefromjpeg()函数替换为ImageMagick或GD库的操作。ImageMagick 或 GD库具有独立的图像解码器,不同于PHP内置的JPEG解码器,风险更低。 2. 修改php.ini的exif.decode_jis_intel和exif.decode_jis_motorola选项,防止编码方式出现错误。 3. 禁用fread(), fgets()和fpassthru()等从文件指针中读取信息的函数,改用imagejpeg()和imagecreatefromjpeg()等更安全的图像操作函数。 此外还需要注意的一点是,对于上传的图片,我们应该限制其文件大小,并启用图像缩略功能,以降低渐进式编码对图像解码器的压力。比如,我们可以使用类似下面的PHP代码在保证照片质量的前提下对图片大小进行压缩:
<?php function compress_image($img_src, $img_dest, $quality) { $info = getimagesize($img_src); if ($info['mime'] == 'image/jpeg') { $image = imagecreatefromjpeg($img_src); } elseif ($info['mime'] == 'image/gif') { $image = imagecreatefromgif($img_src); } elseif ($info['mime'] == 'image/png') { $image = imagecreatefrompng($img_src); } imagejpeg($image, $img_dest, $quality); return $img_dest; } ?>总之,防范php jpg魔术非常必要,我们需要多方面考虑,从服务端和客户端两个角度入手寻找解决方案,并在实际项目中充分应用相应技术以提高图片处理安全性和服务器效率。