PHP关于文件$_FILES一些问题、校验和限制

科学研究

通过 PHP,可以把文件上传到服务器。通过$_FILES可以获取文件上传的相关信息;从而对文件进行操作。经过我的科学研究,发明了许多奇奇怪怪的问题;经过我的认真思考,终于;还是没能解决。最后一边百度一边思考。

上传单个文件

  1. 不管三七二十一,涉及到上传文件都需要使用enctype="multipart/form-data"进行编码
  2. 我们可以使用accept设置文件上传的类型,然并卵,设置了用户还是能更改,所以需要php验证(接收两种值MINE TYPE和文件扩展名)
  3. 我们验证表单的时候可以使用isset吞掉Undefined index的警告
  4. 使用$_FILES[‘name’]获取上传文件的信息
  5. 如果是提交到本页面,使用$_SERVER['PHP_SELF']提高代码的鲁棒性
<?php if($_SERVER['REQUEST_METHOD']==='POST'){ echo '1111'; var_dump($_FILES['file']); } ?>
...
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data">
    <div class="form-group">
        <label for="source">文件</label>
        <input type="file" name="file" accept="image/*">
    </div>
    <button>保存</button>
</form>
  • 我这里选择了一张图片上传
  • 结果打印的图片信息是一个关联数组,右边的值是string类型,所以我们操作的时候不用再遍历数组
    结果
  • 上面各个参数的意思
$_FILES["file"]["name"] - 上传文件的名称
$_FILES["file"]["type"] - 上传文件的类型
$_FILES["file"]["size"] - 上传文件的大小,以字节计
$_FILES["file"]["tmp_name"] - 存储在服务器的文件的临时副本的名称(这里使用的是wampserver服务器,所以是wamp临时文件夹,打开该文件夹,可以看到会有一个文件生成然后就清除了)
$_FILES["file"]["error"] - 由文件上传导致的错误代码

type

  • 这里我们可以校验文件的类型
$file = $_FILES['file'];
        if(strpos($file['type'],'image/')!==0){
            echo '文件不为图片类型';
        }

size

  • 我们可以限制上传图片的大小,比如图片不能大于1M
if ($file['size'] > 1 * 1024 * 1024) {
      echo '上传文件过大';
      return;
}

name和tmp_name

  1. 一般我们用来移动文件,会用到文件名和临时文件夹
  2. 有时候我们发现在移动文件名的时候,如果文件存在中文名,会移动失败,所以我们需要注意中文的问题
  3. 使用move_uploaded_file移动文件
  4. 有时候我们没有创建文件夹的话,需要使用(file_exists检测文件夹)
// 1. 移动到我们网站根目录下uploads文件夹下,为了防止重名,使用产生uniqid随机数
        $tmp = $file['tmp_name'];
        $target = './uploads/'.uniqid().$file['name'];
        $moved = move_uploaded_file($tmp,$target);
  1. 中文文件问题解决iconv('UTF-8', 'GBK', $file['name']

error的情况

  • UPLOAD_ERR_OK
    值为 0:没有错误发生,文件上传成功
  • UPLOAD_ERR_INI_SIZE
    值为 1:上传的文件超过了 php.ini中upload_max_filesize(默认情况为2M) 选项限制的值
  • UPLOAD_ERR_FORM_SIZE
    值为 2:上传文件的大小超过了 HTML表单中MAX_FILE_SIZE选项指定的值
  • UPLOAD_ERR_PARTIAL
    值为 3:文件只有部分被上传
  • UPLOAD_ERR_NO_FILE
    值为 4:没有文件被上传
  • 值为5,传文件大小为0;文件为0基本不会报这个错误
  • UPLOAD_ERR_NO_TMP_DIR
    值为 6,找不到临时文件夹。PHP 4.3.10 和 PHP 5.0.3 引进。
  • UPLOAD_ERR_CANT_WRITE
    值为 7,文件写入失败。PHP 5.1.0 引进。

很多时候我们都会报错1,或则有时候发现文件移动不了,除了中文问题,基本是后台进行了设置。
我移动图片基本没问题,但移动音乐文件时就报了1这个错误;后来我做了多次临床试验…
发现是文件太大导致移动不成功;我查看了文档修改了php限制问题
我这里使用的是wampserver服务器,所以我找到wamp\bin\php\php5.4.12下的php.ini

file_uploads = on ;是否允许通过HTTP上传文件的开关。默认为ON即是开
upload_tmp_dir ;文件上传至服务器上存储临时文件的地方,如果没指定就会用系统默认的临时文件夹
file_uploads = on ;是否允许通过HTTP上传文件的开关。默认为ON即是开
upload_tmp_dir ;文件上传至服务器上存储临时文件的地方,如果没指定就会用系统默认的临时文件夹

然而还是没有成功,我转头一想,这是服务器的问题,应该是该Apache下的php.ini,所以我找到了wamp\bin\apache\Apache2.4.4\bin下的php.ini;最好试验成功了
如果在不行,可以在进一步配置

max_execution_time = 600 ;每个PHP页面运行的最大时间值(),默认30秒
max_input_time = 600 ;每个PHP页面接收数据所需的最大时间,默认60秒
memory_limit = 8m ;每个PHP页面所吃掉的最大内存,默认8M

当然文件上传失败我们也需要做处理

if ($file['error'] !== UPLOAD_ERR_OK) {
            echo '文件上传失败';
            return;
        }

上传成功在移动文件

上传多个文件

使用multiple上传多个文件;在name值里面加上[]来接收多个文件

<input type="file" name="image[]" accept="image/*" multiple>

结果打印var_dump($_FILES['image']);的结果是不一样
结果
我们获取关联数组,右边的值是一个数组,所以我们需要在进行遍历,跟单个文件获取是不一样结果

参考文档

isset 和 empty
PHP文件上传