Laravel-admin 中 summernote 图片 base64 转文件
背景: 不喜欢数据库中存储大段的 base64 图片, 太占空间了; laravel-admin 中没找到其它特别好用的富文本编辑器, 所以改吧.
- 最初的想法是直接改 summernote 的 js 文件, 可是要动到 vendor 中的内容, 不想改
- 在表单内容存储到数据库之前 (或之后) 把 base64 的图片保存成文件, 并用文件的路径代替之前的 base64串
实现:
在 laravel-admin 的控制器中重写 store, update, destroy 方法, 前两个用于 base64 转 文件, 后一个用于删除图片
// ArticlesController.php
/********** 以下重写 store, update, destroy 方法, 用于 summernote 上传的base64图片转文件或删除 *******/
public function store()
{
request()['content'] = summernote_base64_to_file(request()['content']);
parent::store();
}
public function update($id)
{
request()['content'] = summernote_base64_to_file(request()['content']);
parent::update($id);
}
public function destroy($id)
{
$article = Article::find($id);
summernote_delete_image($article->content);
parent::destroy($id);
}
// helpers.php
function summernote_base64_to_file($content)
{
if (!($content && \Str::contains($content, ['src="data:image', 'src=\'data:image']))) {
return $content;
}
$pattern = '/(data:image\/)([^;]+)(;base64,)([^\"]+)/';
$res = preg_replace_callback($pattern, function ($matches) {
// 生成路径
$public_path = public_path();
$folder_path = '/summernote/' . date('Ym') . '/' . date('d') . '/';
if (!is_dir($dir = $public_path . $folder_path)) {
mkdir($dir, 0777, true);
}
// 生成文件名
$matches[2] = $matches[2] === 'jpeg' ? 'jpg' : $matches[2];
$filename = md5(time() . \Illuminate\Support\Str::random()) . '.' . $matches[2];
$file = $dir . $filename;
// 保存文件
file_put_contents($file, base64_decode($matches[4]));// base64 转图片
// 返回相对路径
return $folder_path . $filename;
}, $content);
return $res;
}
function summernote_delete_image($content)
{
if (!($content && \Str::contains($content, ['summernote']))) {
return null;
}
$pattern = '/(\/summernote[^\'\"]+)/';
$times = preg_match_all($pattern, $content, $matches);
if ($times) {
foreach ($matches[0] as $value) {
unlink(public_path() . $value);
}
}
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
謝謝分享,我測試後發現不能正常新增article,試了大半天後發現將 parent::store(); 修改成 return parent::store(); 即可,update() 和 destroy()也需要修改。
感谢 。