下面是一个完整的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// 引入上传类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表单示例
<!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>
功能特点
安全性验证:检查是否为合法上传文件
文件类型限制:可配置允许上传的文件类型
大小限制:可配置最大上传文件大小
自动子目录:支持按日期、hash等方式自动创建子目录
唯一文件名:防止文件名冲突
错误处理:提供详细的错误信息
图片验证:对图片文件进行简单的内容验证
这个类可以满足大多数单文件上传需求,使用时只需简单配置即可。
本文关键词: PHP 学习 php 装的 单文件 文件
希望以上内容对你有所帮助!如果还有其他问题,请随时提问。 各类知识收集 拥有多年CMS企业建站经验,对 iCMS, LeCMS, ClassCMS, Fastadmin, PbootCMS, PHPCMS, 易优CMS, YzmCMS, 讯睿CMS, 极致CMS, Wordpress, HkCMS, YznCMS, WellCMS, ThinkCMF, 等各类cms的相互转化,程序开发,网站制作,bug修复,程序杀毒,插件定制都可以提供最佳解决方案。