move_uploaded_file() 函数用于将上传的文件移动到新位置。此函数是 PHP 中处理文件上传的标准方法。
函数会检查目标文件是否是通过 HTTP POST 上传的,如果是,则将其移动到指定位置。如果不是通过 POST 上传的文件,函数会返回 false。
move_uploaded_file ( string $filename , string $destination ) : bool
| 参数 | 类型 | 说明 |
|---|---|---|
filename |
字符串 | 上传文件的临时文件名(来自 $_FILES['userfile']['tmp_name']) |
destination |
字符串 | 文件移动的目标路径,包括新文件名 |
成功时返回 true,失败时返回 false。
HTML 表单代码:
<!DOCTYPE html>
<html>
<head>
<title>文件上传示例</title>
</head>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
<label for="file">选择要上传的文件:</label>
<input type="file" name="userfile" id="file">
<input type="submit" value="上传">
</form>
</body>
</html>
PHP 处理代码(upload.php):
<?php
// 确保是 POST 请求
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 检查文件上传是否成功
if (isset($_FILES['userfile']) && $_FILES['userfile']['error'] === UPLOAD_ERR_OK) {
$uploadDir = 'uploads/';
// 确保上传目录存在
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
// 生成安全的文件名
$originalName = basename($_FILES['userfile']['name']);
$extension = pathinfo($originalName, PATHINFO_EXTENSION);
$safeName = uniqid('file_') . '.' . $extension;
$destination = $uploadDir . $safeName;
// 移动上传的文件
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $destination)) {
echo "文件上传成功!<br>";
echo "原始文件名: " . htmlspecialchars($originalName) . "<br>";
echo "保存路径: " . htmlspecialchars($destination) . "<br>";
echo "文件大小: " . $_FILES['userfile']['size'] . " 字节";
} else {
echo "文件移动失败。";
}
} else {
echo "文件上传失败。错误代码: " . $_FILES['userfile']['error'];
}
}
?>
HTML 表单代码:
<!DOCTYPE html>
<html>
<head>
<title>多文件上传</title>
</head>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
<label for="files">选择多个文件:</label>
<input type="file" name="userfiles[]" id="files" multiple>
<input type="submit" value="上传">
</form>
</body>
</html>
PHP 处理代码:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$uploadDir = 'uploads/';
$results = [];
// 确保上传目录存在
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
// 处理每个上传的文件
foreach ($_FILES['userfiles']['error'] as $key => $error) {
if ($error === UPLOAD_ERR_OK) {
$originalName = basename($_FILES['userfiles']['name'][$key]);
$tmpName = $_FILES['userfiles']['tmp_name'][$key];
$fileSize = $_FILES['userfiles']['size'][$key];
// 生成安全的文件名
$extension = pathinfo($originalName, PATHINFO_EXTENSION);
$safeName = uniqid('file_') . '.' . $extension;
$destination = $uploadDir . $safeName;
// 移动文件
if (move_uploaded_file($tmpName, $destination)) {
$results[] = [
'original' => $originalName,
'saved' => $destination,
'size' => $fileSize,
'success' => true
];
} else {
$results[] = [
'original' => $originalName,
'success' => false
];
}
}
}
// 显示结果
echo "上传结果:<br><br>";
foreach ($results as $result) {
if ($result['success']) {
echo "✓ " . htmlspecialchars($result['original']) . " 上传成功 (" . $result['size'] . " 字节)<br>";
} else {
echo "✗ " . htmlspecialchars($result['original']) . " 上传失败<br>";
}
}
}
?>
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$uploadDir = 'uploads/';
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'application/pdf'];
$maxFileSize = 2 * 1024 * 1024; // 2MB
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
if (isset($_FILES['userfile']) && $_FILES['userfile']['error'] === UPLOAD_ERR_OK) {
$tmpName = $_FILES['userfile']['tmp_name'];
$originalName = $_FILES['userfile']['name'];
$fileSize = $_FILES['userfile']['size'];
$fileType = $_FILES['userfile']['type'];
// 验证文件类型
if (!in_array($fileType, $allowedTypes)) {
die("错误:不允许的文件类型。只允许:" . implode(', ', $allowedTypes));
}
// 验证文件大小
if ($fileSize > $maxFileSize) {
die("错误:文件太大。最大允许 " . ($maxFileSize / 1024 / 1024) . "MB");
}
// 进一步验证文件类型(通过文件内容)
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $tmpName);
finfo_close($finfo);
if (!in_array($mimeType, $allowedTypes)) {
die("错误:文件类型验证失败");
}
// 生成安全的文件名
$extension = pathinfo($originalName, PATHINFO_EXTENSION);
$safeName = md5_file($tmpName) . '.' . $extension;
$destination = $uploadDir . $safeName;
// 移动文件
if (move_uploaded_file($tmpName, $destination)) {
echo "文件验证成功并已保存!";
} else {
echo "文件保存失败";
}
} else {
echo "文件上传失败";
}
}
?>
当文件上传时,PHP 会将文件信息存储在 $_FILES 超级全局数组中。对于名为 "userfile" 的文件输入字段,$_FILES['userfile'] 包含:
| 键名 | 说明 |
|---|---|
name |
原始文件名 |
type |
文件的 MIME 类型(由浏览器提供,不可靠) |
tmp_name |
文件的临时存储路径(用于 move_uploaded_file() 的第一个参数) |
error |
错误代码(UPLOAD_ERR_OK 表示成功) |
size |
文件大小(字节) |
| 错误代码 | 常量 | 说明 |
|---|---|---|
| 0 | UPLOAD_ERR_OK | 文件上传成功 |
| 1 | UPLOAD_ERR_INI_SIZE | 文件大小超过 php.ini 中的 upload_max_filesize 限制 |
| 2 | UPLOAD_ERR_FORM_SIZE | 文件大小超过表单中的 MAX_FILE_SIZE 限制 |
| 3 | UPLOAD_ERR_PARTIAL | 文件只有部分被上传 |
| 4 | UPLOAD_ERR_NO_FILE | 没有文件被上传 |
| 6 | UPLOAD_ERR_NO_TMP_DIR | 找不到临时文件夹 |
| 7 | UPLOAD_ERR_CANT_WRITE | 文件写入失败 |
| 8 | UPLOAD_ERR_EXTENSION | PHP 扩展停止了文件上传 |