PHP 文件上传

首先前端表单的 method 必须是 post 其次 enctype=“multipart/form-data” 这个属性必须有

后端接收上传文件数据 $_FILES

对 $_FILES 的处理 与前端 input type=file 的命名有关
例如:

<input type="file" class="form-control" name="file1">
<input type="file" class="form-control" name="file2">

后端打印$_FILES:

Array
(
    [file1] => Array
        (
            [name] => 1.jpg
            [type] => image/jpeg
            [tmp_name] => C:\Users\Administrator\AppData\Local\Temp\phpF27F.tmp
            [error] => 0
            [size] => 1419239
        )
    [file2] => Array
        (
            [name] => 2.jpg
            [type] => image/jpeg
            [tmp_name] => C:\Users\Administrator\AppData\Local\Temp\phpF2A0.tmp
            [error] => 0
            [size] => 1155138
        )
)

例:

<input type="file" class="form-control" name="file[]" multiple="multiple">

打印结果:

Array
(
    [file] => Array
        (
            [name] => Array
                (
                    [0] => 1.jpg
                    [1] => 2.jpg
                )
            [type] => Array
                (
                    [0] => image/jpeg
                    [1] => image/jpeg
                )
            [tmp_name] => Array
                (
                    [0] => C:\Users\Administrator\AppData\Local\Temp\php7775.tmp
                    [1] => C:\Users\Administrator\AppData\Local\Temp\php77A5.tmp
                )
            [error] => Array
                (
                    [0] => 0
                    [1] => 0
                )
            [size] => Array
                (
                    [0] => 1419239
                    [1] => 1155138
                )
        )
)

因此, 针对第二种 ,需要对 $_FILES[‘file’] 做数据格式的转换

$temp = [];
foreach( $_FILES['file'] as $key => $val )
{
	foreach( $val as $k=>$v )
	{
		$temp[$k][$key] = $v;
	}
}

打印一下 $temp

Array
(
    [0] => Array
        (
            [name] => 1.jpg
            [type] => image/jpeg
            [tmp_name] => C:\Users\Administrator\AppData\Local\Temp\php33E2.tmp
            [error] => 0
            [size] => 1419239
        )
    [1] => Array
        (
            [name] => 2.jpg
            [type] => image/jpeg
            [tmp_name] => C:\Users\Administrator\AppData\Local\Temp\php33F3.tmp
            [error] => 0
            [size] => 1155138
        )
)
接下来是上传操作
  • 检查错误 error 字段 错误信息如下:
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,找不到临时文件夹。
UPLOAD_ERR_CANT_WRITE  //其值为 7,文件写入失败。
  • 判断文件大小是否超过限制 ( 自定义的上传文件大小 )
  • 判断是否为合法文件 ( 允许上传的文件类型 )
  • 检查上传目录
  • 重命名文件
  • 移动文件
    大致步骤如上

下面是自己写的一个上传类 比较简单 支持单文件和多文件上传
先贴用法:

$load = new Uploader;// new Uploader(['maxSize' =>2048000 ,'allowFiles' => ['.jpg' ,'.png']]);
$result = $load->file('file');//file 上传文件的表单名称
var_dump($result);//返回结果集
<?php
/**
 * Date: 18-11-21
 * Time: am 0: 38
 * 文件上传
 */
class Uploader
{
    private $maxSize = 1024000;// 允许上传的文件最大size 1M 自行修改
    private $allowFiles = array('.png' ,'.jpg' ,'.jpeg' ,'.gif');//允许上传的文件类型 自行修改
    private $file; //文件上传对象
    private $config; //配置信息
    private $oriName; //原始文件名
    private $fileName; //新文件名
    private $path = '/uploads'; //保存路径,从根目录开始
    private $fullName; //完整文件名,即从根目录开始的URL
    private $filePath; //完整文件名,从盘符开始
    private $fileSize; //文件大小
    private $fileType; //文件类型
    private $state; //上传状态信息,
    private $stateMap = array(
        "SUCCESS", //上传成功标记
        "文件大小超出 upload_max_filesize 限制",
        "文件大小超出 MAX_FILE_SIZE 限制",
        "文件未被完整上传",
        "没有文件被上传",
        "上传文件为空",
        "ERROR_TMP_FILE" => "临时文件错误",
        "ERROR_TMP_FILE_NOT_FOUND" => "找不到临时文件",
        "ERROR_SIZE_EXCEED" => "文件大小超出网站限制",
        "ERROR_TYPE_NOT_ALLOWED" => "文件类型不允许",
        "ERROR_CREATE_DIR" => "目录创建失败",
        "ERROR_DIR_NOT_WRITEABLE" => "目录没有写权限",
        "ERROR_FILE_MOVE" => "文件保存时出错",
        "ERROR_FILE_NOT_FOUND" => "找不到上传文件",
        "ERROR_WRITE_CONTENT" => "写入文件内容错误",
        "ERROR_FILE_NOT_SAFE" => "非法上传的文件",
        "ERROR_UNKNOWN" => "未知错误",
    );

