php上传文件原理

上传文件原理

总述:将本地的文件上传到服务器中。
php上传文件的步骤:

第一步:将本地的文件上传到服务器的临时目录
第二步:将上传的文件从临时目录移动到指定的目录中。

method属性:传值的方法 method=’post’
enctype属性:上传文件进行编码 enctype=”multipart/form-data”

简单原理 :
表单部分
这里写图片描述
PHP代码部分:
这里写图片描述
超全局变量 $_FILES
这里写图片描述
这里写图片描述
这里写图片描述

对上传文件的判断需要考虑到?

/**
*
* 1)判断是否是HTTP POST上传的
* 2)判断是否有错误
* 3)判断文件大小
* 4)判断文件扩展名
* 5)判断文件类型
* 6)构建临时文件
* 7)构建目标文件
*/
1)判断文件是否是通过HTTP POST 上传的
is_uploaded_file //判断文件是否是通过HTTP POST上传的
这里写图片描述
2)上传文件错误代码

这里写图片描述
3)对上传文件大小的判断
在php.ini中设置上传文件的大小:
upload_max_filesize // 上传允许的单文件的最大值
max_file_uploads //上传文件的允许最大数量

这里写图片描述
这里写图片描述
4)对上传文件扩展名的判断
strrpos //计算指定字符串在目标字符串中最后一次出现的位置
strrchr //查找指定字符在字符串中的最后一次出现
这里写图片描述
5)上传文件类型的判断(MIME)
这里写图片描述
这里写图片描述
利用php_fileinfo.dll 对MIME类型进行严格检查:
开启php_fileinfo.dll扩展,finof_open(FILEINFO_MIME_TYPE);finfo_file();
这里写图片描述
这里写图片描述
这里写图片描述
6上传文件:move_uploaded_file
move_uploaded_file( t m p n a m e , dst_name) //将上传的文件移动到新的路径
说明:
1) t m p n a m e / / 2 ) dst_name //将上传文件移动到指定的路径中,并设置新的文件名.
这里写图片描述
如果上传文件打不开:
关于没有temp访问权限,添加一个everyone的用户
这里写图片描述
表单代码:
index.php 如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
    请选择上传文件:<input type='file' name='upload'></input>
    <input type="submit" name="submit" value="立即上传"></input>
</form>
</body>
</html>

后台逻辑
接收代码

<?php 
header("content-type:text/html;charset=utf-8");
if (isset($_POST['submit'])) {
    //打印一下$_FILES
    echo "<pre>";
    print_r($_FILES);
    echo "</pre>";

    //判断文件是不是通过表单上传的
    //is_uploaded_file(上传的临时文件)
    if(!is_uploaded_file($_FILES['upload']['tmp_name'])){
        exit('上传的文件有问题');
    }

    //上传文件是否有错误
    if($_FILES['upload']['error'] != 0){
        exit('上传文件有错误,请重新上传');
    }
    //判断文件大小
    //允许上传小于2MB的文件
    if ($_FILES['upload']['size']>2*1024*1024) {
        exit('上传文件过大,请重新上传');
    }

    //获取文件扩展名
    //方法一:
    //strrpos — 计算指定字符串在目标字符串中最后一次出现的位置
    //strrpos(大海, 针);
    //$index = strrpos($_FILES['upload']['name'], ".");
    //echo $index; 9
    //$ext = substr($_FILES['upload']['name'], $index);
    //echo $ext;  .jpg

    //方法二:
    //strrchr — 查找指定字符在字符串中的最后一次出现
    $ext = strrchr($_FILES['upload']['name'], '.');

    //判断文件类型
    //使用第三扩展
    $fs = finfo_open(FILEINFO_MIME_TYPE);
    //var_dump($fs);
    //finfo_file(资源类型,上传的临时文件)
    $mime = finfo_file($fs,$_FILES['upload']['tmp_name']);
    //image/jpeg
    //本网站对用户上传文件的类型有限制
    $arr_mime = array('image/jpeg' ,'image/png');
    //in_array — 检查数组中是否存在某个值
    //in_array(needle, haystack)
     if(!in_array($mime, $arr_mime)){
        exit('上传的文件类型不合法,请重新上传');
     }

    //构建临时文件
    $filename = $_FILES['upload']['tmp_name'];
    //构建目标文件的文件名及路径
    $path ='./upload/'; //在服务器的目录
    $destination = $path.date('YmdHis').$ext;  //$ext是文件的扩展名
    if(!move_uploaded_file($filename, $destination)){
        exit('上传失败');
    }

} else {
    echo "<script>alert('非法上传');location.href='index.php'</script>";
}

