一、前端代码

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>文件上传</title>
</head>
<body>
<form action="do.php" method="post" enctype="multipart/form-data">
<input type="file" name="file" value=""><br>
<input type="submit" value="上传文件"/><br>
</form>
</body>
</html>

二、php代码

<?php
/**
* Created by PhpStorm.
* User: Yang
* Date: 2019/8/13
* Time: 14:02
*/ include_once "./Upload.php"; $upload = new Upload();
if (!$upload->uploadFile("file")) {
echo $upload->errorInfo;
}

三、类库代码

<?php

/**
* Created by PhpStorm.
* User: Yang
* Date: 2019/8/13
* Time: 13:49
*/
class Upload
{
//文件上传路径
protected $path = 'upload/'; //允许文件上传的后缀
protected $allowSuffix = ['jpg', 'jpeg', 'gif', 'wbmp', 'png']; //mime类型
protected $allowMime = ['image/jpg', 'image/jpeg', 'image/gif', 'image/wbmp', 'image/png']; //允许上传的大小
protected $maxSize = 2 * 1024 * 1024; //是否启用默认的前缀
protected $isRandName = true; //文件的前缀
protected $prefix = 'up_'; //错误号和错误信息
protected $errorNumber;
protected $errorInfo; //文件的信息 //文件名
protected $oldName; //文件的后缀
protected $suffix; //文件的大小
protected $size; //文件的mime
protected $mime; //文件的临时文件的路径
protected $tmpName; //文件新名字
protected $newName; /**
* 构造方法
* Upload constructor.
* @param array $arr
*/
public function __construct($arr = [])
{
foreach ($arr as $key => $value) {
$this->setOption($key, $value);
}
} /**
* 判断$key是不是我的成员属性,如果是就设置
* @param $key
* @param $value
*/
protected function setOption($key, $value)
{
//得到所有的成员属性
$keys = array_keys(get_class_vars(__CLASS__));
if (in_array($key, $keys)) {
$this->$key = $value;
}
} /**
* 文件上传函数
* key 就是input框中的name属性值
* @param $key
* @return bool|string
*/
public function uploadFile($key)
{
//判断有没有设置路径 path
if (empty($this->path)) {
$this->setOption('errorNumber', -1);
return false;
}
//判断该路径是否存在是否可写
if (!$this->check()) {
$this->setOption('errorNumber', -2);
return false;
}
//判断$_FILES里面的error信息是否为0,如果为0则说明文件信息在服务器端可以直接获取,提取信息保存到成员属性中
$error = $_FILES[$key]['error'];
if ($error) {
$this->setOption('errorNumber', -3);
return false;
} else {
//提取文件相关信息并且保存到成员属性中
$this->getFileInfo($key);
}
//判断文件的大小、mime、后缀是否符合
if (!$this->checkSize() || !$this->checkMime() || !$this->checkSuffix()) {
return false;
}
//得到新的文件名字
$this->newName = $this->createNewName();
//判断是否是上传文件,并且是移动上传文件
if (is_uploaded_file($this->tmpName)) {
if (move_uploaded_file($this->tmpName, $this->path . $this->newName)) {
return $this->path . $this->newName;
} else {
$this->setOption('errorNumber', -7);
return false;
}
} else {
$this->setOption('errorNumber', -6);
return false;
}
} /**
* 检测文件夹是否存在,是否可写
* @return bool
*/
protected function check()
{
//文件夹不存在或者不是目录。创建文件夹
if (!file_exists($this->path) || !is_dir($this->path)) {
return mkdir($this->path, 0777, true);
}
//判断文件是否可写
if (!is_writeable($this->path)) {
return chmod($this->path, 0777);
}
return true;
} /**
* 根据key得到文件信息
* @param $key
*/
protected function getFileInfo($key)
{
//得到文件的名字
$this->oldName = $_FILES[$key]['name'];
//得到文件的mime类型
$this->mime = $_FILES[$key]['type'];
//得到文件的临时文件
$this->tmpName = $_FILES[$key]['tmp_name'];
//得到文件大小
$this->size = $_FILES[$key]['size'];
//得到文件后缀
$this->suffix = pathinfo($this->oldName)['extension'];
} /**
* 判断文件大小
* @return bool
*/
protected function checkSize()
{
if ($this->size > $this->maxSize) {
$this->setOption('errorNumber', -3);
return false;
}
return true;
} /**
* 判断mime类型
* @return bool
*/
protected function checkMime()
{
if (!in_array($this->mime, $this->allowMime)) {
$this->setOption('errorNumber', -4);
return false;
}
return true;
} /**
* 判断后缀
* @return bool
*/
protected function checkSuffix()
{
if (!in_array($this->suffix, $this->allowSuffix)) {
$this->setOption('errorNumber', -5);
return false;
}
return true;
} /**
* 创建新名字
* @return string
*/
protected function createNewName()
{
if ($this->isRandName) {
$name = $this->prefix . uniqid() . '.' . $this->suffix;
} else {
$name = $this->prefix . $this->oldName;
}
return $name;
} /**
* 读取不可访问属性的值时,__get() 会被调用。也就是,当想要获取一个类的私有属性,或者获取一个类并为定义的属性时。该魔术方法会被调用。
* @param $name
* @return string
*/
public function __get($name)
{
if ($name == 'errorNumber') {
return $this->errorNumber;
} elseif ($name == 'errorInfo') {
return $this->getErrorInfo();
}
} /**
* 获取错误信息
* @return string
*/
protected function getErrorInfo()
{
switch ($this->errorNumber) {
case -1:
$str = '文件路径没有设置';
break;
case -2:
$str = '文件不是目录或者不可写';
break;
case -3:
$str = '文件超过指定大小';
break;
case -4:
$str = 'mime类型不符合';
break;
case -5:
$str = '文件后缀不符合';
break;
case -6:
$str = '不是上传文件';
break;
case -7:
$str = '移动失败';
break;
case 1:
$str = '超出ini设置大小';
break;
case 2:
$str = '超出html表单大小';
break;
case 3:
$str = '文章只有部分上传';
break;
case 4:
$str = '没有文件上传';
break;
case 6:
$str = '找不到临时文件';
break;
case 7:
$str = '文件写入失败';
break;
}
return $str;
} }