	//若无需要,构造函数可以省略
    function __construct($config = array())
    {
    	if( !empty($config) )
        {
            if( isset($config['maxSize']) )
                $this->maxSize = $config['maxSize'];

            if( isset($config['allowFiles']) )
                $this->allowFiles = $config['allowFiles'];
        }
        
        $this->path = rtrim($this->path ,'/') . '/';
    }

    /**
     * 接收表单 ,并做上传处理
     * @return array
     */
    public function file ($fileField)
    {
        if( is_array($_FILES[$fileField]['name']) )//多文件
        {
            $files = $_FILES[$fileField];
            $temp = array();//空数组
            foreach ( $files as $key => $val) {
                foreach ($val as $k => $v) {
                    $temp[$k][$key] = $v;//格式转换
                }
            }

            $result = array();//接收上传结果
            foreach ($temp as $file) {
                $this->file = $file;
                $this->upFile();
                $result[] = $this->getFileInfo();
            }
            return $result;

        } else { //单文件
            $this->file = $_FILES[$fileField];
            $this->upFile();
            return $this->getFileInfo();
        }
    }

    /**
     * 上传文件的主处理方法
     * @return mixed
     */
    private function upFile()
    {
        $file = $this->file;
        if (!$file) {
            $this->state = $this->getErrInfo("ERROR_FILE_NOT_FOUND");
            return;
        }
        if ($this->file['error']) {
            $this->state = $this->getErrInfo($file['error']);
            return;
        } else if (!file_exists($file['tmp_name'])) {
            $this->state = $this->getErrInfo("ERROR_TMP_FILE_NOT_FOUND");
            return;
        } else if (!is_uploaded_file($file['tmp_name'])) {
            $this->state = $this->getErrInfo("ERROR_FILE_NOT_SAFE");
            return;
        }

        $this->oriName = $file['name'];
        $this->fileSize = $file['size'];
        $this->fileType = $this->getFileExt();
        $this->fullName = $this->getFullName();
        $this->filePath = $this->getFilePath();
        $this->fileName = $this->getFileName();
        $dirname = dirname($this->filePath);

        //检查文件大小是否超出限制
        if (!$this->checkSize()) {
            $this->state = $this->getErrInfo("ERROR_SIZE_EXCEED");
            return;
        }

        //检查是否不允许的文件格式
        if (!$this->checkType()) {
            $this->state = $this->getErrInfo("ERROR_TYPE_NOT_ALLOWED");
            return;
        }

        //创建目录失败
        if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
            $this->state = $this->getErrInfo("ERROR_CREATE_DIR");
            return;
        } else if (!is_writeable($dirname)) {
            $this->state = $this->getErrInfo("ERROR_DIR_NOT_WRITEABLE");
            return;
        }

        //移动文件
        if (!(move_uploaded_file($file["tmp_name"], $this->filePath) && file_exists($this->filePath))) { //移动失败
            $this->state = $this->getErrInfo("ERROR_FILE_MOVE");
        } else { //移动成功
            $this->state = $this->stateMap[0];
        }
    }

    /**
     * 上传错误检查
     * @param $errCode
     * @return string
     */
    private function getErrInfo($errCode)
    {
        return !$this->stateMap[$errCode] ? $this->stateMap["ERROR_UNKNOWN"] : $this->stateMap[$errCode];
    }

    /**
     * 获取文件扩展名
     * @return string
     */
    private function getFileExt()
    {
        return strtolower(strrchr($this->oriName, '.'));
    }

    /**
     * 重命名文件
     * @return string
     */
    private function getFullName()
    {
        //替换文件名
        $format = $this->path . md5( substr($this->oriName, 0, strrpos($this->oriName, '.')) );
        $ext = $this->getFileExt();
        return $format . $ext;
    }

    /**
     * 获取文件名
     * @return string
     */
    private function getFileName () {
        return substr($this->filePath, strrpos($this->filePath, '/') + 1);
    }

    /**
     * 获取文件完整路径
     * @return string
     */
    private function getFilePath()
    {
        $fullname = $this->fullName;
        $rootPath = $_SERVER['DOCUMENT_ROOT'];
        return $rootPath . $fullname;
    }

    /**
     * 文件类型检测
     * @return bool
     */
    private function checkType()
    {
        return in_array($this->getFileExt(), $this->allowFiles);
    }

    /**
     * 文件大小检测
     * @return bool
     */
    private function  checkSize()
    {
        return $this->fileSize <= ($this->maxSize);
    }

    /**
     * 获取当前上传成功文件的各项信息
     * @return array
     */
    private function getFileInfo()
    {
        return array(
            "state" => $this->state,
            "url" => $this->fullName,
            "title" => $this->fileName,
            "original" => $this->oriName,
            "type" => $this->fileType,
            "size" => $this->fileSize
        );
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值