美文网首页
laravel 分块上传大文件

laravel 分块上传大文件

作者: 大萝卜2022 | 来源:发表于2022-10-26 17:10 被阅读0次

    1.安装pion/laravel-chunk-upload,

    composer require pion/laravel-chunk-upload
    \Pion\Laravel\ChunkUpload\Providers\ChunkUploadServiceProvider::class
    php artisan vendor:publish --provider="Pion\Laravel\ChunkUpload\Providers\ChunkUploadServiceProvider"
    

    2.添加路由

    Route::post('/upload', 'UploadController@upload');
    
    1. 添加视图和脚本
    <script src="https://cdnjs.cloudflare.com/ajax/libs/resumable.js/1.1.0/resumable.min.js"></script>
    
    <script>
            var $ = window.$; // use the global jQuery instance
    
            var $fileUpload = $('#resumable-browse');
            var $fileUploadDrop = $('#resumable-drop');
            var $uploadList = $("#file-upload-list");
    
            if ($fileUpload.length > 0 && $fileUploadDrop.length > 0) {
                var resumable = new Resumable({
                    // Use chunk size that is smaller than your maximum limit due a resumable issue
                    // https://github.com/23/resumable.js/issues/51
                    chunkSize: 1 * 1024 * 1024, // 1MB
                    simultaneousUploads: 3,
                    testChunks: false,
                    throttleProgressCallbacks: 1,
                    // Get the url from data-url tag
                    target: $fileUpload.data('url'),
                    // Append token to the request - required for web routes
                    query:{_token : $('input[name=_token]').val()}
                });
    
            // Resumable.js isn't supported, fall back on a different method
                if (!resumable.support) {
                    $('#resumable-error').show();
                } else {
                    // Show a place for dropping/selecting files
                    $fileUploadDrop.show();
                    resumable.assignDrop($fileUpload[0]);
                    resumable.assignBrowse($fileUploadDrop[0]);
    
                    // Handle file add event
                    resumable.on('fileAdded', function (file) {
                        // Show progress pabr
                        $uploadList.show();
                        // Show pause, hide resume
                        $('.resumable-progress .progress-resume-link').hide();
                        $('.resumable-progress .progress-pause-link').show();
                        // Add the file to the list
                        $uploadList.append('<li class="resumable-file-' + file.uniqueIdentifier + '">Uploading <span class="resumable-file-name"></span> <span class="resumable-file-progress"></span>');
                        $('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-name').html(file.fileName);
                        // Actually start the upload
                        resumable.upload();
                    });
                    resumable.on('fileSuccess', function (file, message) {
                        // Reflect that the file upload has completed
                        $('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-progress').html('(completed)');
                    });
                    resumable.on('fileError', function (file, message) {
                        // Reflect that the file upload has resulted in error
                        $('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-progress').html('(file could not be uploaded: ' + message + ')');
                    });
                    resumable.on('fileProgress', function (file) {
                        // Handle progress for both the file and the overall upload
                        $('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-progress').html(Math.floor(file.progress() * 100) + '%');
                        $('.progress-bar').css({width: Math.floor(resumable.progress() * 100) + '%'});
                    });
                }
    
            }
    
    
    </script>
    
    
    <div class="text-center" >
        <div id="resumable-error" style="display: none">
            Resumable not supported
        </div>
        <div id="resumable-drop" style="display: none">
            <p><button id="resumable-browse" data-url="{{ url('upload') }}" >Upload</button> or drop here
            </p>
            <p></p>
        </div>
        <ul id="file-upload-list" class="list-unstyled"  style="display: none">
    
        </ul>
        <br/>
    </div>
    
    1. UploadController 控制器中代码
    <?php
    namespace App\Http\Controllers;
    use Storage;
    use Illuminate\Http\Request;
    use Illuminate\Http\UploadedFile;
    use Pion\Laravel\ChunkUpload\Exceptions\UploadMissingFileException;
    use Pion\Laravel\ChunkUpload\Handler\AbstractHandler;
    use Pion\Laravel\ChunkUpload\Handler\HandlerFactory;
    use Pion\Laravel\ChunkUpload\Receiver\FileReceiver;
    class UploadController extends Controller
    {
        /**
         * Handles the file upload
         *
         * @param Request $request
         *
         * @return \Illuminate\Http\JsonResponse
         *
         * @throws UploadMissingFileException
         * @throws \Pion\Laravel\ChunkUpload\Exceptions\UploadFailedException
         */
        public function upload(Request $request) {
            // create the file receiver
            $receiver = new FileReceiver("file", $request, HandlerFactory::classFromRequest($request));
            // check if the upload is success, throw exception or return response you need
            if ($receiver->isUploaded() === false) {
                throw new UploadMissingFileException();
            }
            // receive the file
            $save = $receiver->receive();
            // check if the upload has finished (in chunk mode it will send smaller files)
            if ($save->isFinished()) {
                // save the file and return any response you need, current example uses `move` function. If you are
                // not using move, you need to manually delete the file by unlink($save->getFile()->getPathname())
                return $this->saveFile($save->getFile());
            }
            // we are in chunk mode, lets send the current progress
            /** @var AbstractHandler $handler */
            $handler = $save->handler();
            return response()->json([
                "done" => $handler->getPercentageDone(),
                'status' => true
            ]);
        }
        /**
         * Saves the file to S3 server
         *
         * @param UploadedFile $file
         *
         * @return \Illuminate\Http\JsonResponse
         */
        protected function saveFileToS3($file)
        {
            $fileName = $this->createFilename($file);
            $disk = Storage::disk('s3');
            // It's better to use streaming Streaming (laravel 5.4+)
            $disk->putFileAs('photos', $file, $fileName);
            // for older laravel
            // $disk->put($fileName, file_get_contents($file), 'public');
            $mime = str_replace('/', '-', $file->getMimeType());
            // We need to delete the file when uploaded to s3
            unlink($file->getPathname());
            return response()->json([
                'path' => $disk->url($fileName),
                'name' => $fileName,
                'mime_type' =>$mime
            ]);
        }
        /**
         * Saves the file
         *
         * @param UploadedFile $file
         *
         * @return \Illuminate\Http\JsonResponse
         */
        protected function saveFile(UploadedFile $file)
        {
            $fileName = $this->createFilename($file);
            // Group files by mime type
            $mime = str_replace('/', '-', $file->getMimeType());
            // Group files by the date (week
            $dateFolder = date("Y-m-W");
            // Build the file path
            $filePath = "upload/{$mime}/{$dateFolder}/";
            $finalPath = storage_path("app/".$filePath);
            // move the file name
            $file->move($finalPath, $fileName);
            return response()->json([
                'path' => $filePath,
                'name' => $fileName,
                'mime_type' => $mime
            ]);
        }
        /**
         * Create unique filename for uploaded file
         * @param UploadedFile $file
         * @return string
         */
        protected function createFilename(UploadedFile $file)
        {
            $extension = $file->getClientOriginalExtension();
            $filename = str_replace(".".$extension, "", $file->getClientOriginalName()); // Filename without extension
            // Add timestamp hash to name of the file
            $filename .= "_" . md5(time()) . "." . $extension;
            return $filename;
        }
    }
    

    相关文章

      网友评论

          本文标题:laravel 分块上传大文件

          本文链接:https://www.haomeiwen.com/subject/hfbttdtx.html