{{ $variable }} 默认安全输出,因其编译为 htmlspecialchars() 转义html实体;仅适用于普通文本,不适用于富文本、属性值、js/json等上下文,且对空对象访问易报错,需用空合并操作符防护。

{{ $variable }} 是安全输出的默认方式,只要变量来自可信上下文(如控制器传入的模型或硬编码值),直接用它就行。
为什么 {{ $variable }} 会自动转义 HTML
Blade 把 {{ $variable }} 编译成类似 echo htmlspecialchars($variable, ENT_QUOTES, 'UTF-8') 的 PHP 代码。这意味着 <script>alert(1)</script> 会被变成纯文本显示,而不是执行脚本。
常见错误现象:变量里有 &、、<code>> 或引号时,页面显示乱码或标签消失——这不是 Bug,是转义在起作用。
- 适用场景:所有普通文本内容,比如用户昵称、文章标题、状态描述
- 不适用场景:富文本编辑器存的 HTML(如
<p>加粗</p>),此时浏览器只会看到源码,不会渲染成段落 - 性能影响:无感知,转义是底层函数调用,开销极小
{!! $html !!} 只在你完全控制内容时才可用
{!! $html !!} 等价于裸 echo $variable,跳过所有转义。一旦变量含用户提交的内容(比如评论框、后台富文本字段未过滤),XSS 风险立刻出现。
使用前必须确认:
– 内容是否由管理员/可信后台录入
– 是否已用 strip_tags()、htmlspecialchars_decode() 或专用 HTML 清洗库(如 league/commonmark)做过净化
- 典型正确用法:
{!! $post->rendered_content !!},其中rendered_content是服务端用 Markdown 解析器生成的 HTML - 典型错误用法:
{!! $request->input('bio') !!},用户可随意输入<img src="x" onerror="alert(1)"> - IDE 和 Laravel Pint 不会警告这个写法,但安全扫描工具(如 Psalm、PHPStan 插件)能识别高风险点
访问数组和对象属性时,语法不能混用
Blade 支持 $user['name'] 和 $user->name,但两者行为不同:前者要求键存在且非 null,后者触发 PHP 的魔术方法(如 __get)或抛出 ErrorException(若属性不存在)。
容易踩的坑:
– {{ $data['items'][0]['title'] }} 在 $data 为空时直接报错,不是静默失败
– {{ $user->posts->first()->title }} 中任意环节为 null,整个表达式崩掉
- 推荐写法:
{{ $user?->posts?->first()?->title }}(PHP 8.0+ 空合并链式调用) - 兼容旧版写法:
{{ optional($user->posts->first())->title }} - 数组键含短横线(如
data-user-id)不能用箭头访问,只能用方括号:{{ $attrs['data-user-id'] }}
最常被忽略的是嵌套结构的健壮性——{{ $item->name }} 看似简单,但只要 $item 是 null,页面就 500;而开发者往往只在模板里测了“有数据”的情况。











