• PHP回顾(4)文件相关函数


    • touch()          创建文件 (修改时间,不存在时创建)  
    • copy()            复制文件,复制过程中可以修改文件名
    • rename()        重命名 或  移动文件  不能移动目录
    • unlink()           删除文件
    • file_exists()      判断文件是否存在
    • filesize()         获取文件大小
    • is_file()           判断是否是文件
    • fopen()           以什么方式打开文件,第二参数以什么方式打开    r w a(追加写入)  x(文件不存在新建,存在则报错,异或)
    • fclose()          关闭文件
    • fread()             读取文件内容,
    • feof()             判断指针是否读到文件结尾
    • fwrite()
    • file()               把整个文件读入一个数组中,file ( string $filename [, int $flags = 0 [, resource $context ]] ) : array,Returns the file in an array. Each element of the array corresponds to a line in the file, with the newline still attached. Upon failure, file()returns FALSE.
    • file_put_contents()               FILE_APPEND(追加写入)
    • file_get_contents()               字符串形式获取文件的内容

    目录相关

    • opendir()           
    • readdir()
    • closedir()
    • mkdir()                            想要嵌套创建目录,需要加参数                    第二个 0777    第三个true表示允许嵌套创建
    • rmdir()           只能删除空目录
    • is_dir()

    文件上传

    1. 从客户端选择文件,通过网络上传到服务器,为了防止病毒等,会把文件先存在服务器的临时目录tmp中(在这个临时目录中的文件都是不能执行的),当脚本运行结束时,临时目录中的文件会被删除。所以需要在脚本结束前,把上传的文件从临时目录中移动到指定的目录中,才成功实现文件上传。
    2. 文件上传表单需要加上   enctype="multipart/form-data"   ,文件信息存储在$_FILES超全局数组,是个二维数组
    3. 上传文件考虑几个问题: (1)根据错误号  error  判断文件是否成功上传到服务器的临时目录中;
      (2)文件的类型是否符合要求
      (3)文件大小是否符合要求
      (4)上传多个文件时,可能会出现重名,为避免重名需要给文件重命名;
      (5)创建保存文件的目录
      (6)然后把文件从临时目录中移到新目录中保存
    4. 文件上传相关的配置选项:
      upload_max_filesize    允许上传的文件最大值
      file_uploads=on            允许文件上传
      upload_tmp_dir            文件上传的临时目录
      max_file_uploads        允许上传的文件个数  (php.ini 默认配置是20,所以即便后端接收了40个文件,但最后上传成功的一定是20个。想要上传成功80个,需要将此项改为80,同时要注意文件的大小限制)
      post_max_size             post最大传输内容(包括文件还有其他信息)
      max_excution_time      文件上传的时间限制,  0表示没有限制,   # 默认设置30秒, 这设置了脚本被解析器中止之前允许的最大执行时间,单位秒。 这有助于防止写得不好的脚本占尽服务器资源。在 安全模式 下你不能通过 ini_set() 来修改此设置。 唯一的解决方法是关闭安全模式或者在 php.ini 中修改时间限制。
      max_input_time           脚本解析输入数据(类似 POST 和 GET)允许的最大时间,单位是秒。 它从接收所有数据到开始执行脚本进行测量的.
    5. 在lnmp环境下, PHP上传文件失败, 基本上就几个原因:
      (1) upload_max_filesize设置的值过小, 导致文件上传不上去, 服务器端打印$_FILES数组就会是null   # 默认只有2m  还发现一点: 文件大小的限制是针对多个文件的, 比如说上传两个文件, 那么 如果这两个文件的总和大于了配置文件设置的值, 仍然会上传失败
      (2) post_max_size 设置的过小  # 默认只有8m
      (3) upload_tmp_dir 设置了自定义的目录, 却没有赋予这个目录读写权限,  # 这个默认是注释掉的, 默认使用系统的临时目录,  具体是哪个目录还没研究...  如果是注释掉的话, 那么一般情况下是没有问题的, (找到了, Linux系统 cd / 在根目录下有一个tmp目录,嗯, 应该就是他了)
      (4) memory_limit  内存不够用,  # 不过系统默认值为 -1 ,就是不限制,  可以设置其他值   (https://segmentfault.com/q/1010000010591073)这个里面说了一个stripos函数导致文件上传内存会翻倍的问题, 需要memory_limit设置更大.
      (5) nginx的配置文件没有设置client_max_body_size, 需要设置 这个值, 比如 client_max_body_size  100m;   
      (6) 其余的几个相关的参数都是系统默认的 file_uploads=on  #默认开启, 排查的时候也要看一下, 万一系统默认关闭 

    文件下载

    (1)header('content-type:image/jepg');   //指定下载的文件 类型  当不知道要下载的文件类型时,省略这行代码
    (2)header('content-disposition:attachment;filename="abc.jpeg" ');    //对下载文件进行描述,并指定文件下载后的名称
    (3)readfile('./statics/a.jpeg');   //,给定路径,读取要下载的文件

    当浏览器是IE的时候,可能出现文件名乱码,需要再写一行代码     iconv('转换前的字符集','想要转换的字符集','要转换的内容');

    自定义文件上传函数(多文件上传时,需要在表单加上  multiple="multiple"     name属性值设置数组)

     1 <?php
     2 
     3 
     4 /**
     5  * @param 文件上传页面file表单的name值
     6  * @param 上传文件后的新目录
     7  * @param 文件类型
     8  * @param 文件大小
     9  * @return 上传后的信息
    10  */
    11 //文件上传函数就是处理客户端上传到服务器临时目录的文件
    12 function uploadFile($fileName,$path='./uploads',$arr=['image/jpeg','image/png','image/jpg'],$filesize=1000000)
    13 {
    14     $file = $_FILES[$fileName];
    15     if($file['error']>0)
    16     switch($file['error']){
    17         case 1:
    18         case 2:
    19             return '文件过大';
    20         case 3:
    21             return '上传文件不完整,请重新上传';
    22         case 4:
    23             return '请选择文件';
    24         case 6:
    25             return 'tmp不存在';
    26         case 7:
    27             return '没有权限';
    28         case 8:
    29             return '........';
    30     }
    31     //判断文件类型是否合法
    32     if(!in_array($file['type'], $arr)){
    33         return '上传的文件类型不合法';
    34     }
    35     //判断文件大小
    36     if($file['size']>$filesize){
    37         return '上传文件过大';
    38     }
    39     
    40     //创建存放文件的新目录
    41     if(!file_exists($path)){
    42         mkdir($path);
    43     }
    44     //把文件重命名,,,,,想了想必须得先创建目录,不然没法判断文件名是否已存在,给他一个文件路径file_exists才能找到文件
    45     //先获取文件后缀
    46     $suffix = strrchr($file['name'],'.');
    47     //如果传的$path参数后面带有/或,需要删除掉
    48     $path = rtrim($path,'/\');
    49     do{
    50         //生成一个新的文件名,并拼接后缀
    51         $newFileName = md5(mt_rand(1000,9999).uniqid()).$suffix;
    52         $newPath = $path.'/'.$newFileName;
    53     }while(file_exists($newPath));
    54     
    55     //移动到新目录,使用move_uploaded_file还可以判断是不是post传过来的
    56     if(move_uploaded_file($file['tmp_name'],$newPath)){
    57         return '上传文件成功';
    58     }else{
    59         return '上传失败,请重新上传';
    60     }
    61 }
    62     $res = uploadFile('pic','./statics/');
    63     echo '<pre>';
    64     print_r($res);
    View Code

     文件上传类(多文件或单文件都可以)

      1 <?php
      2     //能够实现多文件上传,也可以单文件上传
      3     class Upload
      4     {    
      5         //文件上传表单的name属性值
      6         private $fileName;
      7         //文件上传后,创建的保存路径
      8         private $path;
      9         //文件的类型
     10         private $type;
     11         //文件大小
     12         private $size;
     13         //用于接收遍历后的文件
     14         private $files = [];
     15 
     16         //初始化  注意:如果用户传的路径是嵌套的,需要给mkdir()传第二个和第三个参数
     17         public function __construct($fileName,$path='./statics/images',$size=1500000,array $type=['image/jpeg','image/png','image/jpg','image/gif'])
     18         {
     19             $this->fileName = $fileName;
     20             $this->path = $path;
     21             $this->type = $type;
     22             $this->size = $size;
     23         }
     24 
     25         //为避免可能出现用户上传的是单文件却调用多文件处理方法的错误,新进行判断用户上传的文件是不是三维数组is_array($_FILES['pic']['name'])
     26         public function uploadFile()
     27         {
     28             //这个判断也可可以写在uploads 和 upload 方法里判断
     29             if(is_array($_FILES['pic']['name'])){
     30                 echo $this->uploads();  //输出信息
     31             }else{
     32                 echo $this->upload();  
     33             }
     34         }
     35 
     36         //用户上传多文件时调用此方法。
     37         public function uploads()
     38         {
     39             //其实多文件上传时,就是遍历一遍,然后在每次遍历的时候,把error,type,size都判断一次
     40             //每遍历一次就把所有单文件上传的步骤执行一次
     41             foreach($_FILES[$this->fileName]['name'] as $k=>$v){
     42                 $this->files['name'] = $v;
     43                 $this->files['type'] = $_FILES[$this->fileName]['type'][$k];
     44                 $this->files['tmp_name'] = $_FILES[$this->fileName]['tmp_name'][$k];
     45                 $this->files['error'] = $_FILES[$this->fileName]['error'][$k];
     46                 $this->files['size'] = $_FILES[$this->fileName]['size'][$k];
     47                 //把那些方法都调用一遍,判断必须判断类型,否则返回的错误信息也会转换成真
     48                 if($this->fileError()!==true){
     49                     echo $this->fileError();      //输出返回的错误信息
     50                 }elseif($this->fileType()!==true){
     51                     echo $this->fileType();
     52                 }elseif($this->fileSize()!==true){
     53                     echo $this->fileSize();
     54                 }else{
     55                     echo $this->moveImg();
     56                 }
     57             }
     58         }
     59 
     60         //当用户是单文件上传时,调用此方法
     61         public function upload()
     62         {
     63             //单文件上传把所有步骤都写在这一个方法里
     64             $file = $_FILES[$this->fileName];
     65             //判断错误号
     66             if($file['error']>0){
     67                 switch($file['error']){
     68                     case 1:
     69                     case 2:
     70                         return '文件过大';
     71                     case 3:
     72                         return '上传文件不完整,请重新上传';
     73                     case 4:
     74                         return '请选择文件';
     75                     case 6:
     76                         return 'tmp不存在';
     77                     case 7:
     78                         return '没有权限';
     79                 }
     80             }
     81             //判断文件类型
     82             if(!in_array($file['type'],$this->type)){
     83                 return '上传文件类型不合法';
     84             }
     85             //判断文件大小
     86             if($file['size']>$this->size){
     87                 return '上传文件过大,请压缩后上传';
     88             }
     89             //判断保存文件的目录是否存在
     90             if(!file_exists($this->path)){
     91                 mkdir($this->path,0777,true);  //可以递归创建目录
     92             }
     93             //过滤用户可能传进的/ 
     94             $this->path = rtrim($this->path,'/\');
     95             //获取文件后缀
     96             $suffix = strrchr($file['name'],'.');
     97             do{
     98                 $newPath = $this->path.'/'.md5(time().mt_rand(100,999).uniqid()).$suffix;
     99             }while(file_exists($newPath));
    100             if(move_uploaded_file($file['tmp_name'],$newPath)){
    101                 return '<font color="green">上传文件成功</font>';
    102             }else{
    103                 return '<font color="red">上传文件失败</font>';
    104             }
    105         }
    106 
    107         //判断错误号
    108         private function fileError()
    109         {
    110             if($this->files['error']>0){
    111                 switch($this->files['error']){
    112                     case 1: return '上传的文件超过了 php.ini 中 upload_max_filesize选项限制的值';
    113                     case 2: return '上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值';
    114                     case 3: return '文件只有部分被上传';
    115                     case 4: return '没有文件被上传';
    116                     case 6: return '找不到临时文件夹';
    117                     case 7: return '文件写入失败';
    118                 }
    119             }
    120             return true;
    121         }
    122 
    123         //判断文件类型是否合法
    124         private function fileType()
    125         {
    126             if(!in_array($this->files['type'],$this->type)){
    127                 return '上传类型不合法';
    128             }
    129             return true;
    130         }
    131 
    132         //判断上传文件大小是否合法
    133         private function fileSize()
    134         {
    135             if($this->files['size']>$this->size){
    136                 return '上传文件过大,请压缩后上传';
    137             }
    138             return true;
    139         }
    140 
    141         //从临时目录中移出
    142         private function moveImg()
    143         {
    144             //判断保存文件的目录是否存在
    145             if(!file_exists($this->path)){
    146                 mkdir($this->path,0777,true);
    147             }
    148             //用户传路径的时候可能会多/   过滤掉
    149             $this->path = rtrim($this->path,'/\');
    150             //获取文件后缀
    151             $suffix = strrchr($this->files['name'],'.'); 
    152             //重命名文件
    153             do{
    154                 $newPath = $this->path.'/'.md5(time().mt_rand(100,999).uniqid()).$suffix;
    155             }while(file_exists($newPath));
    156             //移动文件
    157             if(move_uploaded_file($this->files['tmp_name'],$newPath)){
    158                 return '<font color="green">上传文件成功</font>';
    159             }else{
    160                 return '<font color="red">上传文件失败</font>';
    161             }
    162         }
    163     }
    View Code

     验证码类

    <?php
    class Code{
        private $width;
        private $height;
        private $codeNum;
        private $fontFamily;
        private $image;
        private $font;
    
        //成员属性
        function __construct($fontFamily='',$width=100,$height=40,$codeNum=4){
            session_start();
            $this->fontFamily=$fontFamily;
            $this->width=$width;
            $this->height=$height;
            $this->codeNum=$codeNum;
        }
    
        function __tostring(){
            $this->getCreateImg();
            $this->setPixel();
            $this->setLine();
            $this->setChar();
            $this->outputImg();
            $_SESSION['code']=$this->font;
            return '';
        }
    
        private function getCreateImg(){
            $this->image=imagecreatetruecolor($this->width,$this->height);
            $back=imagecolorallocate($this->image,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255));
            imagefill($this->image,0,0,$back);
            $borderColor=imagecolorallocate($this->image,255,0,0);
            imagerectangle($this->image,0,0,$this->width-1,$this->height-1,$borderColor);
    
        }
    
    
        private function setPixel(){
            for($i=0;$i<299;$i++){
                $pixelColor=imagecolorallocate($this->image,mt_rand(150,200),mt_rand(150,200),mt_rand(150,200));
                imagesetpixel($this->image,mt_rand(2,$this->width-2),mt_rand(2,$this->height-2),$pixelColor);
            }
        }
    
        private function setLine(){
            for($i=0;$i<5;$i++){
                $lineColor=imagecolorallocate($this->image,mt_rand(180,200),mt_rand(180,200),mt_rand(180,200));
                imageline($this->image,mt_rand(2,$this->width-2),mt_rand(2,$this->height-2),mt_rand(2,$this->width-2),mt_rand(2,$this->height-2),$lineColor);
            }
        }
    
        private function setChar(){
            $str='3456789ABCDEFGHJKLMNPQRSTUVWXYabcdefghijkmnpqrstuvwxyz';
            for($i=0;$i<$this->codeNum;$i++){
                $this->font.=$str{mt_rand(0,strlen($str)-1)};
            }
            if($this->fontFamily==''){
                for($i=0;$i<strlen($this->font);$i++){
                    $fontColor=imagecolorallocate($this->image,mt_rand(0,120),mt_rand(0,120),mt_rand(0,120));
                    $x=$this->width/$this->codeNum*$i+mt_rand(3,7);
                    $y=mt_rand(10,$this->height/2);
                    imagechar($this->image,mt_rand(3,5),$x,$y,$this->font{$i},$fontColor);
    
                }
            }else{
                for($i=0;$i<strlen($this->font);$i++){
                        $fontColor = imagecolorallocate($this->image,mt_rand(0,120),mt_rand(0,120),mt_rand(0,120));
                        $x = $this->width/$this->codeNum * $i + mt_rand(5,8);
                        $y = mt_rand($this->height/2,$this->height);
                        imagettftext($this->image,mt_rand($this->height/3,$this->height/2),mt_rand(0,45),$x,$y,$fontColor,$this->fontFamily,$this->font{$i});
                }
            }
        }
    
        private function outputImg(){
                header('Content-type:image/jpeg');
                imagejpeg($this->image);
        }
    
            //6.释放资源  析构方法
        function __destruct(){
                //imagedestroy($this->image);
                //imagedestroy($this->image);
                imagedestroy($this->image);
        }
    }
    View Code

    Returns the file in an array. Each element of the array corresponds to a line in the file, with the newline still attached. Upon failure, file()returns FALSE.

    Note:

  • 相关阅读:
    Kubebuilder简介与架构
    Flutter: 解决iOS真机时Can't load Kernel binary: Invalid kernel binary format version.和安装ipa闪退的问题
    Flutter: 解决WebView无法打开非SSL页面的问题
    在Windows上用getopt
    centos8 启动一个 caddy 作为文件服务器
    python print 在同一行覆盖打印
    CentOS8 修改国内镜像源
    docker 批处理操作
    基于 docker inspect + Python 反向生成容器启动命令
    升级gcc版本
  • 原文地址:https://www.cnblogs.com/bneglect/p/10527022.html
Copyright © 2020-2023  润新知