php实现文件上传下载
PHP 文件上传实现
创建 HTML 表单,设置 enctype="multipart/form-data" 以支持文件上传:
<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="file" name="fileToUpload">
<input type="submit" value="Upload">
</form>
处理上传的 PHP 脚本 (upload.php):
$targetDir = "uploads/";
$targetFile = $targetDir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($targetFile, PATHINFO_EXTENSION));
// 检查文件是否已存在
if (file_exists($targetFile)) {
echo "文件已存在";
$uploadOk = 0;
}
// 限制文件大小 (5MB)
if ($_FILES["fileToUpload"]["size"] > 5000000) {
echo "文件过大";
$uploadOk = 0;
}
// 允许特定文件格式
$allowedTypes = ["jpg", "png", "jpeg", "gif"];
if (!in_array($imageFileType, $allowedTypes)) {
echo "仅支持 JPG, JPEG, PNG & GIF 格式";
$uploadOk = 0;
}
// 检查错误并移动文件
if ($uploadOk == 1) {
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $targetFile)) {
echo "文件上传成功";
} else {
echo "上传失败";
}
}
PHP 文件下载实现
创建下载链接:
<a href="download.php?file=example.pdf">下载文件</a>
处理下载的 PHP 脚本 (download.php):
$file = $_GET['file'] ?? '';
$filePath = "uploads/" . basename($file);
if (file_exists($filePath)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($filePath).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filePath));
readfile($filePath);
exit;
} else {
echo "文件不存在";
}
安全注意事项
验证文件类型时不要仅依赖扩展名,应使用 finfo_file() 检测实际 MIME 类型:
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $_FILES["fileToUpload"]["tmp_name"]);
finfo_close($finfo);
$allowedMimeTypes = ["image/jpeg", "image/png", "image/gif"];
if (!in_array($mime, $allowedMimeTypes)) {
echo "无效的文件类型";
$uploadOk = 0;
}
限制上传目录的执行权限,防止上传的脚本文件被执行:
// 在服务器配置中设置
<Directory "/path/to/uploads">
php_flag engine off
</Directory>
大文件上传处理
对于大文件上传,可能需要调整 PHP 配置:
; php.ini 设置
upload_max_filesize = 100M
post_max_size = 100M
max_execution_time = 300
使用分块上传技术处理超大文件:
// 前端使用File API分割文件
// 后端接收并合并分块






