文件上传案例
1.基础
- 前端页面要做的是,首先是提交方式必须修改为
post
,因为文件上传和大数据的传输,post
更合适。需要注意的地方如下: - 然后当前端页面提交后,剩余的就是我们后端需要处理的事情了。首先获得文件的后缀名。并对文件的存放位置进行设定。
- 这里使用 PHP 的全局数组
$_FILES
来实现文件上传:
$_FILES["file"]["name"]
- 被上传文件的名称
$_FILES["file"]["type"]
- 被上传文件的类型
$_FILES["file"]["size"]
- 被上传文件的大小,以字节计
$_FILES["file"]["tmp_name"]
- 存储在服务器的文件的临时副本的名称
$_FILES["file"]["error"]
- 由文件上传导致的错误代码
其他具体的在案例中注意注释部分
2. 单文件上传案例
<?php
// printf('<pre>%s</pre>', print_r($_FILES, true));
// Exception系统异常类
class UploadException extends Exception
{
// 在异常子类中,可以访问并重写Exception中的四个属性,通过__toString()格式化异常输出信息
public function __toString()
{
return <<< UPLOAD
<style>
table {border-collapse: collapse;border:1px solid black;text-align: center;}
td {border:1px solid black;padding: 5px;}
tr:first-of-type {background-color:#eee;}
tr:last-of-type td {color: coral;}
</style>
<table>
<tr><td>代码</td><td>信息</td><td>文件</td><td>行号</td></tr>
<tr><td>$this->code</td><td>$this->message</td><td>$this->file</td><td>$this->line</td></tr>
</table>
UPLOAD;
}
}
try {
// 上传出错的代码
$errorCode = $_FILES['my_pic']['error'];
if ($errorCode > UPLOAD_ERR_OK) {
switch ($errorCode) {
case UPLOAD_ERR_INI_SIZE:
throw new UploadException('上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值', 1);
break;
case UPLOAD_ERR_FORM_SIZE:
throw new UploadException('上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值', 2);
break;
case UPLOAD_ERR_PARTIAL:
throw new UploadException('文件只有部分被上传', 3);
break;
case UPLOAD_ERR_NO_FILE:
throw new UploadException('没有文件被上传', 4);
break;
case UPLOAD_ERR_NO_TMP_DIR:
throw new UploadException('找不到临时文件夹', 6);
break;
case UPLOAD_ERR_CANT_WRITE:
throw new UploadException('文件写入失败', 7);
break;
default:
// 测试时建议关掉default: 避免误报影响
throw new UploadException('未知类型错误', 8);
}
}
// 判断文件类型
// $fileType = $_FILES['my_pic']['type'];
// if (strstr($fileType, '/', true) !== 'image') throw new UploadException('文件类型错误', 9);
// 将文件从临时目录 移动到用户自定义的目标目录中
// 临时文件名
$tempFileName = $_FILES['my_pic']['tmp_name'];
if (is_uploaded_file($tempFileName)) {
// 原始文件名
$originalFileName = $_FILES['my_pic']['name'];
// 目录文件名
$destFileName = 'uploads/' . md5(time()) . strstr($originalFileName, '.');
// 移动文件到目标目录使用的函数
if (move_uploaded_file($tempFileName, $destFileName)) {
// echo "<p>$originalFileName: 上传成功~~</p>";
// 预览
}
}
} catch (UploadException $e) {
echo $e;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>头像上传</title>
</head>
<body>
<h3>头像上传</h3>
<form action="" method="POST" enctype="multipart/form-data">
<fieldset>
<legend>点击上传头像</legend>
<input type="file" name="my_pic" />
<button>点击上传</button>
</fieldset>
</form>
<h2>头像预览</h2>
<div><?php echo "<img src='{$destFileName}' width='200'>"; ?></div>
</body>
</html>
3. 多文件上传案例
3.1 通过定义不同的上传文件名属性方式
<?php
// printf('<pre>%s</pre>', print_r($_FILES, true));
foreach ($_FILES as $file) {
// 只要判断 error === 0
if ($file['error'] === 0) {
$destinationFile = 'uploads/' . md5(time() . mt_rand(1, 10000)) . strstr($file['name'], '.');
move_uploaded_file($file['tmp_name'], $destinationFile);
echo "<img src='{$destinationFile}' width='200'>";
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>多文件上传</title>
</head>
<body>
<h3>多文件上传</h3>
<form action="" method="POST" enctype="multipart/form-data">
<fieldset>
<legend>逐一上传多个文件</legend>
<input type="file" name="my_pic1">
<input type="file" name="my_pic2">
<button>点击上传</button>
</fieldset>
</form>
</body>
</html>
3.2 通过数组的方式定义文件名属性
<?php
printf('<pre>%s</pre>', print_r($_FILES, true));
if ($_FILES['my_pic'])
foreach ($_FILES['my_pic']['error'] as $key => $error) {
// 只要判断 error === 0
if ($error === UPLOAD_ERR_OK) {
// 临时文件名
$tmpFileName = $_FILES['my_pic']['tmp_name'][$key];
// 原始文件名
$originalFileName = $_FILES['my_pic']['name'][$key];
// 目标文件名
$destFileName = 'uploads/' . $originalFileName;
// 移动文件
move_uploaded_file($tmpFileName, $destFileName);
// 预览
echo "<img src='{$destFileName}' width='200'>";
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>多文件上传</title>
</head>
<body>
<h3>多文件上传</h3>
<form action="" method="POST" enctype="multipart/form-data">
<fieldset>
<legend>逐一上传多个文件</legend>
<input type="file" name="my_pic[]">
<input type="file" name="my_pic[]">
<input type="file" name="my_pic[]">
<button>点击上传</button>
</fieldset>
</form>
</body>
</html>
4. 批量上传案例
- 增加参数
multiple
<?php
printf('<pre>%s</pre>', print_r($_FILES, true));
if ($_FILES['my_pic'])
foreach ($_FILES['my_pic']['error'] as $key => $error) {
// 只要判断 error === 0
if ($error === UPLOAD_ERR_OK) {
// 临时文件名
$tmpFileName = $_FILES['my_pic']['tmp_name'][$key];
// 原始文件名
$originalFileName = $_FILES['my_pic']['name'][$key];
// 目标文件名
$destFileName = 'uploads/' . $originalFileName;
// 移动文件
move_uploaded_file($tmpFileName, $destFileName);
// 预览
echo "<img src='{$destFileName}' width='200'>";
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>多文件上传</title>
</head>
<body>
<h3>多文件上传</h3>
<form action="" method="POST" enctype="multipart/form-data">
<fieldset>
<legend>逐一上传多个文件</legend>
<input type="file" name="my_pic[]" multiple>
<button>点击上传</button>
</fieldset>
</form>
</body>
</html>
5. 上传方法封装成类
本节课程学习了文件上传的知识,PHP 支持同时上传多个文件并将它们的信息自动以数组的形式组织。课后尝试对上传方法进行封装,发现失败了,就没在这里展示失败的代码了,希望可以慢慢学会如何封装一个类。