单文件上传
前端页面

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>upload a file</title>
    </head>
    <body>
        <form action="upload.php" method="post" enctype="multipart/form-data">
            <input type="hidden" name="max_file_size" value="1024000" />
            <input type="file" name="test_pic" />
            <input type="submit" value="上传" />
        </form>
    </body>
    </html>

后端实现upload.php

    <?php
    /**
     * created by phpstorm.
     * date: 2018/11/11
     * time: 14:06
     */

    // 接收$_files数组
    $key = 'test_pic';
    $mimewhitelist = ['image/jpeg', 'image/png', 'image/gif'];//文件映射白名单
    $extwhitelist = ['jpeg', 'jpg', 'png', 'gif'];//文件扩展名白名单
    $allowsize = 2*1024*1024;
    $destdir = './uploads';

    $name = $_files[$key]['name']; // 源文件名称
    $type = $_files[$key]['type']; // mime 类型
    $tmpname = $_files[$key]['tmp_name']; // 临时文件名称
    $error = $_files[$key]['error']; // 错误信息
    $size = $_files[$key]['size']; // 文件大小 字节

    // 处理错误
    // 0 - 无错误
    if ($error > upload_err_ok) {
        switch($error) {
            // 1 - 文件大小超出了php.ini当中的upload_max_filesize的大小
            case upload_err_ini_size:
                exit('文件大小超出了php.ini当中的upload_max_filesize的大小');
            // 2 - 超出表单当中的max_file_size的大小
            case upload_err_form_size:
                exit('超出表单当中的max_file_size的大小');
            // 3 - 部分文件被上传
            case upload_err_partial:
                exit('部分文件被上传');
            // 4 - 没有文件被上传
            case upload_err_no_file:
                exit('没有文件被上传');
            // 6 - 临时目录不存在
            case upload_err_no_tmp_dir:
                exit('临时目录不存在');
            // 7 - 磁盘写入失败
            case upload_err_cant_write:
                exit('磁盘写入失败');
            // 8 - 文件上传被php扩展阻止
            case upload_err_extension:
                exit('文件上传被php扩展阻止');
            default:
                exit('未知错误');
        }
    }

    // 限制文件的mime
    if (!in_array($type, $mimewhitelist)) {
        exit('文件类型' . $type . '不被允许!');
    }

    // 限制文件的扩展名
    $ext = pathinfo($name, pathinfo_extension);
    if (!in_array($ext, $extwhitelist)) {
        exit('文件扩展名' . $ext . '不被允许!');
    }

    // 限制文件大小
    if ($size > $allowsize) {
        exit('文件大小 ' . $size . ' 超出限定大小 ' . $allowsize . ' !');
    }

    // 生成新的随机文件名称
    // md5(rand());
    $filename = uniqid() . '.' . $ext;

    // 移动临时文件到指定目录当中并重新命名文件名
    if (!file_exists($destdir)) {
        mkdir($destdir, 0777, true);
    }
    if (is_uploaded_file($tmpname) && move_uploaded_file($tmpname, $destdir . '/' . $filename)) {
        echo "恭喜,文件上传成功";
    } else {
        echo "很抱歉,文件上传失败";
    }

多文件上传,指定文件数量
前端页面

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>upload multiple files</title>
    </head>
    <body>
    <form action="multiple_upload.php" method="post" enctype="multipart/form-data">
        <input type="hidden" name="max_file_size" value="1024000" />
        <input type="file" name="test_pic1" />
        <input type="file" name="test_pic2" />
        <input type="file" name="test_pic3" />
        <input type="submit" value="上传" />
    </form>
    </body>
    </html>

