PHP 图片上传:客户端表单与服务端处理实现
在 Web 开发中,图片上传是常见需求。本文将演示如何通过 HTML 表单与 PHP 脚本配合,实现安全的图片上传逻辑,包括客户端的文件选择与提交方式设置,以及服务器端的临时文件验证、重命名与持久化存储操作。
核心目标
本教程旨在解决如何将用户浏览器端选择的图片文件安全地传输到服务器,并存储在指定的目录中,同时避免文件名冲突。
准备条件
- 运行环境:已安装 PHP 的服务器环境(如 Apache + Nginx)。
- 前置权限:确保目标上传目录(例如 /attached/)具有写权限(chmod 777 或适当用户组权限)。
真实操作顺序
第1步:创建前端上传表单
目的:提供一个界面让用户选择图片并提交请求。
入口:新建一个 HTML 文件(如 index.html)。
动作:关键步骤是将 form 标签的 method 设为 post,并将 enctype 属性设置为 multipart/form-data。这是二进制文件(如图片)上传的必要配置,否则文件内容会损坏或无法传输。
参数:
action:指向处理上传的后端 PHP 脚本路径。name="pic":输入框的名称,后续在后端通过此名称索引。
<form name="form1" method="post" action="admin_upfile.php" enctype="multipart/form-data"> <input type="file" name="pic"> <input type="submit" name="Submit" value="开始上传" class="button"> </form>
第2步:编写后端接收与解析脚本
目的:接收前端提交的临时文件数据,计算绝对路径。
入口:新建 PHP 脚本(如 admin_upfile.php)。
动作:首先定义相对上传路径 $uppath = "/attached/"。由于服务器内部通常使用绝对路径才能准确写入磁盘,代码中包含了一段逻辑遍历当前脚本路径 $_SERVER["SCRIPT_NAME"],通过提取目录层级并拼接 ../ 来转换为相对于根目录的实际物理路径 $uppaths。
第3步:构建日期子目录
目的:管理大量文件,避免单一目录下文件过多导致性能下降或混乱。
入口:基于当前日期生成目录名。
动作:使用 date("y-m-d") 获取形如 23-05-15 的日期字符串作为子目录名。若该目录不存在(!is_dir()),则调用 mkdir() 创建它。
第4步:执行安全验证与文件重命名
目的:防止用户上传恶意脚本或非图片文件,并确保文件名全局唯一。
入口:读取 $_FILES['pic'] 数组数据。
动作:
- MIME 校验:检查
$f["type"]。示例中硬编码了允许的图像类型(image/gif,image/pjpeg,image/jpeg,image/x-png)。若不在列表中,直接终止并提示错误。 - 扩展名提取:利用
explode(".", $f["name"])拆分原始文件名,取最后一部分作为扩展名,并进行小写化处理。 - 唯一性生成:为了避免同名覆盖,使用
md5(date("YmdHis"))生成基于时间的哈希值作为新文件名主体,拼接原扩展名,得到$new_file_name。
第5步:移动临时文件至最终位置
目的:将浏览器暂存在服务器的临时文件转移到正式存储区。
入口:PHP 上传处理函数。
动作:构造目标绝对路径 $dest = $uppaths . $filename . "/" . date("ymdhis") . "_" . $new_file_name,然后调用 move_uploaded_file($f['tmp_name'], $dest)。此函数不仅移动文件,还自动删除临时文件,保障存储整洁。
<?php
//这里上传 $upsize判断上传文件的大小
$uppath = "/attached/"; //文件上传路径
//转换根目录的路径
if (strpos($uppath, "/") == 0)
{
$i = 0;
$thpath = $_SERVER["SCRIPT_NAME"];
$thpath = substr($thpath, 1, strlen($thpath));
while (strripos($thpath, "/") !== false)
{
$thpath = substr($thpath, strpos($thpath, "/") + 1, strlen($thpath));
$i = ++$i;
}
$pp = "";
for ($j = 0; $j < $i; ++$j)
{
$pp .= "../";
}
$uppaths = $pp . substr($uppath, 1, strlen($thpath));
}
$filename = date("y-m-d");
if (is_dir($uppaths . $filename) != TRUE)
mkdir($uppaths . $filename, 0777);
$f = $_FILES['pic'];
if ($f["type"] != "image/gif" && $f["type"] != "image/pjpeg" && $f["type"] != "image/jpeg" && $f["type"] != "image/x-png")
{
echo "<script>alert('只能上传图片格式的文件');window.close()</script>";
return false;
}
//获得文件扩展名
$temp_arr = explode(".", $f["name"]);
$file_ext = array_pop($temp_arr);
$file_ext = trim($file_ext);
$file_ext = strtolower($file_ext);
//新文件名
$new_file_name = md5(date("YmdHis")) . '.' . $file_ext;
echo $dest = $uppaths . $filename . "/" . date("ymdhis") . "_" .
$new_file_name; //设置文件名为日期加上文件名避免重复 上传目录
echo $dest1 = $uppath . $filename . "/" . date("ymdhis") . "_" .
$new_file_name; //设置文件名为日期加上文件名避免重复
$r = move_uploaded_file($f['tmp_name'], $dest);
?>
完成判断
当页面控制台不再弹出警告且服务器对应日期目录下出现带有时间戳命名的图片文件时,即表示上传与存储流程成功执行。
简要总结
以上就是 PHP 实现图片客户端和服务器端上传方法的详细内容,更多关于 PHP 文件上传的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