PHP 之文件上传类封装的更多相关文章

  1. 自定义MVC框架之工具类-文件上传类

    截止目前已经改造了3个类: ubuntu:通过封装验证码类库一步步安装php的gd扩展 自定义MVC框架之工具类-分页类的封装 该文件上传类功能如下: 1,允许定制上传的文件类型,文件mime信息,文 ...

  2. ASP.NET 文件上传类 简单好用

    调用: UploadFile uf = new UploadFile(); /*可选参数*/ uf.SetIsUseOldFileName(true);//是否使用原始文件名作为新文件的文件名(默认: ...

  3. PHP 文件上传类

    FileUpload.;                $];                $_newname = date(,). :                             To ...

  4. php 文件上传类 实例分享

    最近在研究php上传的内容,找到一个不错的php上传类,分享下. <?php /** * 文件上传类 * class: uploadFile * edit: www.jbxue.com */ c ...

  5. [上传下载] C#FileUp文件上传类 (转载)

    点击下载 FileUp.zip 主要功能如下 .把上传的文件转换为字节数组 .流转化为字节数组 .上传文件根据FileUpload控件上传 .把Byte流上传到指定目录并保存为文件 看下面代码吧 // ...

  6. ThinkPHP文件上传类

    TP框架自带文件上传类使用: 类文件在ThinkPHP/Library/Think/默认在目录下 public function upload(){ $upload = new \Think\Uplo ...

  7. C#文件上传类,文件流,字节数组等

    using System;using System.IO;using System.Web;using System.Web.UI.WebControls; namespace DotNet.Util ...

  8. Php文件上传类class.upload.php

    简介 Class.upload.php是用于管理上传文件的php文件上传类, 它可以帮助你快速的给自己的网站集成上传文件功能.不仅如此,此分类还有一些列的处理功能,可以对上传的文件或者本地的文件进行处 ...

  9. php 文件上传类,功能相当齐全,留作开发中备用吧。

    收藏一个经典好用的php 文件上传类,功能相当齐全,留作开发中备用吧. 好东西,大家都喜欢,才是真的好,哈哈!!! <?php  /**   * 文件上传类   */  class upload ...

随机推荐

  1. C#常用数据结构

    常碰到的几种数据结构:Array,ArrayList,List,LinkedList,Queue,Stack,Dictionary<K,T>: 1.数组是最简单的数据结构.其具有如下特点: ...

  2. Vibe

    在读研和工作之间徘徊了半年,看着一个个好友工作.保研,生活安排得井井有条,我也是时候收拾心情,整装前进了.既然选择了图像,就一定要好好做下去. 今天开始第一个算法,Vibe. ViBe是一种像素级视频 ...

  3. CPCT精细化运营:客户、产品、渠道、时机

    关键词:CPCT.精细化运营思维.客户.产品.渠道.时机.运营 电信运营商市场饱和,用户新增主要靠弃卡后重新入网以及异网用户策反. 用户新增已如此艰难,所以更加关注存量用户经营. 运营商营销资源不断收 ...

  4. HttpResponse与JasonResponse

    两者的含义 我们都知道后台给前台返回的数据都是字符串类型,那么怎么返回成为一个问题 HttpResponse与JasonResponse都是django中后台给前台返回数据的方法, 并且他们最后走的都 ...

  5. leetcode-29.两数相除(不用乘除法和mod)

    如题,不用乘除法和mod实现两数相除. 这里引用一位clever boy 的解法. class Solution { public: int divide(int dividend, int divi ...

  6. moment——日期格式化常用示例

    <template> <div id="app" style="text-align: center;"> <h1>{{ m ...

  7. Image Processing and Analysis_21_Scale Space:Edge Detection and Ridge Detection with Automatic Scale Selection——1998

    此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...

  8. POST,PUT和PATCH的区别

    1. GET方法用于获取资源,不应有副作用,所以是幂等的. 比如:GET http://www.bank.com/account/123456,不会改变资源的状态,不论调用一次还是N次都没有副作用.请 ...

  9. 用js刷剑指offer(变态跳台阶)

    一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 牛客网链接 思路 假设青蛙跳上一个n级的台阶总共有f(n)种跳法. 现在青蛙从第n个台阶 ...

  10. 若干简单的进程和作业调度的C++模拟程序

    进程调度(时间片轮转,动态优先级,链表形式): #include<cstdio> #include<cstdlib> struct PCB { ]; char state; / ...