zoukankan      html  css  js  c++  java
  • 16.ThinkPHP 文件上传

    框架上传功能

    上传文件

    内置的上传只是上传到本地服务器,上传到远程或者第三方平台的话需要自己扩展。

    假设表单代码如下:

    <form action="/index/index/upload" enctype="multipart/form-data" method="post">
    <input type="file" name="image" /> <br> 
    <input type="submit" value="上传" /> 
    </form> 
    

    然后在控制器中添加如下的代码:

    public function upload(){
        // 获取表单上传文件 例如上传了001.jpg
        $file = request()->file('image');
        // 移动到框架应用根目录/uploads/ 目录下
        $info = $file->move( '../uploads');
        if($info){
            // 成功上传后 获取上传信息
            // 输出 jpg
            echo $info->getExtension();
            // 输出 20160820/42a79759f284b767dfcb2a0197904287.jpg
            echo $info->getSaveName();
            // 输出 42a79759f284b767dfcb2a0197904287.jpg
            echo $info->getFilename(); 
        }else{
            // 上传失败获取错误信息
            echo $file->getError();
        }
    }
    

    move方法成功的话返回的是一个 hinkFile对象,你可以对上传后的文件进行后续操作。

    多文件上传

    如果你使用的是多文件上传表单,例如:

    <form action="/index/index/upload" enctype="multipart/form-data" method="post">
    <input type="file" name="image[]" /> <br> 
    <input type="file" name="image[]" /> <br> 
    <input type="file" name="image[]" /> <br> 
    <input type="submit" value="上传" /> 
    </form> 
    

    控制器代码可以改成:

    public function upload(){
        // 获取表单上传文件
        $files = request()->file('image');
        foreach($files as $file){
            // 移动到框架应用根目录/uploads/ 目录下
            $info = $file->move( '../uploads');
            if($info){
                // 成功上传后 获取上传信息
                // 输出 jpg
                echo $info->getExtension(); 
                // 输出 42a79759f284b767dfcb2a0197904287.jpg
                echo $info->getFilename(); 
            }else{
                // 上传失败获取错误信息
                echo $file->getError();
            }    
        }
    }
    

    上传验证

    支持对上传文件的验证,包括文件大小、文件类型和后缀:

    public function upload(){
        // 获取表单上传文件 例如上传了001.jpg
        $file = request()->file('image');
        // 移动到框架应用根目录/uploads/ 目录下
        $info = $file->validate(['size'=>15678,'ext'=>'jpg,png,gif'])->move( '../uploads');
        if($info){
            // 成功上传后 获取上传信息
            // 输出 jpg
            echo $info->getExtension();
            // 输出 20160820/42a79759f284b767dfcb2a0197904287.jpg
            echo $info->getSaveName();
            // 输出 42a79759f284b767dfcb2a0197904287.jpg
            echo $info->getFilename(); 
        }else{
            // 上传失败获取错误信息
            echo $file->getError();
        }
    }
    

    getSaveName方法返回的是图片的服务器文件地址,并不能直接用于图片的URL地址,尤其在windows平台上必须做转换才能正常显示图片。

    如果上传文件验证不通过,则move方法返回false。

    验证参数 说明
    size 上传文件的最大字节
    ext 文件后缀,多个用逗号分割或者数组
    type 文件MIME类型,多个用逗号分割或者数组

    还有一个额外的自动验证规则是,如果上传的文件后缀是图像文件后缀,则会检查该文件是否是一个合法的图像文件。

    上传错误提示信息支持多语言,你可以修改语言包来修改错误提示。

    上传规则

    默认情况下,会在上传目录下面生成以当前日期为子目录,以微秒时间的md5编码为文件名的文件,例如上面生成的文件名可能是:

    /home/www/uploads/20160510/42a79759f284b767dfcb2a0197904287.jpg
    

    我们可以指定上传文件的命名规则,使用rule方法即可,例如:

    // 获取表单上传文件 例如上传了001.jpg
    $file = request()->file('image');
    // 移动到服务器的上传目录 并且使用md5规则
    $file->rule('md5')->move('../uploads/');
    

    最终生成的文件名类似于:

    application/uploads/72/ef580909368d824e899f77c7c98388.jpg
    

    系统默认提供了几种上传命名规则,包括:

    规则 描述
    date 根据日期和微秒数生成
    md5 对文件使用md5_file散列生成
    sha1 对文件使用sha1_file散列生成

    其中md5和sha1规则会自动以散列值的前两个字符作为子目录,后面的散列值作为文件名。

    如果需要使用自定义命名规则,可以在rule方法中传入函数或者方法,例如:

    // 获取表单上传文件 例如上传了001.jpg
    $file = request()->file('image');
    // 移动到服务器的上传目录 并且使用uniqid规则
    $file->rule('uniqid')->move('../uploads/');
    

    生成的文件名类似于:

    application/uploads/573d3b6d7abe2.jpg
    

    如果你希望保留原文件名称,可以使用:

    // 获取表单上传文件 例如上传了001.jpg
    $file = request()->file('image');
    // 移动到服务器的上传目录 并且使用原文件名
    $file->move('../uploads/','');
    

    默认情况下,会覆盖服务器上传目录下的同名文件,如果不希望覆盖,可以使用:

    // 获取表单上传文件 例如上传了001.jpg
    $file = request()->file('image');
    // 移动到服务器的上传目录 并且设置不覆盖
    $file->move('../uploads/',true,false);
    

    获取文件hash散列值

    可以获取上传文件的哈希散列值,例如:

    // 获取表单上传文件
    $file = request()->file('image');
    // 移动到服务器的上传目录 并且使用原文件名
    $upload = $file->move('/home/www/upload/');
    // 获取上传文件的hash散列值
    echo $upload->md5();
    echo $upload->sha1();
    

    可以统一使用hash方法获取文件散列值

    // 获取表单上传文件
    $file = request()->file('image');
    // 移动到服务器的上传目录 并且使用原文件名
    $upload = $file->move('/home/www/upload/');
    // 获取上传文件的hash散列值
    echo $upload->hash('sha1');
    echo $upload->hash('md5');
    

    返回对象

    上传成功后返回的仍然是一个File对象,除了File对象自身的方法外,并且可以使用SplFileObject的属性和方法,便于进行后续的文件处理。

    webuploader 无刷新上传前端组件上传

    官网:http://fex.baidu.com/webuploader/

    简介

    image-20200529231156559

    结合tp5.1的上传demo


    文件上传并回显到页面

    视图文件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>文件上传</title>
        <!--引入CSS-->
        <link rel="stylesheet" type="text/css" href="/static/webuploader/css/webuploader.css">
        <!--引入jquery-->
        <script type="text/javascript" src="/static/admin/js/jquery.min.js"></script>
        <!--引入JS-->
        <script type="text/javascript" src="/static/webuploader/jekyll/js/webuploader.js"></script>
    </head>
    <body>
    <img src="#" id="avatar" style="200px ;display:none" >
    <div id="picker">选择文件</div>
    <script>
        var token = '{:token()}';
        var uploader = WebUploader.create({
            // 选完文件后,是否自动上传。
            auto: true,
            // swf文件路径
            swf: '/static/webuploader/jekyll/js/Uploader.swf',
            // 文件接收服务端。
            server: '{:url("uploadSubmit")}',
            // 选择文件的按钮。可选。
            // 内部根据当前运行是创建,可能是input元素,也可能是flash.
            pick: '#picker',
    
            //设置文件上传域的name
            fileVal: 'pic',
    
            //传递请求的额外参数
            formData: {
                '__token__': token,
            },
            // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
            resize: false
        });
    
        //回调事件
        uploader.on( 'uploadSuccess', function( $file,response ){
            console.log(arguments);
            if(response.static == 0){
                $('#avatar').attr('src', response.msg).show();
            }
        });
    </script>
    </body>
    </html>
    

    控制器

    <?php
    
    namespace appadmincontroller;
    
    use thinkController;
    use thinkRequest;
    
    class Upload extends Controller
    {
        //上传界面
        public function index(){
            return view('admin@/upload/index');
        }
    
    	//上传处理
        public function upload(Request $request){
            //dump($request->file());
            $file = $request->file('pic');
            // 移动到框架应用根目录/uploads/ 目录下
            $info = $file->move( './uploads');
            if($info){
                $savename = '/uploads/'.str_replace('\','/', $info->getSaveName());
                //$savename = '1111';
                return json(['static' => 0, 'msg' => $savename]);
            }
    
            return json(['static' => 1, 'msg' => $file->getError()]);
        }
    }
    

    路由

    <?php
    use 	hinkfacadeRoute;
    Route::group('admin', function (){
        //文件上传界面
        Route::get('upload', '@admin/upload/index')->name('upload');
        //服务器端文件接收
        Route::post('uploadSubmit', '@admin/upload/upload')->name('uploadSubmit');
    });
    

    运行效果

    image-20200529231603688

    文件删除操作

    视图文件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>文件上传</title>
        <!--引入CSS-->
        <link rel="stylesheet" type="text/css" href="/static/webuploader/css/webuploader.css">
        <!--引入jquery-->
        <script type="text/javascript" src="/static/admin/js/jquery.min.js"></script>
    
        <!--引入JS-->
        <script type="text/javascript" src="/static/webuploader/jekyll/js/webuploader.js"></script>
    
        <style>
            .box {
                position: relative;
                 200px;
            }
    
            .box p {
                position: absolute;
                right: 10px;
                top: 5px;
                z-index: 100;
                color: white;
                background: red;
                /*将鼠标改成手型*/
                cursor: pointer;
            }
    
            .box p:hover {
                text-decoration: underline;
            }
        </style>
    </head>
    <body>
    
    <div class="box">
        <img src="#" id="avatar" style="200px ;display:none" >
        <p id="del">删除</p>
    </div>
    <div id="picker">选择文件</div>
    
    <script>
        var token = '{:token()}';
        var uploader = WebUploader.create({
            // 选完文件后,是否自动上传。
            auto: true,
    
            // swf文件路径
            swf: '/static/webuploader/jekyll/js/Uploader.swf',
    
            // 文件接收服务端。
            server: '{:url("uploadSubmit")}',
    
            // 选择文件的按钮。可选。
            // 内部根据当前运行是创建,可能是input元素,也可能是flash.
            pick: '#picker',
    
            //设置文件上传域的name
            fileVal: 'pic',
    
            //传递请求的额外参数
            formData: {
                '__token__': token,
            },
            // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
            resize: false
        });
    
        //回调事件
        uploader.on( 'uploadSuccess', function( $file,response ) {
            //console.log(arguments);
            if(response.static == 0){
                $('#avatar').attr('src', response.msg).show();
            }
        });
    
        //点击删除事件
        $('#del').click(function () {
            let img = $(this).prev().attr('src');
            //console.log(img);
            /*发送ajax*/
            $.ajax({
                url: '{:url("uploadDel")}',
                type: 'delete',
                data: {img},
                success: ret => {
                    console.log(ret);
                    if(ret.status == 0){
                        alert(ret.msg);
                        $('#avatar').hide();
                    }
                }
            });
        });
    </script>
    </body>
    </html>
    

    控制器

    <?php
    
    namespace appadmincontroller;
    
    use thinkController;
    use thinkRequest;
    
    class Upload extends Controller
    {
        //上传界面
        public function index(){
            return view('admin@/upload/index');
        }
    
        //上传处理
        public function upload(Request $request){
            //dump($request->file());
            $file = $request->file('pic');
            // 移动到框架应用根目录/uploads/ 目录下
            $info = $file->move( './uploads');
            if($info){
                $savename = '/uploads/'.str_replace('\','/', $info->getSaveName());
                //$savename = '1111';
                return json(['static' => 0, 'msg' => $savename]);
            }
            return json(['static' => 1, 'msg' => $file->getError()]);
        }
    
    	//文件删除
        public function del(Request $request){
            //var_dump($request->server());
            // 注意路径问题
            //向上3级
            $img = dirname(__DIR__, 3) .'/public'.$request->delete('img');
            //dump($img);
            $data = ['status'=>1,'msg'=>'删除失改'];
            if (unlink($img)){
                $data = ['status'=>0,'msg'=>'删除成功'];
            }
            return json($data);
        }
    }
    

    路由

    <?php
    use 	hinkfacadeRoute;
    
        //文件上传界面
        Route::get('upload', '@admin/upload/index')->name('upload');
    
        //服务器端文件接收
        Route::post('uploadSubmit', '@admin/upload/upload')->name('uploadSubmit');
    
        //服务端删除文件
        Route::delete('uploadDel', '@admin/upload/del')->name('uploadDel');
    
    });
    

    运行结果

    image-20200530152539572

  • 相关阅读:
    next()nextLine()以及nextInt()的区别及用法【转载】
    JAVA集合 list set map
    JAVA求回文数
    左移右移操作_进制转换与区分
    window_mysql踩坑
    centos_mysql踩坑
    【纪中受难记】——C3D6:大小不分
    zzLinux 中直接 I/O 机制的介绍https://www.ibm.com/developerworks/cn/linux/l-cn-directio/
    zz-zookeeper 启动失败 BindException: Address already in use 或者Error contacting service. It is probably not running
    zz---对象存储(Object-based Storage)概述
  • 原文地址:https://www.cnblogs.com/makalochen/p/12990127.html
Copyright © 2011-2022 走看看