Laravel发邮件调用$message->embed提示图片路径不可读如何解决
问题原因
$message->embed() 是服务端执行的文件读取方法,要求传入服务器本地磁盘的绝对文件路径。你传入的 /img/logo.svg 是Web访问的根相对路径,会被程序识别为服务器磁盘根目录下的img文件夹内的文件,和你实际存放在项目public目录下的文件位置完全不匹配,所以程序无法读取文件抛出Path "/img/logo.svg" is not readable.的错误。
你之前写的字体引入能生效,是因为那段CSS是交给邮件客户端解析的,走的是HTTP资源请求逻辑,和服务端本地读文件的embed()逻辑完全不同,两者的路径规则不通用。
解决方法
直接用框架提供的路径辅助函数生成真实磁盘路径即可,按你的文件存放位置选对应写法:
- 如果logo存放在
public/img/目录(也就是你现在其他视图能正常调用的位置),把嵌入代码改成:
src="{{ $message->embed(public_path('img/logo.svg')) }}"
public_path()方法会自动拼接出项目public目录的真实磁盘绝对路径,比如你的项目部署在/www/wwwroot/your-project/目录下,上面的代码实际传入的路径是/www/wwwroot/your-project/public/img/logo.svg,服务端可以直接读取到目标文件。
- 如果logo存放在storage目录下,就用
storage_path()辅助函数生成路径,比如文件在storage/app/public/img/logo.svg位置,写法为:
src="{{ $message->embed(storage_path('app/public/img/logo.svg')) }}"
补充说明
- 不要混淆两类路径规则:写在HTML、CSS里供客户端请求的资源用Web相对/绝对HTTP路径即可,只要是服务端PHP直接操作本地文件的场景,都要传磁盘真实路径。
- 如果不想做内联嵌入,也可以直接把图片src写成带域名的完整HTTP地址,比如
src="https://你的站点域名/img/logo.svg",这种方式不需要服务端读文件嵌入,但是大部分邮件客户端默认会拦截外联图片,收件人需要手动点“显示图片”才能看到,体验不如内联嵌入。 - SVG格式在部分老旧邮件客户端里存在兼容性问题,如果嵌入后出现展示异常,可以把logo导出为PNG格式再嵌入,兼容性更好。
- 如果替换路径后仍然报不可读错误,检查对应logo文件的系统权限,确保运行PHP进程的用户拥有该文件的读取权限。
内容的提问来源于stack exchange,提问作者Daniel L
相关产品推荐
相关产品推荐

