我正在尝试编写一个user_upload()函数并且它可以工作,但是图像mime类型文件不会上传,但html文件会上传。我该如何在这个脚本中修复它?
function user_upload()
{
$target_path = "uploads/".$_SESSION['username']."/";
$client_ID = mysql_query("SELECT 'client_ID'
FROM 'clients'
WHERE username='".$_SESSION['username']."'");
if(!empty($_FILES)){
// Add the original filename to our target path.
// Result is "uploads/filename.extension"
$target_path = $target_path . basename( $_FILES['uploadedfile']['name']);
if((!$_FILES["uploadedfile"]["type"] == "image/gif")
||(!$_FILES["uploadedfile"]["type"] == "image/png")
||(!$_FILES["uploadedfile"]["type"] == "image/jpeg") // "jpeg" for Firefox
||(!$_FILES["uploadedfile"]["type"] == "image/pjpeg") // "jpeg" for IE
||(!$_FILES["uploadedfile"]["type"] == "text/css")
||(!$_FILES["uploadedfile"]["type"] == "text/html")
||(!$_FILES["uploadedfile"]["type"] == "text/javascript")
||(!$_FILES["uploadedfile"]["type"] == "application/msword")
||(!$_FILES["uploadedfile"]["type"] == "application/pdf")
&&(!$_FILES["file"]["size"] < 1000000)){
echo "The file is not of the right type or size. It should be a
.gif, .png, .jpeg/.jpg, .css, .html, .javascript, .doc, or .pdf and under 1 billion kb.";
echo "If you need to send me a file different from these specification, feel free to
email it to me at exaple@support.com. These specifications are for the website's safety.";
}else{
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
mysql_query("INSERT INTO uploads(ID, URL) VALUES ('$client_ID', '$target_path')");
} else{
echo "There was an error uploading the file, please try again!";
}
}
}
}
答案 0 :(得分:1)
if语句错了。将其设为if (((type == png) || (type == gif)) && (size < 1 billion kb)) ...
而不是!type == png ...
。
答案 1 :(得分:1)
我通常不会像这样进行完整的代码审核,但这是我在您的代码中看到的一些问题。有些可能与这个问题有关,有些是我看到的其他问题。
第if(!empty($_FILES)){
行应为if(isset($_FILES['uploadedfile'])){
。这是因为如果有人在文件输入中上传了一个名称不同的文件,你的代码仍会运行,从而引发多个错误。
我对这条线感到不舒服:
$target_path = $target_path . basename( $_FILES['uploadedfile']['name']);
我95%肯定基本名称会使这个安全,但如果有一个正则表达式,白色列出了基本名称中允许的字符,我会感觉好多了。例如:
$target_path = $target_path . basename( $_FILES['uploadedfile']['name']);
// allow only target paths in the form abc123.ext only
if (!preg_match('/^[a-z0-9 -]+\.[a-z0-9]+$/i', $target_path) {
// invalid data, handle error
}
我对该类型的if语句有两条评论。
首先使用in_array
,它会使代码更容易阅读和维护。
其次,if语句中的最后一个||
与&&
的大小相关联。这是由order of operations引起的。如果需要a || (b && c)
,则可以使用此(a || b) && c
。
考虑到这两条评论,我会按照以下方式编写if statemnet。
$allowed_types = array("image/gif", "image/png", "image/jpeg", "image/pjpeg", "text/css", "text/html", "text/javascript", "application/msword", "application/pdf");
if(!in_array($_FILES["uploadedfile"]["type"], $allowed_types) || $_FILES["file"]["size"] >= 1000000) {
关于sql注入的可能性,我想提一下你的代码的最后一件事。如果你使用上面的正则表达式应该使输入安全,但因为我相信做安全性绝不是坏事我会使用mysql_real_escape_string
进一步消毒$target_path
变量。如下所示:
$target_path = mysql_real_escape_string($target_path);
mysql_query("INSERT INTO uploads(ID, URL) VALUES ('$client_ID', '$target_path')");
我不知道这是否能解决您的任何问题,但这些问题需要在代码中修复,并可能有助于调试代码无法正常工作的原因。