Laravel中使用Summernote更新含图片文章报Undefined array key错误
报错原因
Undefined array key报错的核心原因是:更新文章时,循环处理img标签拿到的src属性不全是base64格式的内嵌图片。已经存储过的老图片src是之前保存的服务器本地路径(比如/upload/169xxxx0.png),这类路径里没有;分隔符,执行explode(';', $data)时返回的数组只有1个元素,用list接收两个变量时第二个下标不存在,直接抛出错误。
store方法能正常运行是因为新建文章时,Summernote新上传的图片全是data:image/png;base64,xxxx格式的base64编码URI,拆分逻辑能正常取到分段。另外你的update方法里loadHtml的参数写法有误,把libxml_use_internal_errors(true)的布尔返回值拼到了加载配置项里,属于无效传参。
修复方法
在图片处理循环里先判断src是否为base64格式的data URI,只有新上传的base64图片走解码存文件逻辑,已经是本地路径的老图片直接跳过即可,同时修正loadHtml的参数错误。
修正后的update方法代码
public function update(Request $request, Post $post) { $this->validate($request, [ 'title' => 'required', 'body' => 'required' ]); $content = $request->body; libxml_use_internal_errors(true); $dom = new \DomDocument(); // 移除错误的传参,不要将函数返回值拼入加载配置 $dom->loadHtml($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); $imageFile = $dom->getElementsByTagName('img'); foreach ($imageFile as $item => $image) { $data = $image->getAttribute('src'); // 非base64格式的图片(已存本地/外链图)直接跳过 if (strpos($data, 'data:image/') !== 0) { continue; } list($type, $data) = explode(';', $data); list(, $data) = explode(',', $data); $imgeData = base64_decode($data); $image_name = "/upload/" . time() . $item . '.png'; $path = public_path() . $image_name; file_put_contents($path, $imgeData); $image->removeAttribute('src'); $image->setAttribute('src', $image_name); } $content = $dom->saveHTML(); $post->title = $request->title; $post->body = $content; $post->save(); return redirect()->back(); }
额外优化建议
- 建议把图片处理逻辑抽成公共复用方法,
store和update调用同一段逻辑,避免两边代码不一致引发问题 store方法里也加上同样的base64格式判断,防止后续逻辑调整出现同类报错- 如果使用PHP8.0+版本,可以用
str_starts_with($data, 'data:image/')替换示例里的strpos判断,写法更简洁 - 图片命名建议增加随机字符串后缀,避免同一秒内循环处理多张图片时出现文件名覆盖问题
内容的提问来源于stack exchange,提问作者Alphy Gacheru
相关产品推荐
相关产品推荐

