欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

PHP学习笔记 02 之文件上传

程序员文章站 2023-09-09 17:46:01
我们了解了表单传值后,这些我就可以完成PHP的文件上传了。我们了解PHP文件上传前,先了解PHP文件上传的原理。 一、PHP上传文件原理 1. 第一步:将本地的文件通过form表单上传到服务器的临时目录中,临时目录是默认的,但我们可以修改,修改方式最后讲; 2. 第二步:将上传的文件从临时目录中移动 ......

我们了解了表单传值后,这些我就可以完成php的文件上传了。我们了解php文件上传前,先了解php文件上传的原理。

一、php上传文件原理

  1. 第一步:将本地的文件通过form表单上传到服务器的临时目录中,临时目录是默认的,但我们可以修改,修改方式最后讲;
  2. 第二步:将上传的文件从临时目录中移动到指定目录中.。

二、form表单注意事项

  • method属性必须是: method = ‘post’
  • enctype属性必须是:enctype = multipart/form-data , 对上传文件进行编码,文件上传并不是上传的文件本身,而是上传文件的编码,由服务器端对编码进行分析。

三、简单的文件上传功能实现

1、思路分析

PHP学习笔记 02 之文件上传

PHP学习笔记 02 之文件上传

对于上面error字段的错误信息说明,php官方手册上给出了解释:

upload_err_ok
: 其值为 0,没有错误发生,文件上传成功。

upload_err_ini_size
: 其值为 1,上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值。

upload_err_form_size
: 其值为 2,上传文件的大小超过了 html 表单中 max_file_size 选项指定的值。

upload_err_partial
: 其值为 3,文件只有部分被上传。

upload_err_no_file
: 其值为 4,没有文件被上传。

upload_err_no_tmp_dir
: 其值为 6,找不到临时文件夹。php 4.3.10 和 php 5.0.3 引进。

upload_err_cant_write
: 其值为 7,文件写入失败。php 5.1.0 引进。

我们知道如何获取临时文件信息后,根据原理我们只需要做以下几件事就可以实现文件上传功能:

  1. 得到临时文件,即得到文件的路径,就是数组里的tmp_name;
  2. 自定义一个目录,然后加上文件名,然后拼接成文件路径,如‘e:/uploads/1.jpg’,我们上次的文件名就是数组里的name;
  3. 然后将临时文件移动到自定义的目录,这里我们会用到 move_uploaded_file 函数,关于这个函数如下说明:
    PHP学习笔记 02 之文件上传

2、代码实现

(1)前台test.html

<!--  
created by phpstrom
user: 冷魅蘇
date: 2019/4/27
time: 17:00
-->
<!doctype html>
<html lang="zh-cn">
<head>
    <meta charset="utf-8">
    <title>examples</title>
</head>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
    <label for="myfile">上传文件:</label>
    <input type="file" id="myfile" name="myfile">
    <br>
    <input type="submit" value="提交">
</form>
</body>
</html>

(2)后台upload.php

<?php
/*
* created by phpstrom
* user: 冷魅蘇
* date: 2019/4/27
* time: 17:02
*/
echo '<pre size="16">';
//得到临时文件
$tmpname = $_files['myfile']['tmp_name'];
//对应保存的目录
$filename = 'e:/uploads/'. $_files['myfile']['name'];
//移动临时文件到目录
move_uploaded_file($tmpname,$filename);

开心,文件上传已经实习了,但问题很大。

四、完善上传代码upload.php

1、简单的文件上传代码漏洞分析

上述的文件上传我们是已经实习了,但有几点问题:

  1. 自定义的文件目录是否存在,如果根本没有这个文件夹,会出现错误。所以,我们要检查是否有该文件夹,如果没有就创建。
  2. 文件上传到临时目录可能会出现错误,所以错误信息我们还是要显示出来的;
  3. 文件上传的大小要限制,不限制是不合理的,我们限制文件上传大小可以通过前台js限制,也可以通过php.ini中配置相应的参数(后面会说明),但我们还是要通过php代码进行判断;
  4. 我们常见的有头像上传、视频上传、文本上传等,所有我们对于不同的功能应该规定上传的文件类型;
  5. 我们保存的文件名不应该是同样的,否则每次上传就把原文件给覆盖了,但如何你需要把原文件给覆盖也可以,但生成不同的文件名保存,这个功能也应该是需要具备的;
  6. 临时文件的移动可能会出错,所以错误处理我们需要加上去;
  7. 文件保存的目录、文件上传的大小、上传的文件类型还有name的名称,这些我们都是可能变的,我们不可以固定不变,所以我们要把上面的全部封装成函数,以变量传参的方式来实习文件上传。

2、完善后的upload.php

下面直接给出修改后的代码,具体思路代码注释里面有说明:

