企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
## **文件的上传下载** **对于上传文件的判断需要考虑到的问题** >[danger]1. 构建临时文件 >2. 判断是否是HTTP POST上传的 >3. 判断是否有错误 >4. 判断文件大小 >5. 获取文件扩展名 开启php_fileinfo.dll扩展 获取mime类型 >6. 判断文件类型 >7. 构建目标文件 **注意:对于表单上传文件必须的属性** >[danger]1. method 属性 :必须是 method='post' >2. enctype 属性 :对上传文件进行编码处理 :enctype ='multipart/form-data' **容易出错的地方** **MAX_FILE_SIZE**:` <input type="hidden" name="MAX_FILE_SIZE" value="2048" />`不能大于 ini 设置中upload_max_filesize选项设置的值。 >[danger]**MAX_FILE_SIZE**可以避免等一个大文件传上服务器以后才发现超过限制了,在上传之初就提示用户 **IE**和**FireFox**这两个主流浏览器都不支持这个特性 **upload_max_filesize**:上传单个文件的最大限制(默认2M) **post_max_size**:POST的数据最大字节长度(默认8M);如果post_max_size设置的值太小,则较大的文件会无法被上传。因此,请保证*post_max_size*的值足够的大。 **memory_limit**:最大的内存消耗(默认128M) >[danger]如果内存限制设置被激活,可能需要将[memory_limit](http://php.net/manual/zh/ini.core.php#ini.memory-limit)设置的更大些(默认128M),upload_max_filesize与post_max_size不要超过memory_limit的值 **max_file_uploads**:上传文件数量(默认20) 如果[max_execution_time](http://php.net/manual/zh/info.configuration.php#ini.max-execution-time)(脚本执行的最大时间,默认30s)设置的值太小,脚本运行的时间可能会超过该设置。因此,也请保证*max_execution_time*足够的大。 >[danger] **注意**:[max\_execution\_time](http://php.net/manual/zh/info.configuration.php#ini.max-execution-time)仅仅只影响脚本本身运行的时间。任何其它花费在脚本运行之外的时间,诸如用函数[system()](http://php.net/manual/zh/function.system.php)对系统的调用、[sleep()](http://php.net/manual/zh/function.sleep.php)函数的使用、数据库查询、文件上传等,在计算脚本运行的最大时间时都不包括在内。 **Warning** [max_input_time](http://php.net/manual/zh/info.configuration.php#ini.max-input-time)以秒为单位设定了脚本接收输入(类似get、post)的最大时间,包括文件上传。对于较大或多个文件,或者用户的网速较慢时,可能会超过默认的*60 秒*。 不对正在操作的文件进行验证可能意味着用户能够访问其它目录下的敏感信息。 确保php.ini的配置file_uploads是开启的`file_uploads = On` ~~~ <html> <body> <form action="upload_file.php" method="post" enctype="multipart/form-data"> <label for="file">Filename:</label> <input type="file" name="file" id="file" /> <input type="hidden" name="MAX_FILE_SIZE" value="2000" /> <br /> <input type="submit" name="submit" value="Submit" /> </form> </body> </html> ~~~ upload\_file.php: ~~~ var_dump($_FILES);//array(1) { ["fieldname"]=> array(5) { ["name"]=> string(5) "1.jpg" ["type"]=> string(10) "image/jpeg" ["tmp_name"]=> string(24) "D:\xampp\tmp\phpACE5.tmp" ["error"]=> int(0) ["size"]=> int(13789) } }  if(is_uploaded_file($tmp_name = $_FILES['fieldname']['tmp_name'])){  $newdirpath = dirname(__FILE__); $name=$_FILES['fieldname']['name']; $name = time().'xxxxx'.$name; move_uploaded_file($tmp_name, "$newdirpath/$name");  } ~~~ 保存临时文件:move_uploaded_file 当上传文件时php会将会生成一个临时文件,但执行完毕时会将这个临时文件删除,所以我们需要move_uploaded_file永久保存上传的文件 is_uploaded_file() 函数判断指定的文件是否是通过 HTTP POST 上传的 windows10的temp文件可能有权限问题,若有,需要修改上传临时文件地址 修改上传的临时文件地址 修改php.ini中的upload\_tmp\_dir的文件目录 单文件上传 ``` <?php //var_dump($_FILES); $rootpath = 'http://localhost/atest/php/head'; //构建临时文件并quiet判断是否是http post上传 if(is_uploaded_file($tmp_name = $_FILES['fieldname']['tmp_name'])){ //判断错误 if($_FILES['fieldname']['error'] !=0){ switch ($_FILES['fieldname']['error']) { case 1: echo '上传到文件超过了php.ini中设置的upload_max_filesize的值'; break; case 2: echo '上传的文件大小超过了HTML表单中MAX_FILE_SIZE选项限定的值'; break; case 3: echo '文件只有部分被上传'; break; case 4: echo '没有文件被上传'; break; case 6: echo '找不到临时文件'; break; case 7: echo '文件写入失败'; break; default: echo '未知错误!'; break; } } //判断文件大小get_cfg_var或者ini_get都可以获取到ini的配置 $upload_max_filesize=get_cfg_var('upload_max_filesize');//上传允许的单文件的最大值 $post_max_size=ini_get('post_max_size');//上传所有文件字节允许的最大值 $max_file_uploads=ini_get('max_file_uploads');//上传文件的允许最大数量 if($_FILES['fieldname']['size'] > return_bytes($upload_max_filesize)){ echo '文件的大小超过了上传允许的单文件的最大值'; } //设置允许上传的文件类型 $arr_ext = ['image/jpeg','image/png','application/zip']; //利用php_fileinfo.dll对MIME类型进行严格检查在php.ini开启 $fs = finfo_open(FILEINFO_MIME_TYPE);// 创建一个返回 mime 类型的资源 $mime = finfo_file($fs,$_FILES['fieldname']['tmp_name']);//返回上传临时文件的mime类型 // 判断是否包括当前文件类型 if (!in_array($mime,$arr_ext)) { die('上传的文件类型错误'); } //获取文件扩展名:至少有7种以上的方法自行百度 $ext = strchr($_FILES['fieldname']['name'],'.'); $customdir=strtotime(date('Y-m-d',time())); $newdirpath = dirname(__FILE__).'/uploads/'.$customdir; //判断文件夹是否存在不存在新建他 if(!is_dir($newdirpath)){ $re = mkdir($newdirpath,0777,true); if(!$re){ die('目录新建不成功'); } } //$name=$_FILES['fieldname']['name'];原文件名 $newname =uniqid().$ext; $uploadfile=$newdirpath.'/'.$newname; //移动临时文件并保存为永久文件 $result = move_uploaded_file($tmp_name, $uploadfile); if(!$result){ die('上传移动临时文件失败!!'); }else{ echo '上传成功'; var_dump($uploadfile); echo '<div><img src=./uploads/'.$customdir.'/'.$newname.'></div>'; } }else{ header('location:http://localhost/atest/php/head/'); die('请上传文件!'); } /** * [return_bytes 返回给定的字节] * 注意这里的swith没有break;他会重命中的时候一直执行下去 * @param [string] $val [给定的k(千字节), M,G,...] * @return [int] [返回字节整数] */ function return_bytes($val) { //取出空格 $val = trim($val); //获取字符串最后一个索引并且strtolower转小写 $last = strtolower($val[strlen($val)-1]); switch($last) { case 'g': $val *= 1024; case 'm': $val *= 1024; case 'k': $val *= 1024; } return $val; } ``` **多文件上传** ``` <?php $rootpath = 'http://localhost/atest/php/head'; if($_FILES['fieldname']){ $fieldname=$_FILES['fieldname']; if(count($fieldname['tmp_name']) > 1){ $upload_max_filesize=get_cfg_var('upload_max_filesize');//上传允许的单文件的最大值 $post_max_size=ini_get('post_max_size');//上传所有文件字节允许的最大值 $max_file_uploads=ini_get('max_file_uploads');//上传文件的允许最大数量 //设置允许上传的文件类型 $arr_ext = ['image/jpeg','image/png','application/zip']; //利用php_fileinfo.dll对MIME类型进行严格检查在php.ini开启 $fs = finfo_open(FILEINFO_MIME_TYPE);// 创建一个返回 mime 类型的资源 $customdir=strtotime(date('Y-m-d',time())); $newdirpath = dirname(__FILE__).'/uploads/'.$customdir; //判断文件夹是否存在不存在新建他 if(!is_dir($newdirpath)){ $re = mkdir($newdirpath,0777,true); if(!$re){ die('目录新建不成功'); } } //随便循环一个将 三维数组变为2维 以得到key $totalsize=''; foreach ($fieldname['tmp_name'] as $key => $tmpfile) { //判断是否是HTTP POST上传的 if(is_uploaded_file($fieldname['tmp_name'][$key])){ //判断错误 if($_FILES['fieldname']['error'][$key] !=0){ switch ($_FILES['fieldname']['error']) { case 1: echo $fieldname['name'][$key].'上传到文件超过了php.ini中设置的upload_max_filesize的值'; break; case 2: echo $fieldname['name'][$key].'上传的文件大小超过了HTML表单中MAX_FILE_SIZE选项限定的值'; break; case 3: echo $fieldname['name'][$key].'文件只有部分被上传'; break; case 4: echo $fieldname['name'][$key].'没有文件被上传'; break; case 6: echo $fieldname['name'][$key].'找不到临时文件'; break; case 7: echo $fieldname['name'][$key].'文件写入失败'; break; default: echo $fieldname['name'][$key].'未知错误!'; break; } } //构建临时文件 $tmp_file=$tmpfile; //判断文件大小get_cfg_var或者ini_get都可以获取到ini的配置 if($fieldname['size'][$key] > return_bytes($upload_max_filesize)){ echo '文件的大小超过了上传允许的单文件的最大值'; } if(count($fieldname['tmp_name']) > return_bytes($max_file_uploads)){ echo '文件数量超过上传文件的允许最大数量'; } $totalsize += $fieldname['size'][$key]; //返回上传临时文件的mime类型 $mime = finfo_file($fs,$tmpfile); // 判断是否包括当前文件类型 if (!in_array($mime,$arr_ext)) { die('上传的'.$fieldname['name'][$key].'文件类型错误'); } //获取文件扩展名:至少有7种以上的方法自行百度 $ext = strchr($fieldname['name'][$key],'.'); //$name=$_FILES['fieldname']['name'];原文件名 $newname =uniqid().$ext; $uploadfile=$newdirpath.'/'.$newname; //移动临时文件并保存为永久文件 $result = move_uploaded_file($tmpfile, $uploadfile); if(!$result){ die('上传移动临时文件失败!!'); }else{ echo '上传成功'; var_dump($uploadfile); echo '<div><img src=./uploads/'.$customdir.'/'.$newname.'></div>'; } }else{ header('location:http://localhost/atest/php/head/'); die('非法文件'); } } if($totalsize > return_bytes($post_max_size)){ echo '所有上传文件的大小超过了允许的最大值'; } }else{ die('多文件上传不应该出现的这个未知错误'); } }else{ header('location:'.$rootpath); } /** * [return_bytes 返回给定的字节] * 注意这里的swith没有break;他会重命中的时候一直执行下去 * @param [string] $val [给定的k(千字节), M,G,...] * @return [int] [返回字节整数] */ function return_bytes($val) { //取出空格 $val = trim($val); //获取字符串最后一个索引并且strtolower转小写 $last = strtolower($val[strlen($val)-1]); switch($last) { case 'g': $val *= 1024; case 'm': $val *= 1024; case 'k': $val *= 1024; } return $val; } ```