PHP建站技术分享-从入门到精通_各类知识收集PHP建站技术分享-从入门到精通_各类知识收集PHP建站技术分享-从入门到精通_各类知识收集

QQ:420220301 微信/手机:150-3210-7690
当前位置:首页 > 工作总结

php封装的单文件(图片)上传类完整实例

管理员 2025-03-26
工作总结
40

下面是一个完整的PHP单文件上传类实现,包含了安全验证、文件类型检查、大小限制等功能。

文件上传类完整代码

php
复制
<?php/**
 * 单文件上传类
 */class FileUploader {
    // 上传配置
    private $config = array(
        'maxSize'   => 2097152, // 2MB
        'allowExts' => array('jpg', 'gif', 'png', 'jpeg'),
        'savePath'  => './uploads/',
        'autoSub'   => true,    // 自动子目录存储
        'subType'   => 'date',  // 子目录创建方式 date|hash|custom
        'dateFormat'=> 'Ymd',
        'hashLevel' => 1,       // hash子目录层级
        'replace'   => false,   // 存在同名文件是否覆盖
        'saveName'  => array('uniqid', ''), // 保存文件名规则
        'autoCheck' => true,    // 是否自动检查附件
    );
    
    // 上传文件信息
    private $fileInfo = array();
    
    // 错误信息
    private $error = '';
    
    /**
     * 构造函数
     * @param array $config 上传配置
     */
    public function __construct($config = array()) {
        $this->config = array_merge($this->config, $config);
    }
    
    /**
     * 上传文件
     * @param string $field 文件字段名
     * @return bool|string 成功返回文件路径,失败返回false
     */
    public function upload($field) {
        // 检查上传文件
        if (!isset($_FILES[$field])) {
            $this->error = '没有文件被上传';
            return false;
        }
        
        $file = $_FILES[$field];
        
        // 检查上传错误
        if ($file['error']) {
            $this->error = $this->getErrorMsg($file['error']);
            return false;
        }
        
        // 检查是否HTTP上传
        if (!is_uploaded_file($file['tmp_name'])) {
            $this->error = '非法上传文件';
            return false;
        }
        
        // 收集文件信息
        $this->fileInfo = array(
            'name'     => $file['name'],
            'type'     => $file['type'],
            'tmp_name' => $file['tmp_name'],
            'size'     => $file['size'],
            'ext'      => $this->getExt($file['name'])
        );
        
        // 自动检查文件
        if ($this->config['autoCheck']) {
            if (!$this->check()) {
                return false;
            }
        }
        
        // 创建保存目录
        $savePath = $this->getSavePath();
        if (!is_dir($savePath)) {
            if (!mkdir($savePath, 0755, true)) {
                $this->error = '上传目录不存在或不可写';
                return false;
            }
        }
        
        // 生成保存文件名
        $saveName = $this->getSaveName();
        $filename = $savePath . $saveName;
        
        // 移动文件
        if (!move_uploaded_file($file['tmp_name'], $filename)) {
            $this->error = '文件移动失败';
            return false;
        }
        
        return str_replace('\\', '/', $filename);
    }
    
    /**
     * 获取错误信息
     * @return string
     */
    public function getError() {
        return $this->error;
    }
    
    /**
     * 获取上传文件信息
     * @return array
     */
    public function getFileInfo() {
        return $this->fileInfo;
    }
    
    /**
     * 检查上传文件
     * @return bool
     */
    private function check() {
        // 检查文件大小
        if ($this->fileInfo['size'] > $this->config['maxSize']) {
            $this->error = '上传文件大小超过限制';
            return false;
        }
        
        // 检查文件类型
        if (!in_array(strtolower($this->fileInfo['ext']), $this->config['allowExts'])) {
            $this->error = '上传文件类型不允许';
            return false;
        }
        
        // 检查文件是否合法
        if (!$this->checkFile()) {
            $this->error = '上传文件内容不合法';
            return false;
        }
        
        return true;
    }
    
    /**
     * 检查文件内容是否合法
     * @return bool
     */
    private function checkFile() {
        // 简单的图片文件检查
        if (in_array(strtolower($this->fileInfo['ext']), array('jpg', 'jpeg', 'gif', 'png', 'bmp'))) {
            $imgInfo = @getimagesize($this->fileInfo['tmp_name']);
            if (!$imgInfo || !in_array($imgInfo[2], array(1, 2, 3, 6))) {
                return false;
            }
        }
        return true;
    }
    
    /**
     * 获取文件扩展名
     * @param string $filename
     * @return string
     */
    private function getExt($filename) {
        return pathinfo($filename, PATHINFO_EXTENSION);
    }
    
    /**
     * 获取保存路径
     * @return string
     */
    private function getSavePath() {
        $path = rtrim($this->config['savePath'], '/') . '/';
        
        if ($this->config['autoSub']) {
            switch ($this->config['subType']) {
                case 'date':
                    $path .= date($this->config['dateFormat']) . '/';
                    break;
                case 'hash':
                    $name = md5($this->fileInfo['name']);
                    for ($i = 0; $i < $this->config['hashLevel']; $i++) {
                        $path .= substr($name, 0, 2) . '/';
                        $name = substr($name, 2);
                    }
                    break;
                case 'custom':
                    $path .= call_user_func($this->config['subType']) . '/';
                    break;
            }
        }
        
        return $path;
    }
    
    /**
     * 生成保存文件名
     * @return string
     */
    private function getSaveName() {
        $saveName = $this->fileInfo['name'];
        
        if (is_array($this->config['saveName'])) {
            $func = $this->config['saveName'][0];
            $param = $this->config['saveName'][1];
            if ($func) {
                $saveName = $func($param) . '.' . $this->fileInfo['ext'];
            }
        }
        
        // 如果存在同名文件且不覆盖,则重命名
        if (!$this->config['replace'] && file_exists($this->getSavePath() . $saveName)) {
            $saveName = uniqid() . '.' . $this->fileInfo['ext'];
        }
        
        return $saveName;
    }
    
    /**
     * 获取上传错误信息
     * @param int $errorNo
     * @return string
     */
    private function getErrorMsg($errorNo) {
        switch ($errorNo) {
            case 1:
                return '上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值';
            case 2:
                return '上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值';
            case 3:
                return '文件只有部分被上传';
            case 4:
                return '没有文件被上传';
            case 6:
                return '找不到临时文件夹';
            case 7:
                return '文件写入失败';
            default:
                return '未知上传错误';
        }
    }}