?>

将上传封装为函数
在上传的代码中,可以由用户自己来定义的通过设置为形参
表单代码还是之前的
后台逻辑分开
upload.php

<?php 
header("content-type:text/html;charset=utf-8");
require_once './config.php';
if (isset($_POST['submit'])) {

    $file = $_FILES['upload'];
    $arr_mime = array('image/jpeg' ,'image/png');
    $path = 'upload';

    //调用函数
    upload($file,$arr_mime,$path);

} else {
    echo "非法上传";
}
?>

封装的上传文件函数
哪里需要用就可以直接include
config.php代码如下

<?php 
/**
 * [upload description]
 * @param  [type] $file     [表单中文件域name的值 如: $_FILES['upload']]
 * @param  [type] $arr_mime [允许上传的文件类型]
 * @param  [type] $path     [自己定义的上传文件的路径]
 * @return [type]           [description]
 */
function upload($file,$arr_mime,$path){
    //判断文件是不是通过表单上传的
    //is_uploaded_file(上传的临时文件)
    if(!is_uploaded_file($file['tmp_name'])){
        exit('上传的文件有问题');
    }

    //上传文件是否有错误
    if($file['error'] != 0){
        exit('上传文件有错误,请重新上传');
    }
    //判断文件大小
    //允许上传小于2MB的文件
    if ($file['size']>2*1024*1024) {
        exit('上传文件过大,请重新上传');
    }

    //方法二:
    //strrchr — 查找指定字符在字符串中的最后一次出现
    $ext = strrchr($file['name'], '.');

    //判断文件类型
    //使用第三扩展
    $fs = finfo_open(FILEINFO_MIME_TYPE);
    //var_dump($fs);
    //finfo_file(资源类型,上传的临时文件)
    $mime = finfo_file($fs,$file['tmp_name']);
    //image/jpeg
    //本网站对用户上传文件的类型有限制

    //in_array — 检查数组中是否存在某个值
    //in_array(needle, haystack)
     if(!in_array($mime, $arr_mime)){
        exit('上传的文件类型不合法,请重新上传');
     }
    //构建临时文件
    $filename = $file['tmp_name'];
    //构建目标文件的文件名及路径
    //$path ='./upload/'; //在服务器

    $destination = $path.'/'.date('YmdHis').$ext;  //$ext是文件的扩展名

    if(!move_uploaded_file($filename, $destination)){
        exit('上传失败');
    }

}

 ?>

多文件上传

这里写图片描述
将三维数组转为二维数组
这里写图片描述
以临时文件为例进行foreach遍历
k e y , value对应的值如下图:
这里写图片描述
文件名处理:
生成唯一的ID目录文件名,
这里写图片描述
在其它判断中,$key的使用方法:
如在遍历中,文件大小的判断
这里写图片描述

表单代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
    请选择上传文件:<br><br>
    <input type='file' name='upload[]'></input><br><br>
    <input type='file' name='upload[]'></input><br><br>
    <input type='file' name='upload[]'></input><br><br>
    <input type="submit" name="submit" value="立即上传"></input>
</form>
</body>
</html>

后台逻辑代码`

<?php 
header("content-type:text/html;charset=utf-8");

if (isset($_POST['submit'])) { 
    /*echo "<pre>";
    print_r($_FILES);
    echo "</pre>";
    echo "<hr>";*/
    //将三维数组转为二维数组,为了便于操作
    $arr = $_FILES['upload'];
    echo "<pre>";
    print_r($arr);
    echo "</pre>";
    echo "<hr>";

    foreach ($arr['tmp_name'] as $key => $value) {

    //如判断文件的大小
    if($arr['size'][$key]>2*1024*1024){
        exit('文件过大');
    }
    //文件的扩展名
    $ext = strrchr($arr['name'][$key], '.');
    //构建目标文件的文件名及路径
    $path ='./upload'; //在服务
    //多文件上传注意重命名的问题
    //uniqid();
    $destination = $path.'/'.uniqid('itcast').date('YmdHis').'.jpg';  

        if(!move_uploaded_file($value, $destination)){
            exit('上传失败');
        }
    }
} else {
    echo "非法上传";
}
?>

猜你喜欢

转载自blog.csdn.net/liuqun0319/article/details/80740693