文件上传
自定义异常类
<?php
// 文件上传自定义异常类
class UploadException extends Exception
{
public function __toString()
{
return <<< UPLOAD
<table>
<tr>
<th>错误编号</th>
<th>错误信息</th>
<th>错误文件</th>
<th>错误行号</th>
</tr>
<tr>
<td>$this->code</td>
<td>$this->message</td>
<td>$this->file</td>
<td>$this->line</td>
</tr>
</table>
<style>
table {border:1px solid black;border-collapse:collapse;text-align:center;}
th,td {border:1px solid black;}
tr:last-of-type {color: red;}
</style>
UPLOAD;
}
}
try {
$fileCode = $_FILES['my_pic']['error'] ?? null;
if ($fileCode && ($fileCode > UPLOAD_ERR_OK)) {
switch ($fileCode) {
case UPLOAD_ERR_INI_SIZE:
throw new UploadException('超过了php.ini中的大小设置', 1);
break;
case UPLOAD_ERR_FORM_SIZE:
throw new UploadException('超过了前端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:
throw new UploadException('未知类型错误', 5);
}
}
// 判断文件类型
$type = strstr($_FILES['my_pic']['type'], '/', true) ?? null;
if ($type && ($type !== 'image')) throw new UploadException('不是有效的图片格式', 8);
// 判断是否是POst方式上传
$tmp_name = $_FILES['my_pic']['tmp_name'] ?? null;
if ($tmp_name && (!(is_uploaded_file($tmp_name)))) throw new UploadException('不是有效的上传方式', 9);
} 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>
<form action=" " method="POST" enctype="multipart/form-data">
<fieldset>
<legend>文件上传</legend>
<!-- 前端设置上传文件大小 -->
<!-- 设置大小必须写在input:file前面 如果反了就没有效果 -->
<input type="hidden" name="MAX_FILE_SIZE" value="10000">
<input type="file" name="my_pic" id="">
<button>上传</button>
</fieldset>
</form>
</body>
</html>
文件移动
<?php
$tmp_name = $_FILES['my_pic']['tmp_name'] ?? null;
if ($tmp_name) {
if (is_uploaded_file($tmp_name)) {
// 获取原始文件名
$fileName = $_FILES['my_pic']['name'];
// 生成唯一的文件名
$destFileName = 'file/' . 'PHP中文网' . sha1(time() . mt_rand(1, 1000) . $fileName) . strstr($fileName, '.');
// 移动文件到正式目录
move_uploaded_file($tmp_name, $destFileName);
echo '<p>' . $_FILES['my_pic']['name'] . ':上传成功</p>';
echo "<img src='{$destFileName}' width='200px'>";
} else {
throw new UploadException('不是有效的上传方式', 9);
}
}
} 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>
<form action=" " method="POST" enctype="multipart/form-data">
<fieldset>
<legend>文件上传</legend>
<!-- 前端设置上传文件大小 -->
<!-- 设置大小必须写在input:file前面 如果反了就没有效果 -->
<!-- <input type="hidden" name="MAX_FILE_SIZE" value="10000"> -->
<input type="file" name="my_pic" id="">
<button>上传</button>
</fieldset>
</form>
</body>
</html>
多文件上传
<?php
// 文件上传自定义异常类
printf('<pre>%s</pre>', print_r($_FILES, true));
class UploadException extends Exception
{
public function __toString()
{
return <<< UPLOAD
<table>
<tr>
<th>错误编号</th>
<th>错误信息</th>
<th>错误文件</th>
<th>错误行号</th>
</tr>
<tr>
<td>$this->code</td>
<td>$this->message</td>
<td>$this->file</td>
<td>$this->line</td>
</tr>
</table>
<style>
table {border:1px solid black;border-collapse:collapse;text-align:center;}
th,td {border:1px solid black;}
tr:last-of-type {color: red;}
</style>
UPLOAD;
}
}
try {
$error = $_FILES['my_pic']['error'];
// print_r($error);
// die;
if ($error)
foreach ($error as $vaule) {
$fileCode = $vaule;
if ($fileCode && ($fileCode > UPLOAD_ERR_OK)) {
switch ($fileCode) {
case UPLOAD_ERR_INI_SIZE:
throw new UploadException('超过了php.ini中的大小设置', 1);
break;
case UPLOAD_ERR_FORM_SIZE:
throw new UploadException('超过了前端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:
throw new UploadException('未知类型错误', 5);
}
}
};
// 判断文件类型
$type = ($_FILES['my_pic']['type']);
if ($type)
foreach ($type as $key => $vaule) {
$type = strstr($vaule, '/', true);
$tmp_name = $_FILES['my_pic']['tmp_name'][$key];
if ($type === 'image') {
// 判断上传方式是否正确
if (is_uploaded_file($tmp_name)) {
$fileName = $_FILES['my_pic']['name'][$key];
// 生成唯一的文件名
$destFileName = 'file/' . 'PHP中文网' . sha1(time() . mt_rand(1, 1000) . $fileName) . strstr($fileName, '.');
move_uploaded_file($tmp_name, $destFileName);
echo '<p>' . $fileName . ':上传成功</p>';
echo "<img src='{$destFileName}' width='200px'>";
} else {
throw new UploadException('不是有效的上传方式', 9);
}
} else {
throw new UploadException('不是有效的图片格式', 8);
}
}
} 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>
<form action=" " method="POST" enctype="multipart/form-data">
<fieldset>
<legend>多文件上传</legend>
<!-- 前端设置上传文件大小 -->
<!-- 设置大小必须写在input:file前面 如果反了就没有效果 -->
<!-- <input type="hidden" name="MAX_FILE_SIZE" value="270000"> -->
<input type="file" name="my_pic[]" multiple id="">
<button>上传</button>
</fieldset>
</form>
</body>
文件上传类
<?php
class UploadException extends Exception
{
public function __toString()
{
return <<< UPLOAD
<table>
<tr>
<th>错误编号</th>
<th>错误信息</th>
<th>错误文件</th>
<th>错误行号</th>
</tr>
<tr>
<td>$this->code</td>
<td>$this->message</td>
<td>$this->file</td>
<td>$this->line</td>
</tr>
</table>
<style>
table {border:1px solid black;border-collapse:collapse;text-align:center;}
th,td {border:1px solid black;}
tr:last-of-type {color: red;}
</style>
UPLOAD;
}
}
class Upload
{
private $fileCode;
private $type;
private $name;
private $tmp_name;
// 正式文件目录名
private $file_name;
public function __construct($name)
{
$this->file_name = $name;
// 循环获得上传文件的各个信息
foreach ($_FILES as $v) {
$this->fileCode = $v['error'];
$this->type = $v['type'];
$this->tmp_name = $v['tmp_name'];
$this->name = $v['name'];
$this->get();
$this->type();
$this->tmp_name();
}
}
private function get()
{
// 根据错误信息抛出相应错误
if ($this->fileCode && ($this->fileCode > UPLOAD_ERR_OK)) {
switch ($this->fileCode) {
case UPLOAD_ERR_INI_SIZE:
throw new UploadException('超过了php.ini中的大小设置', 1);
break;
case UPLOAD_ERR_FORM_SIZE:
throw new UploadException('超过了前端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:
throw new UploadException('未知类型错误', 5);
}
}
}
private function type()
{
// 判断文件的格式
$typ = strstr($this->type, '/', true);
if ($this->type && ($typ !== 'image')) throw new UploadException('不是有效的图片格式', 8);
}
private function tmp_name()
{
// 判断文件上传方式是否为POST,正确则把文件转入正式目录
if ($this->tmp_name) {
if (is_uploaded_file($this->tmp_name)) {
// 生成唯一文件名
$destFileName = $this->file_name . 'PHP中文网' . sha1(time() . mt_rand(1, 1000) . $this->name) . strstr($this->name, '.');
// 把文件转入正式目录
move_uploaded_file($this->tmp_name, $destFileName);
echo '<p>' . $this->name . ':上传成功</p>';
echo "<img src='{$destFileName}' width='200px'>";
} else {
throw new UploadException('不是有效的上传方式', 9);
}
}
}
}
try {
printf('<pre>%s</pre>', print_r($_FILES, true));
$a = new Upload('123456/');
} 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>
<form action=" " method="POST" enctype="multipart/form-data">
<fieldset>
<legend>单文件上传</legend>
<!-- 前端设置上传文件大小 -->
<!-- 设置大小必须写在input:file前面 如果反了就没有效果 -->
<!-- <input type="hidden" name="MAX_FILE_SIZE" value="10000"> -->
<input type="file" name="my_pic1" id="">
<input type="file" name="my_pic2" id="">
<input type="file" name="my_pic3" id="">
<button>上传</button>
</fieldset>
</form>
</form>
</body>
</html>
总结
1.了解了文件上传的错误处理
2.如果想用一个input标签完成多文件上传,使用了较多的流程控制但不知应该如果精简