首先前端表单的 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
);
}
}