You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Laravel Blade模板中直接调用json_decode报错:期望参数为字符串,实际传入对象

Laravel Blade中json_decode报错的问题解决

问题回顾

你在Laravel项目里遇到了一个有点头疼的问题:Result模型对应的results表中,properties是JSON类型字段,在控制器里调用json_decode能正常得到对象或数组,但在Blade模板里直接用{{ json_decode($result->properties) }}就会抛出htmlspecialchars() expects parameter 1 to be string, object given的错误。

问题根源

这其实是Blade语法的默认特性导致的:{{ }}会自动调用PHP的htmlspecialchars()函数转义输出内容,目的是防止XSS攻击。但json_decode()返回的是对象或者数组,并非字符串类型,htmlspecialchars()只能处理字符串,自然就触发了报错。

而你在控制器里用var_dump()是直接输出变量,不会经过Blade的自动转义流程,所以能正常显示解码后的对象/数组。

解决方案(按推荐程度排序)

1. 利用Laravel模型的$casts自动转换JSON字段(最佳实践)

这是最贴合Laravel设计理念的方法,让模型自动帮你处理JSON的序列化和反序列化,完全不用手动调用json_decode。

在你的Result模型里添加$casts属性:

class Result extends Model
{
    // 其他模型代码...
    protected $casts = [
        'properties' => 'array', // 转成关联数组,也可以用'object'转成对象
    ];
}

设置完成后,不管在控制器还是Blade里,直接访问$result->properties就已经是解码后的数组/对象了:

@foreach ($results as $result)
    {{-- 直接遍历properties里的clubs数组 --}}
    @foreach ($result->properties['clubs'] as $club)
        <div>俱乐部名称:{{ $club['name'] }},获胜次数:{{ $club['wins'] }}</div>
    @endforeach
@endforeach

2. 在控制器中提前处理数据再传递给视图

如果暂时不想修改模型,可以在控制器里提前把所有结果的properties解码完成,再传给视图:

public function index() {
    $user = auth()->user();
    $results = Result::getResults($user->properties)->map(function($item) {
        // 转成关联数组,true参数控制返回类型
        $item->properties = json_decode($item->properties, true);
        return $item;
    });

    return view('dashboard', compact('results'));
}

之后在Blade里就可以直接使用解码后的$result->properties,用法和上面一致。

3. 绕过Blade的自动转义(仅用于调试或特殊场景)

如果你只是临时想查看解码后的内容,或者需要输出对象/数组的字符串形式,可以用{!! !!}语法绕过自动转义,同时把结果转成字符串:

@foreach ($results as $result)
    {{-- 输出JSON格式的字符串 --}}
    {!! json_encode(json_decode($result->properties)) !!}
@endforeach

注意:{!! !!}会关闭XSS转义,生产环境使用时一定要确保内容是安全的,避免注入风险。

内容的提问来源于stack exchange,提问作者Zabs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 08:32:35