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

Laravel如何接收单引号包裹的JSON数据?

解决Laravel无法识别单引号包裹JSON的问题

这个问题很常见——因为标准JSON要求必须用双引号包裹键和值,而RapidPro发送的单引号格式不符合规范,导致Laravel的Request对象无法自动解析,所以返回空数组。好在不用修改第三方API,我们可以在Laravel端手动处理请求内容,下面给你两种可行的方案:

方案一:在控制器中手动解析请求内容

直接在你的sms方法里获取原始请求体,处理单引号后再解析成数组,这样最快见效:

public function sms(Request $request) {
    // 获取原始的请求内容
    $rawContent = $request->getContent();
    
    // 第一步:把键名的单引号替换成双引号(比如 'contact': → "contact":)
    $fixedJson = preg_replace("/'(\w+)':/", '"$1":', $rawContent);
    // 第二步:把值的单引号替换成双引号
    $fixedJson = str_replace("'", '"', $fixedJson);
    
    // 解析处理后的JSON为数组
    $parsedData = json_decode($fixedJson, true) ?? [];
    
    // 写入文件并返回结果
    Storage::put('sms.txt', json_encode($parsedData, JSON_PRETTY_PRINT));
    return response()->json($parsedData);
}

注意事项

如果RapidPro发送的JSON中存在字符串包含单引号的情况(比如'I'm testing'),直接替换会导致JSON格式错误。这种情况下可以用更严谨的正则来处理,只替换键名和值边界的单引号:

// 更严谨的替换逻辑,避免破坏字符串内部的单引号
$fixedJson = preg_replace('/(?<!\\\\)\'([^\']*?)(?<!\\\\)\'/', '"$1"', $rawContent);
$fixedJson = preg_replace("/'(\w+)':/", '"$1":', $fixedJson);

方案二:创建全局/路由中间件自动处理

如果有多个接口需要处理这种非标准JSON,可以创建一个中间件,让请求在到达控制器前就完成解析:

1. 创建中间件文件

在app/Http/Middleware目录下创建ParseSingleQuoteJson.php:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class ParseSingleQuoteJson
{
    public function handle(Request $request, Closure $next)
    {
        // 检查请求是否是JSON类型,且包含单引号
        if ($request->isJson() && strpos($request->getContent(), "'") !== false) {
            $rawContent = $request->getContent();
            
            // 处理单引号JSON
            $fixedJson = preg_replace("/'(\w+)':/", '"$1":', $rawContent);
            $fixedJson = str_replace("'", '"', $fixedJson);
            
            // 替换请求的解析后数据
            $parsedData = json_decode($fixedJson, true) ?? [];
            $request->replace($parsedData);
        }

        return $next($request);
    }
}

2. 注册中间件

打开app/Http/Kernel.php,在$routeMiddleware数组中添加:

protected $routeMiddleware = [
    // ...其他中间件
    'singlequote.json' => \App\Http\Middleware\ParseSingleQuoteJson::class,
];

3. 在路由中使用中间件

修改你的路由,添加中间件:

Route::post('sms', 'UserController@sms')->name('sms.store')->middleware('singlequote.json');

这样处理后,你原来的控制器代码就能正常使用$request获取数据了,不需要再手动解析。


内容的提问来源于stack exchange,提问作者Bw. Kizito

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:56:07