问题
Working on a little upload script here. I'm trying to check if the uploaded image really is an image and not just a renamed PHP file.
When the script is posted I can print the array with
foreach ($_FILES['images']['name'] as $key => $value){
print_r(getimagesize($_FILES['images']['tmp_name'][$key]));
That works just fine, so it won't return false. But even if I upload a file that is not an image, it won't give false. It just returns nothing at all, and the rest of my script just processes the thing like an image.
Could anyone tell me what I am doing wrong?
回答1:
Upload
you can not use getimagesize
on $_FILES['images']['tmp_name'][$key]
directly .. you need to copy it into your system first before you can use it
Use $_FILES['images']['size'][$key]
temporarily
Or
move_uploaded_file($_FILES['images']['tmp_name'][$key], $destination);
print_r(getimagesize($destination));
Fake Image
Please not that $_FILES['images']['type'][$key]
can be faked
Using Fake image Headers
Example
file_put_contents("fake.png", base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAABGdBTUEAALGPC/xhBQAAAAZQTFRF////
AAAAVcLTfgAAAAF0Uk5TAEDm2GYAAAABYktHRACIBR1IAAAACXBIWXMAAAsSAAALEgHS3X78AAAAB3RJTUUH0gQCEx05cq
KA8gAAAApJREFUeJxjYAAAAAIAAUivpHEAAAAASUVORK5CYII='));
Uploading 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
Validate Image
Usage
var_dump ( getimagesizeReal ( "fake.png" ) );
Function Used
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 ;
}
回答2:
I'd like to recommend against trusting the results of getimagesize()
when deciding whether to place the uploaded file anywhere in your document root. That's because PHP code embedded in GIF files (titled like image.gif.php
) will be identified as images by getimagesize()
, but serving them will run the PHP code inside them in addition to displaying the image. Here is some more information on the issue.
The article linked above recommends setting up a separate controller through which all the user uploaded files are served. Files read with readfile()
are not parsed when accessed through the local filesystem.
回答3:
Firstly, you can use getimagesize on $_FILES['images']['tmp_name'], so that's not an issue.
If you want to check if the file is an image, then try this:
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';
}
}
回答4:
You can simply use $_FILES['images']['type']
. it'll give you the type of file uploaded. Then check it againt octate stream or other executable file. If so then do not allow it.
回答5:
@user1362916 If you are uploading multiple images with HTML then perhaps you need to add one more array like this.
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';
}
}
Here check [i] because this is for multiple file upload.
Below is full script
<!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>
来源:https://stackoverflow.com/questions/10464948/getimagesize-not-returning-false-when-it-should