jvizcaya / uploadable
Laravel Eloquent 特性,用于存储基于 base64 编码的数据
Requires
- php: ^7.1.3|^8.0
- intervention/image: ^2.7
README
Uploadable 是一个为 Laravel 5.7+ 设计的 trait,它为我们的模型添加了存储文件的功能,当我们处理预先 base64 编码 的数据时。
由于与模型相关联,我们只需指定表格(数据库)中的列,在该列中我们希望保存存储在磁盘上的文件名。
保存文件名的列必须允许包含空值,因为 trait 的函数在模型的方法 save() 或 update() 之后执行。
安装
composer require jvizcaya/uploadable
使用方法
将 Trait Jvizcaya\Uploadable\UploadableTrait 添加到模型中,并配置变量 protected $uploadable 以包含存储规则。
namespace App; use Illuminate\Database\Eloquent\Model; use Jvizcaya\Uploadable\UploadableTrait; class Post extends Model { use UploadableTrait; /** * Uploadable rules. * * @var array */ protected $uploadable = [ 'image' => ['folder' => 'posts'] ]; }
在上面的例子中,我们定义文件将存储在 posts 文件夹中,而文件名将保存在表格的 image 列中。
将 trait 添加到模型并正确配置变量 protected $uploadable 后,我们可以使用存储功能 storageFile()。
namespace App\Http\Controllers; use App\Post; class PostController extends Controller { public function store(Request $request) { $post = new Post($request->all()); $post->save(); $post->storageFile($request->image); } }
在上面的例子中,$request->image 是从视图传递到控制器的 base64 编码的图像文件。
storageFile() 使用 intervention/image 包来存储图像文件,请确保系统满足此包的要求。
表格列
默认情况下,将使用变量 $uploadable 的第一个元素作为应用存储规则的依据,我们可以动态指定列,将其作为第二个参数传递(如果我们在同一表中具有多个存储字段和不同规则,这将很有用)。
$post->storageFile($request->image, 'image');
文件名
我们可以通过配置规则 name_column 来使文件名自动从模型的另一个列中获取。
use UploadableTrait; /** * Uploadable rules. * * @var array */ protected $uploadable = [ 'image' => [ 'folder' => 'posts', 'name_column' => 'title' ] ];
在上面的例子中,文件将使用模型 title 列中的值进行存储。
我们还可以通过将文件名作为 storageFile() 函数的第三个参数传递来指定文件名。
$post->storageFile($request->image, 'image', 'file name');
在这两种情况下,指定的名称将被格式化,例如,文件名 将被更改为 文件名。
如果没有使用上述方法之一指定文件名,将使用默认值,默认值为存储的日期,格式为 YmdHi。
文件夹名
存储文件到磁盘的文件夹名应在规则 folder 中指定(请参阅示例),但如果需要以动态方式传递存储文件夹名,则可以将它作为 storageFile() 函数的第四个参数传递。
$post->storageFile($request->image, 'image', 'file name', 'folder_name');
缩略图
当我们要存储的文件是 图像 时,我们可以生成多个尺寸的缩略图或副本,为此,我们只需在变量 $uploadable 中配置规则 thumbnail。
use UploadableTrait; /** * Uploadable rules. * * @var array */ protected $uploadable = [ 'image' => [ 'folder' => 'posts', 'name_column' => 'title', 'thumbnail' => ['folder' => 'posts/thumbnails', 'size' => [150, 100]], ] ];
在上面的例子中,我们指定在存储文件时生成我们的图像文件的副本(缩略图)。
此图像将保存在 posts 文件夹中的 thumbnails 文件夹内,宽度为 150 像素,高度为 100 像素。
如果没有指定 size 规则给 thumbnails,则图片将被默认保存为 150px 宽和 150px 高。
多个缩略图
有时我们需要生成不同大小的多个文件,对于这种情况,只需将每个图像所需的规则作为一个元素放入 thumbnail 规则的数组中即可,如下所示
use UploadableTrait; /** * Uploadable rules. * * @var array */ protected $uploadable = [ 'image' => [ 'folder' => 'posts', 'name_column' => 'title', 'thumbnail' => [ ['folder' => 'posts/150', 'size' => [150, 100]], ['folder' => 'posts/400', 'size' => [400, 300]] ], ] ];
在上面的例子中,将创建两个图像,分别位于 posts/150 和 posts/400 目录。
磁盘名称(文件系统)
Uploadable 使用 Laravel 的存储系统(文件存储),因此期望目录位于 storage/app。
默认使用的磁盘是 public,如果我们想配置使用其他磁盘,可以通过指定如下方式的 disk 规则
use UploadableTrait; /** * Uploadable rules. * * @var array */ protected $uploadable = [ 'image' => [ 'folder' => 'posts', 'name_column' => 'title', 'thumbnail' => [ ['folder' => 'posts/150', 'size' => [150, 100]], ['folder' => 'posts/400', 'size' => [400, 300]] ], 'disk' => 'public' ], 'photo' => [ 'folder' => 'photos', 'name_column' => 'title', 'disk' => 'local' ] ];
目前仅保证与本地磁盘的使用兼容,未测试使用 s3 或其他云方法的兼容性。
删除文件
要删除与模型关联的存储文件,我们可以使用 deleteAllFiles() 函数,此函数将遍历 $uploadable 中的每个条目,并从磁盘上删除每个文件。
为了正确工作,每个规则都必须正确指定,尤其是 folder 值的规则。
$post->deleteAllFiles();
如果无法使用前面的方法或需要删除特定文件,可以使用 deleteFile() 方法,此方法接受要删除的列名作为参数。
$post->deleteFile('photo');
deleteFile() 还可以接受一个可选的第二个参数,即文件所在的文件夹名称。
$post->deleteFile('photo', 'photos');
注意: 当使用 deleteAllFiles() 或 deleteFile() 时,如果删除的文件是图像,并且该图像已配置 thumbnail 规则,则也会删除生成的缩略图。
该软件包考虑在删除关联模型之后执行 deleteAllFiles() 和 deleteFile() 函数。因此,它不会在数据库列中执行清理。
如果想在删除图像时不删除模型,可以发送参数 nullColumn 为 true。此参数将指示图像删除函数清理数据库表中的列。
$post->deleteAllFiles(true); $post->deleteFile('photo', 'photos', true);
注意: 如果关联模型先前已被删除,则不能发送 nullColumn 参数。它应在模型更新或软删除 softDelete 的情况下使用。
作为替代,我们可以在同一 storageFileFile 函数中删除先前保存的文件。为此,我们发送一个包含 delete_file 值的字符串而不是作为第一个参数发送编码为 base64 的文件。这种功能仅在更新关联模型时使用。 注意: 此功能将自动清理数据库表中的列值。
移动文件(测试版)
如果想在框架的存储系统(FyleSystem)中更改已存储文件的存储位置,可以使用 moveFile() 函数,此选项应提供新目录的名称作为参数。
$post->moveFile('images');
我们还可以将列名作为第二个参数,将文件当前所在的文件夹名称作为第三个参数。
$post->moveFile('images', 'image', 'posts');
注意事项
目前,storageFile() 函数根据其 MIME 类型支持以下文件类型,这些类型已经过测试。随着稳定性的测试,将添加更多文件类型。
许可证
MIT 协议 © Jorge Vizcaya | jorgevizcayaa@gmail.com