在我们日常的开发中,经常需要用到判断图片是否存在,存在则显示,不存在则显示默认图片,那么我们怎么判断呢?
getimagesize()函数(推荐学习:PHP编程从入门到精通)
getimagesize 函数并不属于 GD 扩展的部分,标准安装的 PHP 都可以使用这个函数。可以先看看这个函数的文档描述:http://php.net/manual/zh/function.getimagesize.php
如果指定的文件如果不是有效的图像,会返回 false,返回数据中也有表示文档类型的字段。如果不用来获取文件的大小而是使用它来判断上传文件是否是图片文件,看起来似乎是个很不错的方案,当然这需要屏蔽掉可能产生的警告,比如代码这样写:<?php
$filesize = @getimagesize('/path/to/image.png');
if ($filesize) {
do_upload();
}
# 另外需要注意的是,你不可以像下面这样写:
# if ($filesize[2] == 0)
# 因为 $filesize[2] 可能是 1 到 16 之间的整数,但却绝对不对是0。
但是如果你仅仅是做了这样的验证,那么很不幸,你成功的在代码里种下了一个 webshell 的隐患。
要分析这个问题,我们先来看一下这个函数的原型:static void php_getimagesize_from_stream(php_stream *stream, zval **info, INTERNAL_FUNCTION_PARAMETERS){
...
itype = php_getimagetype(stream, NULL TSRMLS_CC); switch( itype) {
...
}
...
}static void php_getimagesize_from_any(INTERNAL_FUNCTION_PARAMETERS, int mode) {
...
php_getimagesize_from_stream(stream, info, INTERNAL_FUNCTION_PARAM_PASSTHRU);
php_stream_close(stream);
}
PHP_FUNCTION(getimagesize)
{
php_getimagesize_from_any(INTERNAL_FUNCTION_PARAM_PASSTHRU, FROM_PATH);
}
限于篇幅上面隐藏了一些细节,现在从上面的代码中我们知道两件事情就够了:
最终处理的函数是 php_getimagesize_from_stream
负责判断文件类型的函数是 php_getimagetype
接下来看一下 php_getimagetype 的实现:PHPAPI int php_getimagetype(php_stream * stream, char *filetype TSRMLS_DC){
... if (!memcmp(filetype, php_sig_gif, 3)) { return IMAGE_FILETYPE_GIF;
} else if (!memcmp(filetype, php_sig_jpg, 3)) { return IMAGE_FILETYPE_JPEG;
} else if (!memcmp(filetype, php_sig_png, 3)) {
...
}
}