<?php
/*
* created by phpstrom
* user: 冷魅蘇
* date: 2019/4/25
* time: 22:15
*/
/**
 * @param $file     前台post提交的文件信息
 * @param $mime     定义上传文件的类型
 * @param $maxsize  定义上传文件的大小
 * @param $path     定义保存的路径
 * @return          返回上传成功的文件名或错误信息码
 */
function upload($file,$mime,$maxsize,$path){
    //检查是否有该文件夹,如果没有就创建,并给予最高权限
    if (!file_exists ($path)) {
        if (!mkdir ("$path", 0777, true)) {      //创建文件夹,没成功返回4010
            return 4010;
        }
    }

    //判断文件上传到临时目录的错误
    switch ($file['error']){
        case 1:
            return 4001;     //'上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值'
            break;
        case 2:
            return 4002;     //'上传文件的大小超过了 html 表单中 max_file_size 选项指定的值'
            break;
        case 3:
            return 4003;     //'文件上传不完整'
            break;
        case 4:
            return 4004;     //'没有文件被上传'
            break;
        case 6:
            return 4005;     //'服务器内部错误,文件写入失败'
            break;
        case 7:
            return 4006;     //'服务器内部错误,文件写入失败'
            break;
    }

    if ($file['size']>$maxsize){
        return 4007;     //'文件上传大小超过限制'
    }

    //判断用户的上传文件的类型是合法,in_array() 数组查询
    if (!in_array($file['type'],$mime)){
        return 4008;     //"上传文件必须是图片"
    }

    //得到临时文件名
    $tmp = $file['tmp_name'];

    //调用函数生成随机的文件名
    $filename = getrandfilename();

    //获取文件的扩展名
    $ext = pathinfo($file['name'],pathinfo_extension);

    //拼接成保存的文件名
    $basename = $filename.'.'.$ext;

    //拼接路径
    $destination = $path.$basename;

    //如果文件合法,则将临时文件夹中的文件移动到指定的文件夹,并指定文件名
    if (move_uploaded_file($tmp,$destination)){
        return '上传成功,保存的文件名为:'.$basename;
    }else{
        return 4009;
    }
}

/**
 * 随机文件名的格式,时间戳+随机6位的大小写字母和数字的组合
 * mt_rand(x,y)  x,y的随机整数
 * chr 字符转换
 * ascii码表:97-122 小写字母  65-90大写字母
 */
function getrandfilename(){
    //将时间戳转成我们想要的格式
    $str = date('ymdhis',time());
    for($i=0; $i<6; $i++){
        switch (mt_rand(0,2)){      //随机从小写字母、大写字母、数字取一个
            case 0:
                $str .= chr(mt_rand(97,122));
                break;
            case 1:
                $str .= chr(mt_rand(65,90));
                break;
            case 2:
                $str .= mt_rand(0,9);
                break;
        }
    }
    return $str;
}

//文件上传信息手册
$errorinfo = [
    '4001' => '上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值',
    '4002' => '上传文件的大小超过了 html 表单中 max_file_size 选项指定的值',
    '4003' => '文件上传不完整',
    '4004' => '没有文件被上传',
    '4005' => '服务器内部错误,文件写入失败',
    '4006' => '服务器内部错误,文件写入失败',
    '4007' => '文件上传大小超过限制',
    '4008' => '上传文件必须是图片',
    '4009' => '文件从临时文件夹移动到上传文件夹失败',
    '4010' => '保存文件的目录创建失败,请确定目录是否合法'
];
//文件保存的文件夹
$path = 'e:/uploads/';
//定义文件上传的大小3mb
$maxsize = 1024*1024*3;
//定义允许用户上传的mime类型,现控制在图片上传
$mime = ['image/jpeg','image/jpg','image/pjpeg','image/png','image/gif'];
$file = $_files['myfile'];

$res = upload($file,$mime,$maxsize,$path);


echo '<pre style="font-size: 14px;">';
echo '<h3>临时文件上传信息</h3>';
var_dump($_files['myfile']);
echo '<h3>错误信息手册,显示文件名称上传成功</h3>';
var_dump($errorinfo);
echo $res;

说明:文件类型(mime)
PHP学习笔记 02 之文件上传

常见的几种类型:
PHP学习笔记 02 之文件上传

欢喜,我们的文件上传功能就此完成。下面我们说明一下对于文件上传,php.ini的相关配置,php.ini文件就在你安装的php目录下。

五、php.ini相关参数

1. upload_tmp_dir //修改上传文件的临时目录
upload_max_filesize //上传允许的单文件的最大值
max_file_uploads //上传文件的允许最大数量

PHP学习笔记 02 之文件上传

2. post_max_size //上传所有文件字节允许的最大值
PHP学习笔记 02 之文件上传

声明:本文欢迎大家评论和转载,使用本文章或代码还请声明,且在使用处的明显位置给出。如有其它问题或有什么建议,可在下方评论,或加qq(1414782205),或发邮箱jcdjor@163.com。