如何将JavaScript JSON.stringify()结果转换为PHP数组
问题原因
你这个问题本质是两个层面的错误共同导致的:
- 运行逻辑搞混了:Blade是PHP服务端模板引擎,
@include这类指令在服务器把页面内容返回给浏览器之前就已经编译执行完了,根本读不到浏览器里JS运行时才生成的locationinfo变量。你把@include写在JS模板字符串里的写法从根上就不符合Blade的运行机制,你肉眼看到echo $locationinfo输出和JSON一致,只是浏览器渲染转义字符后的视觉效果,实际传到PHP的字符串早就不是合法JSON了。 - 直接导致
json_decode返回null的诱因:你传递的JSON字符串在Blade编译、HTML渲染的过程中被自动做了HTML实体转义——比如双引号被转成了",部分特殊字符被加了反斜杠转义。这些转义字符在浏览器里echo出来会被还原成双引号,你肉眼看不出区别,但PHP拿到的原始字符串里带这些转义内容,不符合JSON语法规范,解码自然返回null,后续遍历就会报类型错误。
修复方案
优先推荐用正规方案调整逻辑,不要用字符串拼接的方式硬凑模板:
- 方案1:静态渲染场景(页面打开就需要展示该内容)
不要在JS里传数据给Blade,直接在PHP控制器层把locationinfo数据传给对应视图,省掉JSON序列化、反序列化的多余步骤:
页面模板里直接引入子模板即可:// 控制器侧代码 public function businessSpacePage() { // 这里替换成你实际获取$locationinfo的逻辑 $locationinfo = Location::query()->find(3); return view('pages.business-space.index', compact('locationinfo')); }
子模板t1.blade.php里直接遍历变量,不需要做json_decode:<div class="location-info"> <h1>{{ $locationinfo->business_name }}</h1> @include('pages.business-space.templates.t1', compact('locationinfo')) </div>@foreach($locationinfo as $key => $value) <p>{{ $key }}: {{ $value }}</p> @endforeach - 方案2:动态渲染场景(比如点击标点、交互后才加载该内容)
不要在JS里拼接@include指令,单独写一个接口负责渲染子模板,JS动态请求拿到渲染完成的HTML片段再插入页面:- 先加路由和对应的控制器方法:
// routes/web.php 里加路由 Route::post('/location/render-tpl', [LocationController::class, 'renderLocationTpl']); // 控制器里加对应方法 public function renderLocationTpl(Request $request) { // 校验传参合法性,根据自己的字段规则调整 $validData = $request->validate([ 'id' => 'required|integer', 'business_name' => 'required|string', 'business_address' => 'nullable|string', 'lat' => 'required|numeric', 'lng' => 'required|numeric' ]); // 直接把校验后的数据传给子模板渲染,返回HTML片段 return view('pages.business-space.templates.t1', [ 'locationinfo' => (object)$validData ]); } - 调整JS代码,动态请求模板片段:
const loadTemplate = async (locationinfo) => { // 请求服务端拿到渲染好的子模板HTML const resp = await fetch('/location/render-tpl', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content') }, body: JSON.stringify(locationinfo) }); const tplContent = await resp.text(); return ` <div class="location-info"> <h1>${locationinfo.business_name}</h1> ${tplContent} </div> `; }
- 先加路由和对应的控制器方法:
- 临时应急方案(不推荐生产环境长期使用)
如果暂时不想调整整体逻辑,可以在PHP侧先把被转义的字符串还原,再做JSON解码,同时加类型判断避免报错:
这个方案只是临时解决转义问题,本质上JS拼接Blade指令的逻辑维护性极差,很容易出现注入、转义类的bug,后续迭代建议还是换成前面两种正规实现。// 先反转义HTML实体,再去掉多余的转义反斜杠 $cleanJsonStr = stripslashes(html_entity_decode($locationinfo)); $arr = json_decode($cleanJsonStr, true); // 加判断,解码失败就不遍历,避免报错 if (is_array($arr)) { foreach ($arr as $key => $value) { echo $key; } }
内容的提问来源于stack exchange,提问作者wenreloz
相关产品推荐
相关产品推荐

