php json_decode在密钥上没有引号的情况下失败


php json_decode fails without quotes on key

我有类似的json数据

{key:"value"}

(密钥附近没有引号…(

我想把它转换成一个关联数组。

PHP的json_decode返回空

如何在键周围添加引号??谢谢

您可以在源代码处修复JSON,使其返回有效的JSON结构,也可以手动在键周围添加引号。

这个类似问题的答案有一个如何做到这一点的例子:

function my_json_decode($s) {
    $s = str_replace(
        array('"',  "'"),
        array(''"', '"'),
        $s
    );
    $s = preg_replace('/('w+):/i', '"'1":', $s);
    return json_decode(sprintf('{%s}', $s));
}

如果您不能在源代码中将其转换为有效的JSON,那么您可以使用PEAR中的Services_JSON来解析它,因为在键周围添加引号是一个非常容易出错的过程。

Services_JSON将正确解析无效的密钥字符串。

示例:

$json = new Services_JSON();
var_dump($json->decode('{key:"value"}'));

输出:

object(stdClass)#2 (1) {
  ["key"]=>
  string(5) "value"
}

为了避免在不应该插入双引号的地方插入双引号,您应该在这个操作中跳过那些带引号的字符串。

例如,如果您在字符串中有以下JavaScript对象文字:

{
   dt:"2016-10-22T09:13:20",
   "x:y":false
}

则必须注意不要使CCD_ 3变为CCD_。同样,已引用的密钥"x:y"应保持不变。

您可以使用以下正则表达式来实现这一点:

preg_replace('/("(.*?)"|('w+))('s*:'s*(".*?"|.))/s', '"$2$3"$4', $text);

其他问题

JavaScript对象文字允许使用带有左填充零的数字常量,如001和/或带有一元+符号的数值常量,这在JSON中都是不允许的。要删除那些有问题的字符,你可以使用这个扩展版本:

preg_replace('/("(.*?)"|('w+))('s*:'s*)'+?(0+(?='d))?(".*?"|.)/s', '"$2$3"$4$6', $text);

不要使用REGEX

对于这种情况,完全不建议使用REGEX,不要将其用于解析此类数据。如果您有一个简单的目标,并且希望避免使用稳定的PEAR package,那么您可以尝试使用JSON-php库(但不再维护(。

1( 从这里获取JSON.phps文件并重命名为.php,并将构造函数函数名替换为__construct

2( 用法:

$content = '{myKey:"valueeeee"}';
include(__DIR__.'/JSON.php'); 
$this->json = new Services_JSON( SERVICES_JSON_LOOSE_TYPE );  // to return objects instead of Associative array, remove the argument
var_dump( $this->json->decode($content)  );

请不要使用regexp执行此操作!JSON语法无法通过定义以这种方式正确解析。你会让自己面对大量未来的bug。

我建议使用YAML解析器,因为YAML是JSON的超集,同时允许未引用的文字。

Symfony YAML组件运行良好。

与本机实现的json_decode相比,将存在性能损失。

$results = 'Symfony'Component'Yaml'Yaml::parse("{a: d, b: 'c', e: [a, 3]}");

您可能只能使用该lib,而不必使用整个Symfony包:https://packagist.org/packages/symfony/yaml

根据文档(请参阅示例#3-"使用json_decode时的常见错误"(,密钥必须用双引号括起来。

您从哪里获得JSON数据?

这对我有效,使用regex替换'/''s(''w+(''s/i'

$json =  file_get_contents("php://input"); // or whatever json data
$json = preg_replace('/'s('w+)'s/i', '"$1"', $json);
$json = json_decode($json, true);

我测试了这里提出的许多解决方案,但都没有正确运行。

  • @Intelekshual不能与更多的";复数";案例
$json='{hello:{a:2,b:3},world:[1,2,3,"aaa","bbbb"]}';
var_dump(my_json_decode($json)); // returns null
function my_json_decode($s) {
    $s = str_replace(
        array('"',  "'"),
        array(''"', '"'),
        $s
    );
    $s = preg_replace('/('w+):/i', '"'1":', $s);
    return json_decode(sprintf('{%s}', $s));
}
  • @rid和@T.Todua,该库不起作用,因为该代码以PHP 4.x/5.x为目标,并且它有许多不推荐使用的功能

因此,我创建了一个对Services_JSON(PECL(的改编,并将代码更新到PHP 7.2及更高版本(包括PHP 8.1(。它可以与Composer一起使用,并且没有任何其他依赖关系。

https://github.com/EFTEC/Services_JSON

或者你可以从这里复制并粘贴代码:

https://github.com/EFTEC/Services_JSON/blob/main/src/Services_JSON.php