后端实现multiple_upload.php

    <?php
    /**
     * created by phpstorm.
     * date: 2018/11/11
     * time: 14:54
     */

    $errors = [];
    $mimewhitelist = ['image/jpeg', 'image/png', 'image/gif'];
    $extwhitelist = ['jpeg', 'jpg', 'png', 'gif'];
    $allowsize = 2*1024*1024;
    $destdir = './uploads';

    foreach($_files as $key => $val) {
        // name type tmp_name error size
        // 接收$_files
        $name = $_files[$key]['name']; // 源文件名称
        $type = $_files[$key]['type']; // mime 类型
        $tmpname = $_files[$key]['tmp_name']; // 临时文件名称
        $error = $_files[$key]['error']; // 错误信息
        $size = $_files[$key]['size']; // 文件大小 字节

        // 处理错误
        // 0 - 无错误
        if ($error > upload_err_ok) {
            switch($error) {
                // 1 - 文件大小超出了php.ini当中的upload_max_filesize的大小
                case upload_err_ini_size:
                    $errors[$key] = '文件大小超出了php.ini当中的upload_max_filesize的大小';
                    continue 2;
                // 2 - 超出表单当中的max_file_size的大小
                case upload_err_form_size:
                    $errors[$key] = '超出表单当中的max_file_size的大小';
                    continue 2;
                // 3 - 部分文件被上传
                case upload_err_partial:
                    $errors[$key] = '部分文件被上传';
                    continue 2;
                // 4 - 没有文件被上传
                case upload_err_no_file:
                    $errors[$key] = '没有文件被上传';
                    continue 2;
                // 6 - 临时目录不存在
                case upload_err_no_tmp_dir:
                    $errors[$key] = '临时目录不存在';
                    continue 2;
                // 7 - 磁盘写入失败
                case upload_err_cant_write:
                    $errors[$key] = '磁盘写入失败';
                    continue 2;
                // 8 - 文件上传被php扩展阻止
                case upload_err_extension:
                    $errors[$key] = '文件上传被php扩展阻止';
                    continue 2;
                default:
                    $errors[$key] = '未知错误';
                    continue 2;
            }
        }

        // 限制mime
        if (!in_array($type, $mimewhitelist)) {
            $errors[$key] = '文件类型' . $type . '不被允许!';
            continue;
        }

        // 限制扩展名
        $ext = pathinfo($name, pathinfo_extension);
        if (!in_array($ext, $extwhitelist)) {
            $errors[$key] = '文件扩展名' . $ext . '不被允许!';
            continue;
        }

        // 限制大小
        if ($size > $allowsize) {
            $errors[$key] = '文件大小 ' . $size . ' 超出限定大小 ' . $allowsize . ' !';
            continue;
        }

        // 生成随机文件名称
        $filename = uniqid() . '.' . $ext;

        // 移动文件
        if (!file_exists($destdir)) {
            mkdir($destdir, 0777, true);
        }
        if (!is_uploaded_file($tmpname) || !move_uploaded_file($tmpname, $destdir . '/' . $filename)) {
            $errors[$key] = "很抱歉,文件上传失败";
            continue;
        }
    }

    if (count($errors) > 0) {
        var_dump($errors);
    } else {
        echo "文件全部上传成功";
    }

多文件上传,不定文件数量
前端页面

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>upload multiple files</title>
    </head>
    <body>
    <form action="multiple_upload2.php" method="post" enctype="multipart/form-data">
        <input type="hidden" name="max_file_size" value="6024000" />
        <input type="file" name="test_pic[]" />
        <input type="file" name="test_pic[]" />
        <input type="file" name="test_pic[]" />
        <input type="submit" value="上传" />
    </form>
    </body>
    </html>

