namespace kucha\ueditor;

class Uploader

{

private $fileField; //文件域名

private $file; //文件上传对象

private $base64; //文件上传对象

private $config; //配置信息

private $oriName; //原始文件名

private $fileName; //新文件名

private $fullName; //完整文件名,即从当前配置目录开始的URL

private $filePath; //完整文件名,即从当前配置目录开始的URL

private $fileSize; //文件大小

private $fileType; //文件类型

private $stateInfo; //上传状态信息,

private $stateMap = array( //上传状态映射表,国际化用户需考虑此处数据的国际化

"SUCCESS", //上传成功标记,在UEditor中内不可改变,否则flash判断会出错

"文件大小超出 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_UNKNOWN" => "未知错误",

"ERROR_DEAD_LINK" => "链接不可用",

"ERROR_HTTP_LINK" => "链接不是http链接",

"ERROR_HTTP_CONTENTTYPE" => "链接contentType不正确"

);

/**

* 构造函数

* @param $fileField 表单名称

* @param $config 配置项

* @param string $type 是否解析base64编码,可省略。若开启,则$fileField代表的是base64编码的字符串表单名

*/

public function __construct($fileField, $config, $type = "upload")

{

$this->fileField = $fileField;

$this->config = $config;

$this->type = $type;

if ($type == "remote") {

$this->saveRemote();

} else if ($type == "base64") {

$this->upBase64();

} else {

$this->upFile();

}

// $this->stateMap['ERROR_TYPE_NOT_ALLOWED'] = iconv('unicode', 'utf-8', $this->stateMap['ERROR_TYPE_NOT_ALLOWED']);

}

/**

* 上传文件的主处理方法

* @return mixed

*/

private function upFile()

{

$file = $this->file = $_FILES[$this->fileField];

if (!$file) {

$this->stateInfo = $this->getStateInfo("ERROR_FILE_NOT_FOUND");

return;

}

if ($this->file['error']) {

$this->stateInfo = $this->getStateInfo($file['error']);

return;

} else if (!file_exists($file['tmp_name'])) {

$this->stateInfo = $this->getStateInfo("ERROR_TMP_FILE_NOT_FOUND");

return;

} else if (!is_uploaded_file($file['tmp_name'])) {

$this->stateInfo = $this->getStateInfo("ERROR_TMPFILE");

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->stateInfo = $this->getStateInfo("ERROR_SIZE_EXCEED");

return;

}

//检查是否不允许的文件格式

if (!$this->checkType()) {

$this->stateInfo = $this->getStateInfo("ERROR_TYPE_NOT_ALLOWED");

return;

}

//创建目录失败

if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {

$this->stateInfo = $this->getStateInfo("ERROR_CREATE_DIR");

return;

} else if (!is_writeable($dirname)) {

$this->stateInfo = $this->getStateInfo("ERROR_DIR_NOT_WRITEABLE");

return;

}

//移动文件

if (!(move_uploaded_file($file["tmp_name"], $this->filePath) && file_exists($this->filePath))) { //移动失败

$this->stateInfo = $this->getStateInfo("ERROR_FILE_MOVE");

} else { //移动成功

$this->stateInfo = $this->stateMap[0];

}

}

/**

* 处理base64编码的图片上传

* @return mixed

*/

private function upBase64()

{

$base64Data = $_POST[$this->fileField];

$img = base64_decode($base64Data);

$this->oriName = $this->config['oriName'];

$this->fileSize = strlen($img);

$this->fileType = $this->getFileExt();

$this->fullName = $this->getFullName();

$this->filePath = $this->getFilePath();

$this->fileName = $this->getFileName();

$dirname = dirname($this->filePath);

//检查文件大小是否超出限制

if (!$this->checkSize()) {

$this->stateInfo = $this->getStateInfo("ERROR_SIZE_EXCEED");

return;

}

//创建目录失败

if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {

$this->stateInfo = $this->getStateInfo("ERROR_CREATE_DIR");

return;

} else if (!is_writeable($dirname)) {

$this->stateInfo = $this->getStateInfo("ERROR_DIR_NOT_WRITEABLE");

return;

}

//移动文件

if (!(file_put_contents($this->filePath, $img) && file_exists($this->filePath))) { //移动失败

$this->stateInfo = $this->getStateInfo("ERROR_WRITE_CONTENT");

} else { //移动成功

$this->stateInfo = $this->stateMap[0];

}

}

/**

* 拉取远程图片

* @return mixed

*/

private function saveRemote()

{

$imgUrl = htmlspecialchars($this->fileField);

$imgUrl = str_replace("&", "&", $imgUrl);

//http开头验证

if (strpos($imgUrl, "http") !== 0) {

$this->stateInfo = $this->getStateInfo("ERROR_HTTP_LINK");

return;

}

//获取请求头并检测死链

$heads = get_headers($imgUrl, 1);

if (!(stristr($heads[0], "200") && stristr($heads[0], "OK"))) {

$this->stateInfo = $this->getStateInfo("ERROR_DEAD_LINK");

return;

}

//格式验证(扩展名验证和Content-Type验证)

$fileType = strtolower(strrchr($imgUrl, '.'));

if (!in_array($fileType, $this->config['allowFiles']) || stristr($heads['Content-Type'], "image")) {

$this->stateInfo = $this->getStateInfo("ERROR_HTTP_CONTENTTYPE");

return;

}

//打开输出缓冲区并获取远程图片

ob_start();

$context = stream_context_create(

array('http' => array(

'follow_location' => false // don't follow redirects

))

);

readfile($imgUrl, false, $context);

$img = ob_get_contents();

ob_end_clean();

preg_match("/[\/]([^\/]*)[\.]?[^\.\/]*$/", $imgUrl, $m);

$this->oriName = $m ? $m[1] : "";

$this->fileSize = strlen($img);

$this->fileType = $this->getFileExt();

$this->fullName = $this->getFullName();

$this->filePath = $this->getFilePath();

$this->fileName = $this->getFileName();

$dirname = dirname($this->filePath);

//检查文件大小是否超出限制

if (!$this->checkSize()) {

$this->stateInfo = $this->getStateInfo("ERROR_SIZE_EXCEED");

return;

}

//创建目录失败

if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {

$this->stateInfo = $this->getStateInfo("ERROR_CREATE_DIR");

return;

} else if (!is_writeable($dirname)) {

$this->stateInfo = $this->getStateInfo("ERROR_DIR_NOT_WRITEABLE");

return;

}

//移动文件

if (!(file_put_contents($this->filePath, $img) && file_exists($this->filePath))) { //移动失败

$this->stateInfo = $this->getStateInfo("ERROR_WRITE_CONTENT");

} else { //移动成功

$this->stateInfo = $this->stateMap[0];

}

}

/**

* 上传错误检查

* @param $errCode

* @return string

*/

private function getStateInfo($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()

{

//替换日期事件

$t = time();

$d = explode('-', date("Y-y-m-d-H-i-s"));

$format = $this->config["pathFormat"];

$format = str_replace("{yyyy}", $d[0], $format);

$format = str_replace("{yy}", $d[1], $format);

$format = str_replace("{mm}", $d[2], $format);

$format = str_replace("{dd}", $d[3], $format);

$format = str_replace("{hh}", $d[4], $format);

$format = str_replace("{ii}", $d[5], $format);

$format = str_replace("{ss}", $d[6], $format);

$format = str_replace("{time}", $t, $format);

//过滤文件名的非法自负,并替换文件名

$oriName = substr($this->oriName, 0, strrpos($this->oriName, '.'));

$oriName = preg_replace("/[\|\?\"\\/\*\\\\]+/", '', $oriName);

$format = str_replace("{filename}", $oriName, $format);

//替换随机字符串

$randNum = mt_rand(1, 1000000000) . mt_rand(1, 1000000000);

if (preg_match("/\{rand\:([\d]*)\}/i", $format, $matches)) {

$format = preg_replace("/\{rand\:[\d]*\}/i", substr($randNum, 0, $matches[1]), $format);

}

$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;

if (substr($fullname, 0, 1) != '/') {

$fullname = '/' . $fullname;

}

return $this->config['pathRoot'] . $fullname;

}

/**

* 文件类型检测

* @return bool

*/

private function checkType()

{

return in_array($this->getFileExt(), $this->config["allowFiles"]);

}

/**

* 文件大小检测

* @return bool

*/

private function checkSize()

{

return $this->fileSize <= ($this->config["maxSize"]);

}

/**

* 获取当前上传成功文件的各项信息

* @return array

*/

public function getFileInfo()

{

return array(

"state" => $this->stateInfo,

"url" => $this->fullName,

"title" => $this->fileName,

"original" => $this->oriName,

"type" => $this->fileType,

"size" => $this->fileSize

);

}

}

一键复制

编辑

Web IDE

原始数据

按行查看

历史

uploader.php,Uploader.php相关推荐

