菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
2269
0

Laravel-admin 中 summernote 图片 base64 转文件

原创
05/13 14:22
阅读数 2952

背景: 不喜欢数据库中存储大段的 base64 图片, 太占空间了; laravel-admin 中没找到其它特别好用的富文本编辑器, 所以改吧.

  1. 最初的想法是直接改 summernote 的 js 文件, 可是要动到 vendor 中的内容, 不想改
  2. 在表单内容存储到数据库之前 (或之后) 把 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);
        }
    }
}

发表评论

0/200
2269 点赞
0 评论
收藏
为你推荐 换一批