文件上传
一、PHP上传文件参考配置(php.ini)
配置参数 |
描述 |
file_uploads=on/off |
是否允许通过http方式上传文件 |
max_execution_time=30 |
允许脚本最大执行时间,超过这个时间就会报错 |
memory_limit=50M |
设置脚本可以分配的最大内存量,防止失控脚本占用过多内存,此指令只有在编译时设置了 —enable-memory-limit标志的情况下才生效 |
upload_max_filesize=20M |
允许上传文件的最大大小,此指令必须小于post_max_size |
upload_tmp_dir |
上传文件临时存放目录 |
post_max_size=30M |
允许post方式可以接受最大大小 |
二、$_FILES超全局变量数组,保存着与文件上传的相关信息
数组参数 |
描述 |
[name] |
客户端文件的原名称。 |
[type] |
文件的 MIME 类型,需要浏览器提供该信息的支持,例如”image/gif”。 |
[size] |
已上传文件的大小,单位为字节。 |
[tmp_name] |
文件被上传后在服务端储存的临时文件名,一般是系统默认。可以在php.ini的upload_tmp_dir 指定,但 用 putenv() 函数设置是不起作用的。 |
[error] |
和该文件上传相关的错误代码。 |
错误代码 |
描述 |
0 |
没有错误发生,文件上传成功。 |
1 |
上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值。 |
2 |
上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值。 |
3 |
文件只有部分被上传。 |
4 |
没有文件被上传。 |
5 |
上传文件大小为0. |
1.$_FILES练习
<?php
//$_FILES超全局变量数组,保存着所有与文件上传的相关消息
printf('<pre>%s</pre>',print_r($_FILES,true));
?>
<!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 enctype="multipart/form-data" action="" method="post">
<fieldset>
<input type="hidden" name="MAX_FILE_SIZE" value="300000">
<legend>文件上传</legend>
<input name="myFile" type="file">
<input type="submit" value="上传文件">
</fieldset>
</form>
</body>
</html>
- 检查文件是否上传成功
<?php
//$_FILES超全局变量数组,保存着所有与文件上传的相关消息
printf('<pre>%s</pre>',print_r($_FILES,true));
//获取上传错误的代码
$errorCode = $_FILES['myFile']['error'] ?? null;
//2.判断
if($errorCode === 4) echo '<p>没有文件上传</p>';
//if(empty($_FILES['myFile']['name'])) echo '<p>没有文件上传</p>';
?>
<!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 enctype="multipart/form-data" action="" method="post">
<fieldset>
<input type="hidden" name="MAX_FILE_SIZE" value="300000">
<legend>文件上传</legend>
<input name="myFile" type="file">
<input type="submit" value="上传文件">
</fieldset>
</form>
</body>
</html>
3. 判断临时文件是否是通过post方式上传
<?php
//$_FILES超全局变量数组,保存着所有与文件上传的相关消息
printf('<pre>%s</pre>',print_r($_FILES,true));
//判断:1.临时文件名2.is_uploadede_file()
//is_uploaded_file() 函数检查指定的文件是否是通过 HTTP POST 上传的。
//1.原始文件名
$origianlFileName = $_FILES['myFile']['name'] ?? null;
//2.临时文件名
$tmplFileName = $_FILES['myFile']['tmp_name'] ?? null;
//首先临时文件是存在的,并且必须通过post上传
if($tmplFileName && is_uploaded_file($tmplFileName)) echo '<p>上传方式正确</p>';
else echo '上传类型错误';
?>
<!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 enctype="multipart/form-data" action="" method="post">
<fieldset>
<legend>文件上传</legend>
<input name="myFile" type="file">
<input type="submit" value="上传文件">
</fieldset>
</form>
</body>
</html>
4.检查文件类型
<?php
//$_FILES超全局变量数组,保存着所有与文件上传的相关消息
printf('<pre>%s</pre>',print_r($_FILES,true));
$fileType = $_FILES['myFile']['type'] ?? null;
//strstr()返回斜线后面的内容,true返回斜线前面的内容
$type = strstr($fileType,'/',true);
if($type !== 'image') echo '文件类型错误:不是有效的图片格式';
echo '类型正确';
?>
<!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 enctype="multipart/form-data" action="" method="post">
<fieldset>
<legend>文件上传</legend>
<input name="myFile" type="file">
<input type="submit" value="上传文件">
</fieldset>
</form>
</body>
</html>
5.检测文件大小是否超过php.ini设置的大小
<?php
//$_FILES超全局变量数组,保存着所有与文件上传的相关消息
printf('<pre>%s</pre>',print_r($_FILES,true));
//echo ini_get('upload_max_filesize');
//1.获取上传错误的代码
$errorCode = $_FILES['myFile']['error'] ?? null;
switch ($errorCode){
case 1:
echo '超过了php.ini的大小设置';
break;
case 2:
echo '超过了表单的大小设置';
break;
}
?>
<!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 enctype="multipart/form-data" action="" method="post">
<fieldset>
<legend>文件上传</legend>
<!-- <input type="hidden" name="MAX_FILE_SIZE" value="300000"> -->
<input name="myFile" type="file">
<input type="submit" value="上传文件">
</fieldset>
</form>
</body>
</html>
三、单文件上传
<?php
error_reporting(E_ALL);
//$_FILES超全局变量数组,保存着所有与文件上传的相关消息
//printf('<pre>%s</pre>',print_r($_FILES,true));
/***********************************************************/
class E extends Exception
{
public function __tostring()
{
return <<< HERE
<table border="1px" cellspacing="0" cellpadding="10px">
<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>
HERE;
}
}
/***********************************************************/
try{
//对错误编码的判断
//获取错误代码
$ECode = $_FILES['myFile']['error'] ?? null;
//var_dump($ECode);
//使用系统常量进行判断
if($ECode > UPLOAD_ERR_OK){
switch ($ECode){
case UPLOAD_ERR_INI_SIZE:
throw new E('上传的文件超过了php.ini中设置的大小',1001);
break;
case UPLOAD_ERR_FORM_SIZE:
throw new E('上传的文件超过了表单中设置的大小',1002);
break;
case UPLOAD_ERR_PARTIAL:
throw new E('文件只有部分被上传',1003);
break;
case UPLOAD_ERR_NO_FILE:
throw new E('没有文件被上传',1004);
break;
case UPLOAD_ERR_NO_TMP_DIR:
throw new E('找不到临时文件',5);
break;
case UPLOAD_ERR_CANT_WRITE:
throw new E('文件写入失败',6);
break;
default:
//测试时建议关闭
//throw new E('未知类型错误',1007);
break;
}
}
/***********************************************************/
//对文件类型的判断
//获取文件类型
$fileType = $_FILES['myFile']['type'] ?? null;
//截取文件类型 image
$type = strstr($fileType, '/',true);
//var_dump($type);
if($type && $type !== 'image'){
throw new E ('文件类型错误:不是有效的图片格式',1008);
}
/***********************************************************/
//判断上传方式是否正确
//获取文件名
$fileName = $_FILES['myFile']['name'] ?? null;
//获取临时文件名
$tmpName = $_FILES['myFile']['tmp_name'] ?? null;
//判断临时文件名是否存在并且是否通过post方式上传
if($tmpName && is_uploaded_file($tmpName)){
//echo '<p>'.$fileName.':上传方式正确';
//将文件从临时文件移动到目标目录中
//move_uploaded_file(临时文件,目标文件)
//获取文件扩展名
$extends = strstr($fileName,'.');
//设置目标文件名并加密
$destFileName = 'uploads/'.md5(time().mt_rand(1,1000)).$extends;
if(move_uploaded_file($tmpName,$destFileName)){
echo '<p>'.$fileName.':上传成功</p>';
echo "<img src='{$destFileName}' width='100px'>";
}
}
/***********************************************************/
}catch(E $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 enctype="multipart/form-data" action="" method="post">
<fieldset>
<!-- <input type="hidden" name="MAX_FILE_SIZE" value="300000"> -->
<legend>文件上传</legend>
<input name="myFile" type="file">
<input type="submit" value="上传文件">
</fieldset>
</form>
</body>
</html>
四、多文件上传
<?php
error_reporting(E_ALL);
printf('<pre>%s</pre>',print_r($_FILES,true));
/*******************************************************************************/
try {
foreach ($_FILES as $file){
if($file['type'] && strstr($file['type'],'/',true) !== 'image')
{
echo $file['name'].':文件类型错误:不是有效的图片格式';
$file['error'] = 4;
}
switch ($file['error'])
{
case 0:
//上传成功,并保存到目标文件中
$destFileName = 'uploads/'.md5(time().mt_rand(1,1000)).strstr($file['type'],'.');
if(move_uploaded_file($file['tmp_name'],$destFileName)){
echo '<p>'.$file['name'].':上传成功</p>';
echo "<img src='{$destFileName}' width='100px'>";
}
break;
case UPLOAD_ERR_INI_SIZE:
echo $file['name'].':上传的文件超过了php.ini中设置的大小<br>';
break;
case UPLOAD_ERR_FORM_SIZE:
echo $file['name'].':上传的文件超过了表单中设置的大小<br>';
break;
case UPLOAD_ERR_PARTIAL:
echo $file['name'].':文件只有部分被上传<br>';
break;
case UPLOAD_ERR_NO_FILE:
echo $file['name'].':没有文件被上传<br>';
break;
case UPLOAD_ERR_NO_TMP_DIR:
echo $file['name'].':找不到临时文件<br>';
break;
case UPLOAD_ERR_CANT_WRITE:
echo $file['name'].':文件写入失败<br>';
break;
default:
//测试时建议关闭
echo $file['name'].':未知类型错误<br>';
break;
}
}
}catch(E $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 type="file" name="myFile1" id="">
<input type="file" name="myFile2" id="">
<input type="file" name="myFile3" id="">
<button>上传</button>
</fieldset>
</form>
</body>
</html>