  1. webbrowser实现input tab事件_如何合理构造一个Uploader工具类(设计到实现)

    作者:Chaser (本文来自作者投稿) 原文地址:https://juejin.im/post/5e5badce51882549652d55c2 源码地址:https://github.com/im ...

  2. 实现option上下移动_ES6原生实战Uploader工具类(从设计到实现)

    前言 本文将带你基于ES6的面向对象,脱离框架使用原生JS,从设计到代码实现一个Uploader基础类,再到实际投入使用.通过本文,你可以了解到一般情况下根据需求是如何合理构造出一个工具类lib. 需 ...

  3. uploader上传

    综述 Uploader是非常强大的异步文件上传组件,支持ajax.iframe.flash三套方案,实现浏览器的全兼容,调用非常简单,内置多套主题支持和常用插件,比如验证.图片预览.进度条等. 广泛应 ...

  4. 百度上传插件 Web Uploader 使用之单图片上传

    java springmvc 使用Web Uploader 上传单张图片 今天小组长让我完成一个图片上传的功能,并丢给了我一个百度上传的插件 WebUpload .由于是第一次使用该插件,所以先在本地 ...

  5. jQuery-WEUI(jqweui)的Uploader图片上传方法2.0

    之前写了一篇关于用jqweui.cn库中的文件上传(uploader)+图片预览(Gallery)组合实现图片上传的方法,不过只能实现简单的将待上传图片插入到待上传图片预览列表和实现预览.删除功能.但 ...

