当前位置: 首页 > news >正文

一个可以用于生产环境得PHP上传函数

上传表单

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>文件上传</title>
</head>
<body><h1>选择要上传的文件</h1><!-- 定义一个包含文件输入字段的表单 --><form action="upload.php" method="post" enctype="multipart/form-data"><input type="file" name="fileToUpload" id="fileToUpload"><input type="submit" value="上传"></form>
</body>
</html>

PHP文件上传函数

这个是增强版本的文件上传函数,增加了以下功能:

添加了对上传文件大小的限制。 通过指定 $allowedExtensions 参数检查上传文件的扩展名。
使用随机字符串生成新的文件名,防止目录遍历攻击。 对于图片文件,进行了基本的尺寸验证(通过 getimagesize()
函数)。若需进一步验证图像内容或处理潜在的安全风险,可以启用注释中的代码块来创建和销毁临时图像资源。
请注意,在实际生产环境中,针对图像文件的验证可能需要更复杂的逻辑,具体取决于您的需求。例如,您可以根据业务需求设定最大宽高比、最小和最大尺寸等条件。

function uploadFile($file, $uploadDir, $allowedExtensions = [], $maxFileSize = 0, $allowedMimeTypes = []) {// 检查是否是 POST 请求以及是否有文件被上传if (!isset($_FILES[$file]) || $_SERVER['REQUEST_METHOD'] !== 'POST') {return ['status' => false, 'message' => 'Invalid request.'];}$uploadedFile = $_FILES[$file];// 检查错误状态if ($uploadedFile['error'] !== UPLOAD_ERR_OK) {switch ($uploadedFile['error']) {case UPLOAD_ERR_INI_SIZE:case UPLOAD_ERR_FORM_SIZE:$errorMessage = 'The uploaded file exceeds the maximum allowed size.';break;case UPLOAD_ERR_NO_FILE:$errorMessage = 'No file was uploaded.';break;default:$errorMessage = 'Unknown error occurred while uploading file.';}return ['status' => false, 'message' => $errorMessage];}// 检查文件大小限制if ($maxFileSize > 0 && $uploadedFile['size'] > $maxFileSize) {return ['status' => false, 'message' => 'The uploaded file exceeds the maximum allowed size.'];}// 检查 MIME 类型(如果已提供允许的 MIME 类型)if (!empty($allowedMimeTypes)) {$finfo = new finfo(FILEINFO_MIME_TYPE);$mime = $finfo->file($uploadedFile['tmp_name']);if (!in_array($mime, $allowedMimeTypes)) {return ['status' => false, 'message' => 'Invalid file type.'];}}// 检查扩展名是否允许$ext = strtolower(pathinfo($uploadedFile['name'], PATHINFO_EXTENSION));if (!empty($allowedExtensions) && !in_array($ext, $allowedExtensions)) {return ['status' => false, 'message' => 'Invalid file extension.'];}// 生成安全的唯一文件名,防止目录遍历攻击$newFileName = bin2hex(random_bytes(16)) . '.' . $ext;// 定义并检查目标文件夹路径是否存在且可写$targetPath = rtrim($uploadDir, '/') . '/';if (!is_dir($targetPath) || !is_writable($targetPath)) {return ['status' => false, 'message' => 'Upload directory is not writable or does not exist.'];}// 对于图片文件进行尺寸和内容验证(假设使用GD库)if (in_array($mime, ['image/jpeg', 'image/png', 'image/gif'])) {$imageInfo = getimagesize($uploadedFile['tmp_name']);if (!$imageInfo) {return ['status' => false, 'message' => 'Invalid image file.'];}// 可在此处添加对图像尺寸、类型等的进一步验证// ...// 如果需要,可以创建一个临时图像资源以进一步验证内容// $img = imagecreatefromstring(file_get_contents($uploadedFile['tmp_name']));// if (!$img) {//     return ['status' => false, 'message' => 'Failed to process the image.'];// }// imagedestroy($img);}// 将文件移动到目标目录$targetFile = $targetPath . $newFileName;if (!move_uploaded_file($uploadedFile['tmp_name'], $targetFile)) {return ['status' => false, 'message' => 'Failed to move uploaded file to target directory.'];}return ['status' => true,'message' => 'File uploaded successfully.','filename' => $newFileName,'filepath' => $targetFile,];
}

函数使用示例

// 使用示例:
$uploadDir = './upload';
$allowedExtensions = ['jpg', 'jpeg', 'png'];
$maxFileSize = 5 * 1024 * 1024; // 最大文件大小为5MB
$allowedMimeTypes = ['image/jpeg', 'image/png'];if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['fileToUpload'])) {$result = uploadFile('fileToUpload', $uploadDir, $allowedExtensions, $maxFileSize, $allowedMimeTypes);if ($result['status']) {echo 'File uploaded: ' . $result['filepath'];} else {echo 'Error: ' . $result['message'];}
}

相关文章:

  • YoloV5改进策略:基于频域多轴表示学习模块|全网首发|高效涨点|代码注释详解
  • 基于多反应堆的高并发服务器【C/C++/Reactor】(中)子线程 WorkerThread的实现 和 线程池ThreadPool的初始化
  • Wnmp本地部署结合内网穿透实现任意浏览器远程访问本地服务
  • 银行十大主题域
  • MySQL之视图案例
  • ASP.NET可视化流程设计器源码
  • FPGA时序分析与时序约束(三)——I/O接口约束
  • 数脉观察二丨 详解CroPoolv2.0锁仓收益机制 文末附锁仓教程
  • 软件测试|测试平台开发-Flask 入门:编写第一个简单 Web 应用
  • 华为OD机试 - 寻找最优的路测线路(Java JS Python C)
  • 谈谈我的三次考研经历
  • 网络流总结
  • HNU-数据库系统-实验3-数据库设计
  • Lumeical Script------Script Prompt 中的两种输出方式
  • 冬装活动提成计算
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • Android 架构优化~MVP 架构改造
  • Android单元测试 - 几个重要问题
  • angular2开源库收集
  • C++11: atomic 头文件
  • ES2017异步函数现已正式可用
  • Go 语言编译器的 //go: 详解
  • jdbc就是这么简单
  • JS笔记四:作用域、变量(函数)提升
  • mysql 数据库四种事务隔离级别
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • Swoft 源码剖析 - 代码自动更新机制
  • TypeScript实现数据结构(一)栈,队列,链表
  • 第十八天-企业应用架构模式-基本模式
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 简单易用的leetcode开发测试工具(npm)
  • 力扣(LeetCode)56
  • 微信小程序--------语音识别(前端自己也能玩)
  • 怎么把视频里的音乐提取出来
  • 智能网联汽车信息安全
  • ​​​​​​​​​​​​​​Γ函数
  • ​插件化DPI在商用WIFI中的价值
  • #define与typedef区别
  • #if #elif #endif
  • #NOIP 2014#Day.2 T3 解方程
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (vue)页面文件上传获取:action地址
  • (附源码)springboot优课在线教学系统 毕业设计 081251
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)
  • (转)大道至简,职场上做人做事做管理
  • (转)母版页和相对路径
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • .net core webapi 大文件上传到wwwroot文件夹
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .NET Micro Framework初体验
  • .net MVC中使用angularJs刷新页面数据列表
  • .NET 发展历程
  • .net的socket示例