后端实现multiple_upload2.php

    <?php
    /**
     * created by phpstorm.
     * date: 2018/11/11
     * time: 15:12
     */

    $key = 'test_pic';
    $mimewhitelist = ['image/jpeg', 'image/png', 'image/gif'];
    $extwhitelist = ['jpeg', 'jpg', 'png', 'gif'];
    $allowsize = 2*1024*1024;
    $destdir = './uploads';

    // 接收和处理$_files
    if (!empty($_files[$key])) {
        $files = [];
        foreach($_files[$key]['name'] as $k => $v) {
            $files[$k]['name'] = $v;
            $files[$k]['type'] = $_files[$key]['type'][$k];
            $files[$k]['tmp_name'] = $_files[$key]['tmp_name'][$k];
            $files[$k]['error'] = $_files[$key]['error'][$k];
            $files[$k]['size'] = $_files[$key]['size'][$k];
        }
    }

    $errors = [];
    foreach($files as $file) {
        // name type error size
        $name = $file['name']; // 源文件名称
        $type = $file['type']; // mime 类型
        $tmpname = $file['tmp_name']; // 临时文件名称
        $error = $file['error']; // 错误信息
        $size = $file['size']; // 文件大小 字节

        // 处理错误
        // 0 - 无错误
        if ($error > upload_err_ok) {
            switch($error) {
                // 1 - 文件大小超出了php.ini当中的upload_max_filesize的大小
                case upload_err_ini_size:
                    $errors[$key] = $name . '文件大小超出了php.ini当中的upload_max_filesize的大小';
                    continue 2;
                // 2 - 超出表单当中的max_file_size的大小
                case upload_err_form_size:
                    $errors[$key] =  $name . '超出表单当中的max_file_size的大小';
                    continue 2;
                // 3 - 部分文件被上传
                case upload_err_partial:
                    $errors[$key] = $name . '部分文件被上传';
                    continue 2;
                // 4 - 没有文件被上传
                case upload_err_no_file:
                    $errors[$key] = $name . '没有文件被上传';
                    continue 2;
                // 6 - 临时目录不存在
                case upload_err_no_tmp_dir:
                    $errors[$key] = $name . '临时目录不存在';
                    continue 2;
                // 7 - 磁盘写入失败
                case upload_err_cant_write:
                    $errors[$key] = $name . '磁盘写入失败';
                    continue 2;
                // 8 - 文件上传被php扩展阻止
                case upload_err_extension:
                    $errors[$key] = $name . '文件上传被php扩展阻止';
                    continue 2;
                default:
                    $errors[$key] = $name . '未知错误';
                    continue 2;
            }
        }

        // 限制mime类型
        if (!in_array($type, $mimewhitelist)) {
            $errors[$key] = '文件类型' . $type . '不被允许!';
            continue;
        }

        // 限制扩展名
        $ext = pathinfo($name, pathinfo_extension);
        if (!in_array($ext, $extwhitelist)) {
            $errors[$key] = '文件扩展名' . $ext . '不被允许!';
            continue;
        }

        // 限制文件大小
        if ($size > $allowsize) {
            $errors[$key] = '文件大小 ' . $size . ' 超出限定大小 ' . $allowsize . ' !';
            continue;
        }

        // 生成随机文件名称
        $filename = uniqid() . '.' . $ext;

        // 移动文件
        if (!file_exists($destdir)) {
            mkdir($destdir, 0777, true);
        }
        if (!is_uploaded_file($tmpname) || !move_uploaded_file($tmpname, $destdir . '/' . $filename)) {
            $errors[$key] = "很抱歉,文件上传失败";
            continue;
        }
    }

    if (count($errors) > 0) {
        var_dump($errors);
    } else {
        echo "文件全部上传成功";
    }

文件上传类封装 uploadfile.php
支持多文件或者单文件

    <?php