  6. uploader.lib php,Fine Uploader文件上传组件应用介绍

    最近在处理后台数据时需要实现文件上传.考虑到对浏览器适配上采用Fine Uploader. Fine Uploader 采用ajax方式实现对文件上传.同时在浏览器中直接支持文件拖拽[对浏览器版本有要 ...

  7. Mvc Kissy uploader实现图片批量上传 附带瀑布流的照片墙

    前言 KISSY  是由阿里集团前端工程师们发起创建的一个开源 JS 框架.它具备模块化.高扩展性.组件齐全,接口一致.自主开发.适合多种应用场景等特性.本人在一次项目中层使用这个uploader组件 ...

  8. php webuploader大文件,web uploader 上传大文件总结

    由于业务需要,需要上传大文件,已有的版本无法处理IE版本,经过调研,百度的 webuploader 支持 IE 浏览器,而且支持计算MD5值,进而可以实现秒传的功能. 大文件上传主要分为三部分,预上传 ...

  9. JQ_Web Uploader图片上传控件

    2019独角兽企业重金招聘Python工程师标准>>> HTML <div id="uploader">     <div id="j ...

  10. ssm 上传图片到mysql_ssm(Spring+Spring MVC+MyBatis)+Web Uploader开发图片文件上传实例,支持批量上传,拖拽上传,复制粘贴上传...

    项目描述 ssm开发一个上传图片的项目 用百度的插件 Web Uploader 上传,不会的去它的官网找API文档 官网的API文档还是比较 坑的.... 百度插件  Web Uploader 上传文 ...

最新文章

  1. 1002: A+B for Input-Output Practice (II)
  2. mysql数据库主从配置
  3. Windows——Modern Standby(现代待机) S0改Suspend to RAM(待机到内存)S3睡眠解决方案(以机械革命F1 i5-11300H为例)
  4. BZOJ1010 [HNOI2008]玩具装箱toy 动态规划 斜率优化
  5. 玩转mini2440开发板之【在64位WIN7/WIN10系统中安装USB驱动】
  6. java 数组 反射_【译】10. Java反射——数组
  7. 企业文件服务器(samba)配置案例一
  8. 90%做tiktok运营都存在的误区?
  9. 图片服务器 文件系统,调研分享:图片文件在各文件系统上的访问性能对比
  10. selenium 简介 及浏览器配置
  11. java课程讲解,Java基础教程详解:多线程(1)-----多线程概念
  12. 警惕!这5种“脸色”在暗示你这些健康问题!
  13. (一)Redis实战教程之redis简介
  14. php读取与写入文件(详解)
  15. 第二十三天 小丁再战链表
  16. 电阻电路的等效变化(Ⅰ)
  17. 基于JAVA的工资管理系统计算机毕业设计源码+数据库+lw文档+系统+部署
  18. python爬虫之创建表格
  19. 不用深度学习网络,只需预先设置NAS算法,就能实现AutoML自动机器学习的革命吗?
  20. 文件格式转换DOS到UNIX:dos2unix+UltraEdit(解决no such file or directory问题)

热门文章

  1. 如何做二维码批量又快速
  2. 10个互联网兼职平台,让你的一技之长变现,副业薪资比日常搬砖高也太爽了
  3. 关于电源线 USB台灯3C认证相关介绍
  4. AE剪辑快捷键有哪些?这波快捷键分享拿好了
  5. Chrome快捷键整理
  6. 悦读 | 人生十论. 钱穆
  7. java jersey 搭建_Jersey搭建Rest web服务
  8. html中怎样变英文月份,英语月份的巧记方法
  9. 万能五笔输入法弹窗_万能五笔输入法的广告怎么关闭
  10. EMC VMAX存储的内存布局