enlinea777 / laravel-uploader
用于管理并上传 Laravel 10 文件的包
Requires
- php: >=7.0.0, <8.4.0
This package is auto-updated.
Last update: 2024-09-10 20:36:12 UTC
README
为文件上传提供 Laravel 后端
1.需求
建议使用 PHP 版本 8.2.x+ 和 Laravel 框架版本 10 来安装此包
2.安装
composer require enlinea777/laravel-uploader
您可以通过常规表单提交或 AJAX 调用(自行构建或任何第三方插件)将文件上传到后端。
注意:
-
表单提交只支持单个文件上传。对于多个文件上传,您应使用 AJAX 来并行发送文件。
-
该包还包括来自 Krajee 的前端文件输入插件,用于快速演示 AJAX 上传。包中包含的资产几乎是最小的,可能不是最新的。您应查阅http://plugins.krajee.com/file-input以获取插件的最新版本和更高级的使用案例
-
可以通过运行
npm install bootstrap-fileinput
来安装 Krajee 插件的全版本。 -
为了使用包含的前端资产,请运行
php artisan vendor:publish --tag=enlinea777_fileupload.assets
3.使用方法
3.1 在控制器中
首先,在控制器构造函数中为注入 FileUpload 服务,您需要指定 Enlinea777\LaravelUploader\Contracts\FileUpload
类型。
use Enlinea777\LaravelUploader\Contracts\FileUpload; ----------------- protected $fileupload; public function __construct(FileUpload $fileupload) { $this->fileupload = $fileupload; }
然后,在处理文件上传请求的方法中,您将调用
$this->fileupload->handle(Request $request, string $fieldname, array $uploadSettings)
其中
- $request:完整的 Laravel 请求对象
- $fieldname:前端文件输入字段的名称
- $uploadSettings(可选):用于自定义后端行为的内联设置
$uploadSettings 是一个关联数组,具有以下可能的键
directory
:包含您上传文件的根目录disk
:文件上传的存储磁盘。有关更多详细信息,请参阅 Laravel 官方文档,例如:public
、s3
maxFileSize
(以字节为单位):后端可以接受的最大上传文件大小allowedExtensions
:可接受的文件扩展名数组,例如:['jpg', 'png', 'pdf']
后端默认设置如下
- 'directory': 'media'
- 'disk': 'public'
- 'maxFileSize': 50 MB
- 'allowedExtensions': 'png','jpg','jpeg','mp4','doc','docx','ppt','pptx','xls','xlsx','txt','pdf'
您可以使用以下 .env 中的环境变量来更改这些默认设置
ENLINEA777_LARAVEL_UPLOADER_DEFAULT_DISK
ENLINEA777_LARAVEL_UPLOADER_DEFAULT_DIRECTORY
ENLINEA777_LARAVEL_UPLOADER_DEFAULT_MAX_FILE_SIZE
(以字节为单位)
注意:内联设置将覆盖默认设置
如果上传成功,则 $this->fileupload->handle(Request $request, string $fieldname, array $uploadSettings)
将返回以下数据,以便进一步持久化到数据库
[ 'filename' => 'the original file name', 'path' => 'path to file location relative to the disk storage', 'url' => 'public url to access the file in browser', 'disk' => 'name of storage disk' ]
如果上传的文件无效,则将返回 false
,并将错误消息设置为 $this->fileupload->uploadError
3.2 在前端视图中
3.2.1 正常表单上传
(仅支持单个文件上传)
示例:
<form action="/upload" method="POST" role="form" enctype="multipart/form-data"> @csrf() <input class="form-control" type="file" name="photo" id="photo" /> <input type="submit" name="submit" value="Upload" /> </form>
3.2.2 使用 Krajee 的默认前端资产进行 AJAX 上传
(支持并行请求发送多个文件)
示例:
<!DOCTYPE html> <html> <head> <title>File Upload</title> <meta name="csrf-token" content="{{ csrf_token() }}"> <link href="{{ mix('/css/app.css') }}" rel="stylesheet"> <script src="{{ mix('/js/app.js') }}"></script> <!-- You must embed fileinput CSS and Javascript as follows --> <script src="/vendor/fileupload/js/fileinput/fileinput.min.js"></script> <link href="/vendor/fileupload/css/fileinput/fileinput.min.css" rel="stylesheet"> </head> <body> <input class="form-control" type="file" name="photo" id="photo" multiple /> <script type="text/javascript"> $(document).ready(function(){ $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }); $("#photo").fileinput( { uploadUrl: '/upload', maxFileCount: 5, maxFileSize: 10420, //in KBs allowedFileExtensions: ['jpg', 'png', 'pdf'], previewFileType:'any', showUpload: false } ).on("filebatchselected", function(event, files) { $("#photo").fileinput("upload"); }); }); </script> </body> </html>
注意:当使用 Krajee 文件输入插件时,您必须在处理上传请求的控制器方法中返回以下 json 响应
if ($path = $this->fileupload->handle($request, 'photo', $uploadSettings)) { // Persist $path data to database return json_encode([]); } return json_encode([ 'error' => $this->fileupload->uploadError ]);
3.2.3 使用 @bkstar18/jquery-ajax-uploader 插件(由我编写)进行 AJAX 上传
您可以在https://github.com/enlinea777/jquery-ajax-uploader中查看其完整文档
示例使用:
a) 安装
-
npm install --save-dev @bkstar18/jquery-ajax-uploader
-
在
resources/js/bootstrap.js
中,放置以下行
try { window.Popper = require('popper.js').default; window.$ = window.jQuery = require('jquery'); require('bootstrap'); require('@bkstar18/jquery-ajax-uploader'); // Add this line } catch (e) {}
-
然后,使用
laravel-mix
编译您的资源:npm run production
-
或者,如果您不想将此插件捆绑到主 app.js 中,可以在
webpack.mix.js
中放置以下行
mix.js('resources/js/app.js', 'public/js') .copy('node_modules/@bkstar18/jquery-ajax-uploader/dist/enlinea777-ajax-uploader.min.js', 'public/js/enlinea777-ajax-uploader.min.js') // Add this line .sass('resources/sass/app.scss', 'public/css');
然后,在您想使用该插件的任何视图中包含以下代码:<script src="/js/enlinea777-ajax-uploader.min.js"></script>
。记住在使用插件之前加载 jQuery。
b) 在 HTML 部分
<div class="form-group"> <label for="image-upload">Upload Images</label> <input type="file" class="form-control" name="image" id="image-upload" multiple> <div class="gallery" id="gallery"></div> </div>
c) 在 JavaScript 部分
$(document).ready(function () { $('#image-upload').enlinea777_ajaxuploader({ allowedExtensions: ['png','jpg','jpeg'], batchSize: 5, outerClass: 'col-md-12', uploadUrl: '/api/upload', beforeSend: (xhr) => { xhr.setRequestHeader('X-AUTHOR', 'TUANHA'); }, onResponse: (response) => { let res = JSON.parse(response) $('#gallery').append(`<img id=${res.data.filename} src="${res.data.url}" width="50px">`); } }); });
d) 在 Laravel 控制器方法中
public function upload(Request $request, FileUpload $fileupload) { $data = $fileupload->handle($request, 'image', ['allowedExtensions' => ['jpg', 'png', 'jpeg']]); if (!$data) { return response()->json(['error' => $fileupload->uploadError], 422); } // Saving data to database return response()->json(['success' => "{$data['filename']} has been successfully uploaded", 'data' => $data], 200); }
注意:
您应该确保页面 HTML 布局包含以下 <meta>
标签
<meta name="csrf-token" content="{{ csrf_token() }}">
否则,请求可能会被 Laravel 默认阻止。更多信息请查看 https://laravel.net.cn/docs/5.8/csrf#csrf-x-csrf-token。
插件自动检查此 <meta>
标签的存在,获取其内容,并将 X-CSRF-TOKEN
标头与上传请求相关联。
或者,只有当 此 <meta>
标签不存在(可能您不想使用,或者由于某些原因),那么您可以在发送文件到服务器之前通过 beforeSend(xhr)
插槽包含 X-CSRF-TOKEN
请求标头,如下所示
$(document).ready(function () { $('#image-upload').enlinea777_ajaxuploader({ ... beforeSend: (xhr) => { xhr.setRequestHeader('X-CSRF-TOKEN', {!! json_encode(csrf_token()) !!}); }, ... }); });
3.3 物理删除上传的文件
您可以根据以下示例物理删除上传的文件
$this->fileupload->delete($photo->disk, $photo->path)
在此示例中,photos 表必须具有 disk
和 path
列以持久化 photo
实例。
您应该在删除数据库中相关的记录后才能物理删除上传的文件。