我有以下代码:
$filecheck = basename($_FILES['imagefile']['name']);
$ext = substr($filecheck, strrpos($filecheck, '.') + 1);
if (($ext == "jpg" || $ext == "gif" || $ext == "png") && ($_FILES["imagefile"]["type"] == "image/jpeg" || $_FILES["imagefile"]["type"] == "image/gif" || $_FILES["imagefile"]["type"] == "image/png") &&
($_FILES["imagefile"]["size"] < 2120000)){
} else {
echo "F2";
die();
}
我需要做的是检查上传的文件是jpg / gif / png还是小于2 megs。
如果它大于2兆,或者不是正确的文件类型,我需要返回/ echo F2(api的错误代码)。
当我使用上面的代码处理70k jpg文件时,它返回F2。
笔记本都 图片即时上传的扩展名为.JPG。案件可能是一个因素吗?如果是这样,我该如何适应呢?
答案 0 :(得分:22)
请注意,您可能不希望依赖文件扩展名来确定文件类型。例如,某人上传具有.png
扩展名的可执行文件相当容易。恶意客户端也可以轻易伪造mime-type作为图像传递。 依赖该信息存在安全风险。
PHP Documentation:
文件的mime类型,如果浏览器提供了此信息。一个例子是“image / gif”。但是,在PHP方面没有检查这个mime类型,因此不会将其值视为理所当然。
尝试使用gd
(getimagesize()
)加载图片,以确保它们实际上是有效图像(而不仅仅是假装有图像文件标题的随机文件... finfo_file
依赖于那些标题)。
if($_FILES["imagefile"]["size"] >= 2120000) {
echo "F2";
die();
} else {
$imageData = @getimagesize($_FILES["imagefile"]["tmp_name"]);
if($imageData === FALSE || !($imageData[2] == IMAGETYPE_GIF || $imageData[2] == IMAGETYPE_JPEG || $imageData[2] == IMAGETYPE_PNG)) {
echo "F2";
die();
}
}
如果您确实必须使用扩展程序来验证文件是否为图片,请使用strtolower()
将扩展名设为小写。
$filecheck = basename($_FILES['imagefile']['name']);
$ext = strtolower(substr($filecheck, strrpos($filecheck, '.') + 1));
if (!(($ext == "jpg" || $ext == "gif" || $ext == "png") && ($_FILES["imagefile"]["type"] == "image/jpeg" || $_FILES["imagefile"]["type"] == "image/gif" || $_FILES["imagefile"]["type"] == "image/png") &&
($_FILES["imagefile"]["size"] < 2120000))){
echo "F2";
die();
}
答案 1 :(得分:5)
SUBNOTE图片即时上传的扩展名为.JPG。案件可能是一个因素吗?如果是这样,我该如何适应呢?
是的,这就是问题所在。你应该将strtolower()添加到这一行:
$ext = substr($filecheck, strrpos($filecheck, '.') + 1);
像:
$ ext = strtolower(substr($ filecheck,strrpos($ filecheck,'。')+ 1));
这将解决您当前的问题。但从技术上讲,你不应该担心文件扩展名,你真的只需要检查MIME类型
答案 2 :(得分:5)
$ext == "jpg"
之类的比较只会检查$ext
是否完全是“jpg”。
在进行这些比较之前,您可能希望在$ ext上使用strtolower来处理“.JPG”情况。
如果您使用的是PHP&lt; = 5.2,则可能需要使用mime_content_type来检查文件的内容类型,而不是依赖$_FILES['imagefile']['name']
和/或$_FILES["imagefile"]["type"]
两者都是由客户发送的 - 因此可以伪造。
如果您使用的是PHP&gt; = 5.3,则可能需要考虑新的扩展程序fileinfo,并且它是finfo_file
函数
对于文件的大小,您已经在使用$_FILES["imagefile"]["size"]
;没错,我猜,但是你只会在上传文件时才知道 - 但是,在上传之前没有真正的方法来检查那种东西,我担心......
您可能能够找到一些JS代码在文件上传之前对扩展进行首次预检 - 但您仍然需要检查服务器端,因为客户端的任何操作本质上都不安全。 / p>
不确定你可以对文件的大小做同样的事情,但是......
某些浏览器可能支持名为MAX_FILE_SIZE
的隐藏字段(请参阅有关file upload的文档);但不确定它是否真的受到支持(实际上从未见过它使用过;所以可能不是:-()
作为旁注,您可能希望配置upload_max_filesize,因此它允许上传至少与您想要的一样大(默认情况下,它通常设置为2MB;所以应该已经适合您)
答案 3 :(得分:3)
请注意,对于Internet Explorer, 他们将JPEG文件的mime类型提交为 image / pjpeg - 这与其他浏览器不同。
这是一个简单的函数,可以根据文件扩展名获取mime类型:
function mime2ext($mime){ // mime is like image/jpeg
$m = explode('/',$mime);
$mime = $m[count($m)-1]; // get the second part of the mime type
switch($mime){
case 'jpg':
case 'jpeg':
case 'pjpeg':
return 'jpg';
break;
case 'png':
return 'png';
break;
case 'gif':
return 'gif';
break;
}
return '';
}
答案 4 :(得分:3)
文件大小相当明显,但是上面人们在做什么检查它是正确的格式效率有点低,而且“不安全”。
这就是我的所作所为:
if($_FILES["userPicture"]["error"] == 0) {
// File was uploaded ok, so it's ok to proceed with the filetype check.
$uploaded_type = exif_imagetype($_FILES["userPicture"]["tmp_name"]);
// What we have now is a number representing our file type.
switch($uploaded_type) {
case "1":
$uploaded_type = "gif";
break;
case "2":
$uploaded_type = "jpg";
break;
case "3":
$uploaded_type = "png";
break;
}
}
更多信息;
http://www.php.net/manual/en/function.exif-imagetype.php
编辑:这具有“在每个浏览器中”工作的优势,因为它不依赖于文件名或用户提供的任何内容,除了文件数组值“错误”,它告诉我们没有真正的错误。
答案 5 :(得分:2)
Php是一种服务器端脚本语言,如果图片位于客户端,则无法通过php 检查其大小上传。
答案 6 :(得分:2)
你需要两件事:
使您的扩展程序检查不区分大小写:
if($strtolower($ext == "jpg")){
// do your stuff
}
检查文件是否实际包含图像。一个简单的方法是fileinfo:
$finfo = finfo_open(FILEINFO_MIME_TYPE);
echo finfo_file($finfo, $filename);
$finfo_close($finfo);
检查文件是否真的是图像的另一种方法是加载到像gd这样的图像库中。如果您的文件可以成功加载,则为图像。
请注意,jpeg图片可以包含.jpg
或.jpeg
扩展名。