zoukankan      html  css  js  c++  java
  • 【菜鸟学php】用菜鸟的眼光浅谈php上传文件

    本人菜鸟一枚,以下内容如有不当之处,劳烦指正。

    本人由于想写个discuz插件,这个插件功能上涉及到上传文件这一功能,故以菜鸟的眼光来学习了下php上传文件。

    首先,w3cshool查了下案例,觉得他说的非常详细,连我这个菜鸟都略懂了一二。

    贴上地址:http://www.w3school.com.cn/php/php_file_upload.asp

    照着这个讲解,写了下他这个demo,贴上代码:

    html:

    <form action="demo.php" method="post" enctype="multipart/form-data">
        <label for="file">Filename:</label>
        <input type="file" name="file" id="file">
        <br/>
        <input type="submit" name="submit" value="Submit"/>
    </form>

    这个表单页,作为php菜鸟的我说下我在这个里面学到的新东西:

    1.form的属性enctype,百度翻译了下这个单词,才知道,这个是encode type 的缩写,就是指定往服务器传递信息的编码格式;

    2.input的type属性file,这个专用文件上传的;

    php:

    //echo phpinfo();
    //var_dump($_FILES);die;
    
    if((($_FILES["file"]["type"]=="image/gif")||($_FILES["file"]["type"]=="image/jpeg")||($_FILES["file"]["type"]=="image/pjpeg")) && ($_FILES["file"]["size"]<100*1024*1024)){
        if($_FILES["file"]["error"]>0){
            echo "Error: ".$_FILES["file"]["error"]."<br/>";
        }else{
            echo "Upload: ".$_FILES["file"]["name"]."<br/>";
            echo "Type: ".$_FILES["file"]["type"]."<br />";
            echo "Size: ".($_FILES["file"]["size"]/1024)."Kb<br />";
            echo "Stored in ".$_FILES["file"]["tmp_name"];
        }
        
        if(file_exists("upload/".$_FILES["name"]["name"])){
            echo $_FILES["file"]["name"]."already exists.";
        }else{
            move_uploaded_file($_FILES["file"]["tmp_name"],"upload/".$_FILES["file"]["name"]);
            echo "Stored in: "."upload/".$_FILES["file"]["name"];
        }
    }else{
        echo "Invalid file";
    }

    关于调试这个demo的时候,我遇到一个问题:就是运行这个demo的时候php报出warning,表示上传不成功。

    这个时候我就想打印出$_FILES这个变量来看看,结果打印出来发现error=1;才知道上传的文件超过了php.ini的上传文件大小,导致上传失败。

    这里说下俺新了解的知识点:

      
      PHP编程语言中的常见的$_FILES 系统函数用法有:
      $_FILES['myFile']['name'] 显示客户端文件的原名称。
      $_FILES['myFile']['type'] 文件的 MIME 类型,例如"image/gif"。
      $_FILES['myFile']['size'] 已上传文件的大小,单位为字节。
      $_FILES['myFile']['tmp_name'] 储存的临时文件名,一般是系统默认。
      $_FILES['myFile']['error'] 该文件上传相关的错误代码。以下为不同代码代表的意思:
      0; 文件上传成功。
      1; 超过了文件大小php.ini中即系统设定的大小。
      2; 超过了文件大小
      MAX_FILE_SIZE 选项指定的值。
      3; 文件只有部分被上传。
      4; 没有文件被上传。
      5; 上传文件大小为0。
     
    到这里,应该就知道了我刚刚运行demo的错误是啥导致的,那既然发现是php.ini里面限制超出了,那接下来我就修改了下php.ini的配置。
     
    总结下我修改这个php.ini上传限制的感受:
    首先,要修改php上传文件大小限制,那要改php.ini里面的两个参数,一个是upload_max_filesize,还有个就是post_max_size,修改下这两个参数的大小就可以了!
    其次,就是找准php.ini的位置,我由于本地电脑搭建的是集成环境,所以php.ini在apache文件夹下面,如果是自己搭建的环境,那就在php文件夹下面,如果找不到,echo下phpinfo(),可以看到php.ini文件的位置。
     
    那到此为止,跟我差不多的新手们就能运行w3cshool上面的demo了,完成上传实例了。
     
    关于上传文件,我看了下discuz其他插件作者开发的插件,有点小收获,贴上来跟大家分享下:
       $fileTypes  = array('mp3','wav');    //定义允许上传的文件类型
        $result     = null;
        $uploadDir  = './mail';        //上传路径
        if(!submitcheck($_POST['formhash2'])){    //检测是否是上传文件
            if($_POST['upname']==''){    //判断上传文件的命名是否为空
                $result=lang('plugin/saya_mails', 'noname');
            }else{
                    $myfile = $_FILES['myfile'];    //获取上传的文件信息
                    $myfileType = substr($myfile['name'], strrpos($myfile['name'], ".") + 1);    //两种获取上传文件的后缀名
                //    $myfileTyle = substr(strrchr($myfile['name'],'.'),1);
                    if ($myfile['size'] > 1024*1024*1024) {    //判断上传文件大小是否超过限制
                        $result = lang('plugin/saya_mails', 'big');
                    } else if (!in_array($myfileType, $fileTypes)) {    //判断是否是允许上传的类型
                        $result = lang('plugin/saya_mails', 'type');
                    } elseif (is_uploaded_file($myfile['tmp_name'])) {    //判断是否是通过HTTP post上传的文件
                        $toFile = './source/plugin/saya_mails/mail/' . $myfile['name'];        //目标存储地址
                        if (@move_uploaded_file($myfile['tmp_name'], $toFile)) {    //将文件拷贝到目标存储地址     //这个地方加@是屏蔽错误信息和警告
    //                    if (copy($myfile['tmp_name'],$toFile)) {
                            $end=0;
                            $result = lang('plugin/saya_mails', 'success');  
                        } else {
                            $result = lang('plugin/saya_mails', 'unknow');
                        }
                    } else {
                        $result = lang('plugin/saya_mails', 'big');
                    }
        }
      }

     对比了下,w3cshool上面的上传实例,觉得这个作者写的更完善一点

    大体流程就是:

      1.判断是否是上传文件,他用的这个方法是discuz自带的,我们一般用,就是form传递过来的隐藏参数的值存不存在来进行判断;

      2.判断上传文件的命名是否为空,这一步大家可以跳过,这个是他自己写了个input而已;

      3.判断上传大小是否超出;

      4.获取文件后缀名,判断是否是允许的上传文件类型;

      5.判断文件是否是通过http post上传的;

      6.移动保存文件;

    关于以上流程,个人总结了下自己获得的新的知识点:

      1.关于获取文件的后缀名,原插件作者是通过函数strrpos()来返回"."所在的位置,然后通过截取函数substr()来获得上传文件的后缀。

       这里,strrpos()函数,我自己的理解应该是string return position的缩写,当然我还没查证过!这个函数是返回字符串里要查找的字符串最后出现的位置,并返回这个位置。也就是从后往前查,第一次出现的位置。参考地址:http://www.w3school.com.cn/php/func_string_strrpos.asp

         这里原作者用这个方法来判断,肯定是可以的,我百度了下,发现也可以用strrchr()和substr()函数合作来实现这个方法,我把我想的方法注释在了上面源代码里面了,其实差不多,strrchr()函数就是返回最后一次出现的要查找的字符串到结尾的字符串,参考地址:http://www.w3school.com.cn/php/func_string_strrchr.asp

        通过以上两种方法来判断上传文件的类型是否达标,而不是通过$_FILES["file"]["type"]来判断,这样更好判断点,对于新手,因为只要你打印下$_FILES这个参数你就知道了,type属性没这么判断来的清晰明了。

      2.通过is_uploaded_file()来判断文件是否是通过http上传的

      3.move_uploaded_file()前面的@是用来屏蔽错误信息和警告的

    到此为止是小弟的一些个人理解,不足忘指正!

  • 相关阅读:
    python 函数function
    安装python 第三方库遇到的安装问题 microsoft visual studio c++ 10.0 is required,Could not find function xmlCheckVersion in library libxml2. Is libxml2 installed?
    Pandas库入门
    pyplot基础图表函数概述
    Matplotlib库介绍
    Numpy数据存取与函数
    NumPy库入门
    css3知识
    HTML标签marquee实现滚动效果
    JQuery导航选择特效
  • 原文地址:https://www.cnblogs.com/discuzz/p/3549297.html
Copyright © 2011-2022 走看看