前言
今天在公司无事,就搞了下文件上传的东东,方便自己的学习,和今后的使用,目前只支持单文件上传。下面是代码部分,也可以访问我的 Gitee 或 Github,不想看代码的童鞋可以直接[下载]。。。(算了,讨厌百度云,如果有需要的话留言)代码使用,使用方法请点击
代码
<?php
namespace E;
class FileUpload
{
/**
* @var $name 上传文件标记名
*/
protected $name = 'file';
/**
* @var $ext 所允许的扩展名
*/
protected $exts = [];
/**
* @var $file 上传的文件资源
*/
protected $file = null;
/**
* @var $upload_success 是否上传成功标志
*/
protected $upload_success = false;
/**
* @var $max_size 上传文件所允许的大小,单位为 M
*/
protected $max_size = 2;
/**
* @var $error_code 错误码
*/
protected $error_code = 0;
/**
* @var $error_msg 错误信息
*/
protected $error_msg = '';
/**
* @var $file_ext 文件扩展名
*/
protected $file_ext = '';
/**
* @var $type 文件类型,默认为任意类型
*/
protected $type = 'file';
protected const ERR_OK = 0;
protected const ERR_FILE_SIZE = 1;
protected const ERR_FORM_SIZE = 2;
protected const ERR_PARTIAL = 3;
protected const ERR_NO_FILE = 4;
protected const ERR_FILE_EXIST = 5;
protected const ERR_NO_TMP_DIR = 6;
protected const ERR_CANT_WRITE = 7;
protected const ERR_FILE_TYPE = 8;
/**
* 配置上传信息
*
* @param array $arr
* @return EFileUpload
*/
public function config($arr)
{
foreach ($arr as $key => $val) {
if (property_exists($this, $key)) {
$this->$key = $val;
}
}
return $this;
}
/**
* 进行文件上传操作
*
* @return EFileUpload
*/
public function upload()
{
$this->file = $this->getFile();
$this->file_ext = strrchr($this->file['name'], '.');
$this->upload_success = !($this->uploadError() || $this->overMaxSize() || $this->notAllowType());
return $this;
}
/**
* 判断文件是否上传成功
*
* @return boolean
*/
public function uploadSuccess()
{
return $this->upload_success;
}
/**
* 保存已上传的文件
*
* @param string $path
* @param string $file_name
*
* @return boolean
*/
public function save($path, $file_name = '')
{
if (!$this->uploadSuccess()) {
return false;
}
// 判断文件夹是否存在,如果不存在,新建一个文件夹
if (!is_dir($path)) {
mkdir($path);
}
// 获取文件名,不包含后缀
$file_name = $file_name ?: 'e_' . time() . mt_rand(10000, 99999);
$file = rtrim($path, '/') . '/' . $file_name . $this->file_ext;
// 判断文件是否存在
if (file_exists($file)) {
$this->error_code = self::ERR_FILE_EXIST;
return false;
}
if (move_uploaded_file($this->file['tmp_name'], $file)) {
return true;
}
// 文件未上传成功,出现未知错误
$this->error_code = -1;
return false;
}
/**
* 返回错误码
*
* @return integer
*/
public function errorCode()
{
return $this->error_code;
}
/**
* 返回错误信息
*
* @return string
*/
public function errorMsg()
{
!$this->error_msg && $this->setErrorMsgByCode($this->error_code);
return $this->error_msg;
}
/**
* 获取上传文件
*
* @return mixed
*/
protected function getFile()
{
return $_FILES[$this->name];
}
/**
* 判断是否上传错误
*
* @return boolean
*/
protected function uploadError()
{
$this->error_code = $this->file['error'];
return (bool)$this->file['error'];
}
/**
* 根据错误代码设置错误信息
*
* @param int $code
*/
protected function setErrorMsgByCode($code)
{
$msg_arr = [
'',
'上传文件最大为 ' . $this->getMaxSize() . 'M',
'上传文件过大',
'文件只有部分被上传',
'没有文件被上传',
'文件已存在',
'文件丢失',
'文件写入失败',
'只能上传' . implode(',', $this->exts) . '类型的文件'
];
$this->error_msg = $msg_arr[$code] ?? '未知错误';
}
/**
* 获取上传文件所限制的最大大小
*
* @return int
*/
protected function getMaxSize()
{
return min($this->max_size, (int)ini_get('upload_max_filesize'));
}
/**
* 判断文件是否超出限制大小
*
* @return boolean
*/
protected function overMaxSize()
{
if ($this->file['size'] > $this->getMaxSize() * 1024 * 1024 * 8) {
$this->error_code = self::ERR_FILE_SIZE;
return true;
}
return false;
}
/**
* 通过类型获取后缀名数组
*
* @return array
*/
protected function getExtsByType()
{
$exts_arr = [
'image' => ['jpg', 'jpeg', 'png', 'gif'],
'file' => [],
'zip' => ['zip', 'rar', '7z']
];
return $exts_arr[$this->type] ?? [];
}
/**
* 判断是否是允许的类型
*
* @return boolean
*/
protected function notAllowType()
{
$this->exts = $this->exts ?: $this->getExtsByType();
if (!$this->exts) return false;
if (preg_match('/^.' . implode('|', $this->exts) . '$/i', $this->file_ext)) {
return false;
}
$this->error_code = self::ERR_FILE_TYPE;
return true;
}
}
使用方法
- 引入文件
include 'FileUpload.class.php';
- 实例化类
$uploader = new EFileUpload();
- 配置
$uploader->config([
'name' => 'file',
'exts' => ['jpg'],
'type' => 'image',
'max_size' => 2,
]);
配置项的说明:
配置项 | 说明 |
---|---|
name | 是 HTML 中 input 的 name,例如: <input type="file" name="file">,默认是 file |
exts | 所允许上传的文件扩展名,类型为数组,默认是任何类型的文件 |
type | 上传文件类型,可以通过设置 type 属性,设置允许上传类型,默认为 file,目前可选类型有:file 全部文件类型,image 图片类型, zip 压缩包,注意:exts优先级高于 type,即如果设置了 type 为 file,exts 为 ['jpg'] 时,也还是只能上传 jpg 类型的文件的 |
max_size | 所允许上传的大小,单位为 M,默认为 2M |
- 上传
$uploader->upload();
- 保存
$uploader->save('./uploads/', 'test')
save 方法的返回值是一个布尔值,上传成功返回 true,失败返回 false,可以根据返回的状态进行相应的操作,如果失败,可以使用 errorCode()
方法获取错误代码,使用 errorMsg()
方法获取错误信息。
save 方法的第一个参数为必填参数,是要保存的路径,第二个参数是文件名,可选,如果不填,则会自动生成,生成规则: e_ 连接上当前时间的时间戳再连接5位随机数
也可以使用链式操作:
$uploader->upload()->save('./uploads/', 'test');
错误码说明
错误码 | 说明 |
---|---|
0 | 无错误 |
1 | 上传文件超出限制大小 |
2 | 上传文件超出 form 表单所设置的 MAX_FILE_SIZE,也是文件过大 |
3 | 文件只有部分被上传 |
4 | 没有文件被上传 |
5 | 存在同名文件 |
6 | 文件丢失 |
7 | 文件写入失败 |
8 | 上传的文件类型不被允许 |
-1 | 未知错误 |