/**
* created by phpstorm.
* date: 2018/11/11
* time: 22:01
*/
class uploadfile
{
/**
*
*/
const upload_error = [
upload_err_ini_size => '文件大小超出了php.ini当中的upload_max_filesize的值',
upload_err_form_size => '文件大小超出了max_file_size的值',
upload_err_partial => '文件只有部分被上传',
upload_err_no_file => '没有文件被上传',
upload_err_no_tmp_dir => '找不到临时目录',
upload_err_cant_write => '写入磁盘失败',
upload_err_extension => '文件上传被扩展阻止',
];
/**
* @var
*/
protected $field_name;
/**
* @var string
*/
protected $destination_dir;
/**
* @var array
*/
protected $allow_mime;
/**
* @var array
*/
protected $allow_ext;
/**
* @var
*/
protected $file_org_name;
/**
* @var
*/
protected $file_type;
/**
* @var
*/
protected $file_tmp_name;
/**
* @var
*/
protected $file_error;
/**
* @var
*/
protected $file_size;
/**
* @var array
*/
protected $errors;
/**
* @var
*/
protected $extension;
/**
* @var
*/
protected $file_new_name;
/**
* @var float|int
*/
protected $allow_size;
/**
* uploadfile constructor.
* @param $keyname
* @param string $destinationdir
* @param array $allowmime
* @param array $allowext
* @param float|int $allowsize
*/
public function __construct($keyname, $destinationdir = './uploads', $allowmime = ['image/jpeg', 'image/gif'], $allowext = ['gif', 'jpeg'], $allowsize = 2*1024*1024)
{
$this->field_name = $keyname;
$this->destination_dir = $destinationdir;
$this->allow_mime = $allowmime;
$this->allow_ext = $allowext;
$this->allow_size = $allowsize;
}
/**
* @param $destinationdir
*/
public function setdestinationdir($destinationdir)
{
$this->destination_dir = $destinationdir;
}
/**
* @param $allowmime
*/
public function setallowmime($allowmime)
{
$this->allow_mime = $allowmime;
}
/**
* @param $allowext
*/
public function setallowext($allowext)
{
$this->allow_ext = $allowext;
}
/**
* @param $allowsize
*/
public function setallowsize($allowsize)
{
$this->allow_size = $allowsize;
}
/**
* @return bool
*/
public function upload()
{
// 判断是否为多文件上传
$files = [];
if (is_array($_files[$this->field_name]['name'])) {
foreach($_files[$this->field_name]['name'] as $k => $v) {
$files[$k]['name'] = $v;
$files[$k]['type'] = $_files[$this->field_name]['type'][$k];
$files[$k]['tmp_name'] = $_files[$this->field_name]['tmp_name'][$k];
$files[$k]['error'] = $_files[$this->field_name]['error'][$k];
$files[$k]['size'] = $_files[$this->field_name]['size'][$k];
}
} else {
$files[] = $_files[$this->field_name];
}
foreach($files as $key => $file) {
// 接收$_files参数
$this->setfileinfo($key, $file);
// 检查错误
$this->checkerror($key);
// 检查mime类型
$this->checkmime($key);
// 检查扩展名
$this->checkext($key);
// 检查文件大小
$this->checksize($key);
// 生成新的文件名称
$this->generatenewname($key);
if (count((array)$this->geterror($key)) > 0) {
continue;
}
// 移动文件
$this->movefile($key);
}
if (count((array)$this->errors) > 0) {
return false;
}
return true;
}
/**
* @return array
*/
public function geterrors()
{
return $this->errors;
}
/**
* @param $key
* @return mixed
*/
protected function geterror($key)
{
return $this->errors[$key];
}
/**
*
*/
protected function setfileinfo($key, $file)
{
// $_files  name type temp_name error size
$this->file_org_name[$key] = $file['name'];
$this->file_type[$key] = $file['type'];
$this->file_tmp_name[$key] = $file['tmp_name'];
$this->file_error[$key] = $file['error'];
$this->file_size[$key] = $file['size'];
}
/**
* @param $key
* @param $error
*/
protected function seterror($key, $error)
{
$this->errors[$key][] = $error;
}
/**
* @param $key
* @return bool
*/
protected function checkerror($key)
{
if ($this->file_error > upload_err_ok) {
switch($this->file_error) {
case upload_err_ini_size:
case upload_err_form_size:
case upload_err_partial:
case upload_err_no_file:
case upload_err_no_tmp_dir:
case upload_err_cant_write:
case upload_err_extension:
$this->seterror($key, self::upload_error[$this->file_error]);
return false;
}
}
return true;
}
/**
* @param $key
* @return bool
*/
protected function checkmime($key)
{
if (!in_array($this->file_type[$key], $this->allow_mime)) {
$this->seterror($key, '文件类型' . $this->file_type[$key] . '不被允许!');
return false;
}
return true;
}
/**
* @param $key
* @return bool
*/
protected function checkext($key)
{
$this->extension[$key] = pathinfo($this->file_org_name[$key], pathinfo_extension);
if (!in_array($this->extension[$key], $this->allow_ext)) {
$this->seterror($key, '文件扩展名' . $this->extension[$key] . '不被允许!');
return false;
}
return true;
}
/**
* @return bool
*/
protected function checksize($key)
{
if ($this->file_size[$key] > $this->allow_size) {
$this->seterror($key, '文件大小' . $this->file_size[$key] . '超出了限定大小' . $this->allow_size);
return false;
}
return true;
}
/**
* @param $key
*/
protected function generatenewname($key)
{
$this->file_new_name[$key] = uniqid() . '.' . $this->extension[$key];
}
/**
* @param $key
* @return bool
*/
protected function movefile($key)
{
if (!file_exists($this->destination_dir)) {
mkdir($this->destination_dir, 0777, true);
}
$newname = rtrim($this->destination_dir, '/') . '/' . $this->file_new_name[$key];
if (is_uploaded_file($this->file_tmp_name[$key]) && move_uploaded_file($this->file_tmp_name[$key], $newname)) {
return true;
}
$this->seterror($key, '上传失败!');
return false;
}
/**
* @return mixed
*/
public function getfilename()
{
return $this->file_new_name;
}
/**
* @return string
*/
public function getdestinationdir()
{
return $this->destination_dir;
}
/**
* @return mixed
*/
public function getextension()
{
return $this->extension;
}
/**
* @return mixed
*/
public function getfilesize()
{
return $this->file_size;
}
}

