$is_upload = false;
$msg = null;
if(!empty($_FILES['upload_file'])){
//检查MIME
$allow_type = array('image/jpeg','image/png','image/gif');
if(!in_array($_FILES['upload_file']['type'],$allow_type)){
$msg = "禁止上传该类型文件!";
}else{
//检查文件名
$file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];
if (!is_array($file)) {
$file = explode('.', strtolower($file));
}
$ext = end($file);
$allow_suffix = array('jpg','png','gif');
if (!in_array($ext, $allow_suffix)) {
$msg = "禁止上传该后缀文件!";
}else{
$file_name = reset($file) . '.' . $file[count($file) - 1];
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH . '/' .$file_name;
if (move_uploaded_file($temp_file, $img_path)) {
$msg = "文件上传成功!";
$is_upload = true;
} else {
$msg = "文件上传失败!";
}
}
}
}else{
$msg = "请选择要上传的文件!";
}
explode(a,b)
函数以a为分割,把b转为数组。
reset()
函数把数组内部指针移动到数组第一个元素,并返回值。
end()
把数组内部指针移动到数组最后一个元素,并返回值。
count()
函数数组元素的数量。
通过$file_name = reset($file) . '.' . $file[count($file) - 1];
可以知道最终的文件名是由数组的第一个和最后一个元素拼接而成。如果是正常思维来讲,无论如何都是没有办法绕过的,但是有个地方给了一个提示。
这里有个判断,如果不是数组,就自己拆成数组,也就是说,我们是可以自己传数组进入的。如果第一个元素是x.php/
,最后一个元素是end()
,讲道理$file[count($file)-1]
也就是最后一个,但是为什么不直接使用end()
呢,也就是说有特殊的情况下,这两个东西是不等的,其实就是这样的一个数组$array=([0] -> 'x.php/' [2]->'jpg')
,看下面这个测试案例就知道是什么意思了。
$file = array();
$file[0] = 'x.php/';
$file[2] = 'jpg';
print_r($file);
echo "数组总元素个数为".count($file);
?>
Array
(
[0] => x.php/
[2] => jpg
)
数组总元素个数为2
再来分析一下$file_name = reset($file) . '.' . $file[count($file) - 1];
,按上面的测试代码来看,reset($file)
肯定是x.php/
,count($file)
为2
,再减少1
,后缀就变成了$file[1]
。但是上面那个数组里面没有$file[1]
啊,这里,来打印着测试一下。
echo "\$file[1] is".$file[1];
Array
(
[0] => php/
[2] => jpg
)
$file total is2**********************$file[1] is
很明显看到结果是空,也就是$file[count($file) - 1]
相当于没有内容,那最后的文件名为x.php/.
了,这个时候就可以用19关的方法进行绕过,当然也可以利用windows的特性.
和空格
和绕过。
访问,成功解析。