在这里处理一点上传脚本。我正在尝试检查上传的图像是否真的是图像,而不仅仅是重命名的PHP文件。
发布脚本后,我可以用
打印数组foreach ($_FILES['images']['name'] as $key => $value){
print_r(getimagesize($_FILES['images']['tmp_name'][$key]));
这很好用,所以它不会返回false。但即使我上传的文件不是图像,也不会给出错误。它根本不返回任何内容,我的脚本的其余部分只是像处理图像一样处理它。
有谁能告诉我我做错了什么?
答案 0 :(得分:4)
您无法直接在getimagesize
上使用$_FILES['images']['tmp_name'][$key]
..您需要先将其复制到系统中才能使用它
暂时使用$_FILES['images']['size'][$key]
或者
move_uploaded_file($_FILES['images']['tmp_name'][$key], $destination);
print_r(getimagesize($destination));
请注意$_FILES['images']['type'][$key]
可伪造
使用伪图像标题
示例
file_put_contents("fake.png", base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAABGdBTUEAALGPC/xhBQAAAAZQTFRF////
AAAAVcLTfgAAAAF0Uk5TAEDm2GYAAAABYktHRACIBR1IAAAACXBIWXMAAAsSAAALEgHS3X78AAAAB3RJTUUH0gQCEx05cq
KA8gAAAApJREFUeJxjYAAAAAIAAUivpHEAAAAASUVORK5CYII='));
上传fake.png
array
'name' =>
array
0 => string 'fake.png' (length=8)
'type' =>
array
0 => string 'image/png' (length=9)
'tmp_name' =>
array
0 => string 'C:\Apache\xampp\tmp\php44F.tmp' (length=30)
'error' =>
array
0 => int 0
'size' =>
array
0 => int 167
用法
var_dump ( getimagesizeReal ( "fake.png" ) );
使用的功能
function getimagesizeReal($image) {
$imageTypes = array (
IMAGETYPE_GIF,
IMAGETYPE_JPEG,
IMAGETYPE_PNG,
IMAGETYPE_SWF,
IMAGETYPE_PSD,
IMAGETYPE_BMP,
IMAGETYPE_TIFF_II,
IMAGETYPE_TIFF_MM,
IMAGETYPE_JPC,
IMAGETYPE_JP2,
IMAGETYPE_JPX,
IMAGETYPE_JB2,
IMAGETYPE_SWC,
IMAGETYPE_IFF,
IMAGETYPE_WBMP,
IMAGETYPE_XBM,
IMAGETYPE_ICO
);
$info = getimagesize ( $image );
$width = @$info [0];
$height = @$info [1];
$type = @$info [2];
$attr = @$info [3];
$bits = @$info ['bits'];
$channels = @$info ['channels'];
$mime = @$info ['mime'];
if (! in_array ( $type, $imageTypes )) {
return false; // Invalid Image Type ;
}
if ($width <= 1 && $height <= 1) {
return false; // Invalid Image Size ;
}
if($bits === 1)
{
return false; // One Bit Image .. You don't want that ;
}
return $info ;
}
答案 1 :(得分:1)
首先,您可以在$ _FILES ['images'] ['tmp_name']上使用getimagesize,这不是问题。
如果要检查文件是否为图像,请尝试以下操作:
if(isset($_POST['submit'])) {
$check = getimagesize($_FILES['images']['tmp_name']);
if($check !== false) {
echo 'File is an image - ' . $check['mime'];
}
else {
echo 'File is not an image';
}
}
答案 2 :(得分:1)
在决定是否将上传的文件放在文档根目录中的任何位置时,我建议不要信任getimagesize()
的结果。这是因为嵌入在GIF文件中的PHP代码(标题为image.gif.php
)将被getimagesize()
标识为图像,但除了显示图像之外,为它们提供服务还将在其中运行PHP代码。 Here是关于该问题的更多信息。
上面链接的文章建议设置一个单独的控制器,通过该控制器提供所有用户上传的文件。使用readfile()
读取的文件在通过本地文件系统访问时不会被解析。
答案 3 :(得分:0)
您只需使用$_FILES['images']['type']
即可。它会给你上传的文件类型。然后再次检查octate流或其他可执行文件。如果是,那就不要允许它。
答案 4 :(得分:0)
@ user1362916如果您使用HTML上传多个图像,那么您可能需要再添加一个这样的数组。
if(isset($_POST['submit'])) {
$check = getimagesize($_FILES['images']['tmp_name'][$i]);
if($check !== false) {
echo 'File is an image - ' . $check['mime'];
}
else {
echo 'File is not an image';
}
}
这里检查[i],因为这是用于多个文件上传。
以下是完整的脚本
<!DOCTYPE html>
<html>
<body>
<form action="#" method="post" enctype="multipart/form-data">
Select image to upload:
<input name="my_files[]" type="file" multiple="multiple" />
<input type="submit" value="Upload Image" name="submit">
</form>
<?php
if (isset($_FILES['my_files']))
{
$myFile = $_FILES['my_files'];
$fileCount = count($myFile["name"]);
for ($i = 0; $i <$fileCount; $i++)
{
$error = $myFile["error"][$i];
if ($error == '4') // error 4 is for "no file selected"
{
echo "no file selected";
}
else
{
if(isset($_POST['submit'])) {
$check = getimagesize($_FILES['my_files']['tmp_name'][$i]);
if($check !== false) {
echo 'File is an image - ' . $check['mime'];
}
else {
echo 'File is not an image';
}
}
}
}
}
?>
</body>
</html>