前端页面演示

    <!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>test upload class</title>
</head>
<body>
<form action="testuploadfile.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="max_file_size" value="10240000" />
<input type="file" name="test_pic[]" multiple="multiple"/>
<input type="submit" value="上传" />
</form>
</body>
</html>

后端配置演示testuploadfile.php 

    <?php
/**
* created by phpstorm.
* date: 2018/11/11
* time: 22:46
*/
require('uploadfile.php');
$upload = new uploadfile('test_pic');
$upload->setdestinationdir('./uploads');
$upload->setallowmime(['image/jpeg', 'image/gif']);
$upload->setallowext(['gif', 'jpeg']);
$upload->setallowsize(2*1024*1024);
if ($upload->upload()) {
var_dump($upload->getfilename());
var_dump($upload->getdestinationdir());
var_dump($upload->getextension());
var_dump($upload->getfilesize());
} else {
var_dump($upload->geterrors());
}
文件下载
<?php
/**
* created by phpstorm.
* date: 2018/11/12
* time: 00:07
*/
//演示
//echo '<a href="./uploads/test.jpg">下载图片</a>';
// download.php?file=5be822d84c42a.jpeg
// 接收get参数
if (!isset($_get['file'])) {
exit('需要传递文件名称');
}
if (empty($_get['file'])) {
exit('请传递文件名称');
}
// 获取远程文件地址
$file = './uploads/' . $_get['file'];
if (!file_exists($file)) {
exit('文件不存在');
}
if (!is_file($file)) {
exit('文件不存在');
}
if (!is_readable($file)) {
exit('文件不可读');
}
// 清空缓冲区
ob_clean();
// 打开文件 rb
$file_handle = fopen($file, 'rb');
if (!$file_handle) {
exit('打开文件失败');
}
// 通知浏览器
header('content-type: application/octet-stream; charset=utf-8');
header('content-transfer-encoding: binary');
header('content-length: ' . filesize($file));
header('content-disposition: attachment; filename="' . urlencode(basename($file)) . '"');
// 读取并输出文件
while(!feof($file_handle)) {
echo fread($file_handle, 10240);
}
// 关闭文档流
fclose($file_handle);