php实现上传实例
文件上传表单设计
在HTML中创建一个表单,设置enctype="multipart/form-data"以支持文件上传。使用<input type="file">元素允许用户选择文件。
<form action="upload.php" method="post" enctype="multipart/form-data">
<label for="file">选择文件:</label>
<input type="file" name="file" id="file">
<input type="submit" value="上传">
</form>
服务器端处理脚本
创建upload.php文件处理上传逻辑。通过$_FILES超全局数组获取上传文件信息,包括临时路径、大小、类型等。

<?php
$targetDir = "uploads/";
$targetFile = $targetDir . basename($_FILES["file"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($targetFile, PATHINFO_EXTENSION));
// 检查文件是否为真实图片(可选)
if(isset($_POST["submit"])) {
$check = getimagesize($_FILES["file"]["tmp_name"]);
if($check !== false) {
$uploadOk = 1;
} else {
echo "文件不是有效的图片。";
$uploadOk = 0;
}
}
// 检查文件是否已存在
if (file_exists($targetFile)) {
echo "文件已存在。";
$uploadOk = 0;
}
// 限制文件大小(例如5MB)
if ($_FILES["file"]["size"] > 5000000) {
echo "文件过大。";
$uploadOk = 0;
}
// 允许特定文件格式
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg") {
echo "仅支持JPG, JPEG, PNG文件。";
$uploadOk = 0;
}
// 最终处理
if ($uploadOk == 0) {
echo "文件未上传。";
} else {
if (move_uploaded_file($_FILES["file"]["tmp_name"], $targetFile)) {
echo "文件". htmlspecialchars(basename($_FILES["file"]["name"])). "已上传。";
} else {
echo "上传过程中出现错误。";
}
}
?>
安全增强措施
为防止安全漏洞,需添加以下防护:

- 验证文件类型通过MIME类型而非仅扩展名
- 生成随机文件名避免覆盖冲突
- 设置上传目录不可执行
// 生成随机文件名
$newFileName = uniqid().'.'.$imageFileType;
$targetFile = $targetDir . $newFileName;
// 更严格的类型检查
$allowedTypes = ['image/jpeg', 'image/png'];
if(!in_array($_FILES["file"]["type"], $allowedTypes)) {
die("不允许的文件类型");
}
错误处理机制
完善错误处理以提供更好的用户体验:
if ($_FILES["file"]["error"] > 0) {
switch($_FILES["file"]["error"]) {
case UPLOAD_ERR_INI_SIZE:
echo "文件超过服务器限制大小";
break;
case UPLOAD_ERR_FORM_SIZE:
echo "文件超过表单限制大小";
break;
// 其他错误代码处理...
default:
echo "未知错误";
}
}
文件保存优化
对于大文件或高并发场景,可考虑:
- 分块上传处理
- 使用云存储服务
- 异步处理队列
// 示例:分片上传处理
if (isset($_POST['chunk']) && isset($_POST['chunks'])) {
$tempDir = "temp/";
$tempFile = $tempDir . $_POST['filename'] . '.part' . $_POST['chunk'];
move_uploaded_file($_FILES["file"]["tmp_name"], $tempFile);
if ($_POST['chunk'] == $_POST['chunks'] - 1) {
// 所有分片上传完成,合并文件
$finalFile = $targetDir . $_POST['filename'];
$out = fopen($finalFile, "wb");
for ($i = 0; $i < $_POST['chunks']; $i++) {
$partFile = $tempDir . $_POST['filename'] . '.part' . $i;
$in = fopen($partFile, "rb");
while ($buff = fread($in, 4096)) {
fwrite($out, $buff);
}
fclose($in);
unlink($partFile);
}
fclose($out);
}
}






