Laravel查询构建器first()方法报错,limit(1)+get()可正常运行
问题解决:Laravel连接Oracle调用
first()报json_decode参数错误 核心原因
first()方法返回单个stdClass对象,而代码(或Laravel Oracle驱动内部逻辑)中某个环节尝试对该对象调用json_decode(),但该函数要求参数为字符串类型,导致类型不匹配报错。而limit(1)->get()返回包含单个对象的Collection集合,不会触发该错误逻辑。
解决方案
1. 手动转为数组后使用
将first()的结果强制转为数组,避免直接操作对象触发错误:
$data = DB::connection('oracle') ->table('m.rsc_claim as rc') ->select('rc.num as order_number', 'rld.name as reason_claim', 'rc.work_bdate as start_date', 'rc.address_name as address_name' ) ->leftJoin('m.rsc_lst_declaration as rld', 'rld.id', 'rc.declaration_id') ->where('user_id', $userId) ->latest('rc.bdate') ->first(); // 转为数组后再处理业务逻辑 $data = (array) $data;
2. 调整Oracle连接配置,强制字段转为字符串
在config/database.php的oracle连接配置中添加PDO属性,强制所有查询结果转为字符串,避免出现stdClass类型的字段值:
'connections' => [ 'oracle' => [ // 其他配置项 'options' => [ PDO::ATTR_STRINGIFY_FETCHES => true, ], ], ],
3. 显式转换字段类型
若明确某个字段(比如日期字段)是问题根源,可通过SQL函数手动转换字段类型:
->select( 'rc.num as order_number', 'rld.name as reason_claim', DB::raw('TO_CHAR(rc.work_bdate, \'YYYY-MM-DD HH24:MI:SS\') as start_date'), 'rc.address_name as address_name' )
4. 分步查询避开解析问题
先获取目标数据的主键ID,再基于主键查询详情,可绕过驱动的自动解析问题:
// 先取最新记录的主键ID $latestClaimId = DB::connection('oracle') ->table('m.rsc_claim') ->where('user_id', $userId) ->latest('bdate') ->value('id'); // 基于主键查询完整数据 $data = DB::connection('oracle') ->table('m.rsc_claim as rc') ->select('rc.num as order_number', 'rld.name as reason_claim', 'rc.work_bdate as start_date', 'rc.address_name as address_name' ) ->leftJoin('m.rsc_lst_declaration as rld', 'rld.id', 'rc.declaration_id') ->where('rc.id', $latestClaimId) ->first();
排查验证
可以先打印first()返回的对象结构,定位具体是哪个字段为stdClass类型:
dd($data);
找到对应字段后,针对性进行类型转换即可。
内容的提问来源于stack exchange,提问作者Noeld Visard
相关产品推荐
相关产品推荐