使用示例

php
复制
<?php// 引入上传类require_once 'FileUploader.php';// 配置上传参数$config = array(
    'maxSize'   => 5242880, // 5MB
    'allowExts' => array('jpg', 'gif', 'png', 'jpeg'),
    'savePath'  => './uploads/',
    'saveName'  => array('uniqid', ''), // 使用唯一文件名);// 实例化上传类$uploader = new FileUploader($config);// 执行上传$result = $uploader->upload('file'); // 'file'是表单中的文件字段名if ($result) {
    echo "文件上传成功,保存路径:".$result;} else {
    echo "文件上传失败:".$uploader->getError();}

HTML表单示例

html
复制
<!DOCTYPE html><html><head>
    <title>文件上传示例</title></head><body>
    <form action="upload.php" method="post" enctype="multipart/form-data">
        <input type="file" name="file">
        <input type="submit" value="上传">
    </form></body></html>

功能特点

  1. 安全性验证:检查是否为合法上传文件

  2. 文件类型限制:可配置允许上传的文件类型

  3. 大小限制:可配置最大上传文件大小

  4. 自动子目录:支持按日期、hash等方式自动创建子目录

  5. 唯一文件名:防止文件名冲突

  6. 错误处理:提供详细的错误信息

  7. 图片验证:对图片文件进行简单的内容验证

这个类可以满足大多数单文件上传需求,使用时只需简单配置即可。



本文关键词: PHP 学习 php 装的 单文件 文件

希望以上内容对你有所帮助!如果还有其他问题,请随时提问。 各类知识收集 拥有多年CMS企业建站经验,对 iCMS, LeCMS, ClassCMS, Fastadmin, PbootCMS, PHPCMS, 易优CMS, YzmCMS, 讯睿CMS, 极致CMS, Wordpress, HkCMS, YznCMS, WellCMS, ThinkCMF, 等各类cms的相互转化,程序开发,网站制作,bug修复,程序杀毒,插件定制都可以提供最佳解决方案。

相关推荐

扫码关注

qrcode

QQ交谈

回顶部