用于PHP的JSON解析器,支持注释

Bas*_*ani 10 php json comments

任何人都可以建议一个JSON解析器允许任何类型的注释,使用PHP绑定 - 需要严重的配置文件的评论,但json_decode不支持它们.

(我知道:1.其他格式如YAML,2.评论不属于标准的一部分)

更新:

我们为什么不使用:

  • YAML:基准测试显示速度较慢 - 我们可能希望通过网络发送数据 - 不确定YAML是否最适合.

  • XML:太冗长 - 简单的人工编辑是必需的.而且不需要XML的扩展功能.

  • INI:数据中存在可变深度的层次结构和嵌套.我们需要一种无处不在的格式,因为数据可能与应用程序一起分发,也可能与其他语言的应用程序一起使用.

  • 预处理:数据可以由用户提供和共享,在向应用添加数据之前很难强制要求预处理.

Tim*_*hof 8

如果您需要可移植性并且不希望任何预处理来修复非标准组件,那么YAML可能就是您的选择.

大多数(如果不是全部)JSON与YAML兼容(YAML是JSON的超集),它支持注释.

对于最近的项目,我觉得有必要放弃.ini我们的"默认设置"文件 - 这样我们就不再需要将一些字符串转换为整数或布尔值(因为parse_ini_file将值解析为字符串,foo=1或者foo=true都是字符串值).

JSON似乎是一个很好的格式,但它不支持评论.但是,如果你想让这个工作,我建议不要完全实现(或使用)一个单独的JSON解析器.我所做的是创建一个简单的包装函数,用正则表达式去除注释,然后使用本机json_decode.

来自https://github.com/countervandalism/stillalive/blob/v2018.11/src/Util.php#L21-L41的示例:

class Util {
    /**
     * From https://stackoverflow.com/a/10252511/319266
     * @return bool|array
     * @throws ParseException
     */
    public static function loadConfig( $filename ) {
        $contents = @file_get_contents( $filename );
        if ( $contents === false ) {
            return false;
        }
        return json_decode( self::stripComments( $contents ), true );
    }
    /**
     * From https://stackoverflow.com/a/19136663/319266
     * @param string $str
     */
    public static function stripComments( $str = '' ) {
        $str = preg_replace( '![ \t]*//.*[ \t]*[\r\n]!', '', $str );
        return $str;
    }
Run Code Online (Sandbox Code Playgroud)

  • 正则表达式中前导和尾随的“!”的作用是什么? (2认同)
  • @JohnArcher 好问题!这里的“!”刘海用作正则表达式分隔符——取代了传统的“/”斜杠。我这里的正则表达式包括斜杠本身,这意味着否则需要转义这些斜杠。有时您可能还会看到“#”、“%”或“~”用作分隔符。另请参阅 [php.net/regexp.reference.delimiters](https://www.php.net/regexp.reference.delimiters)。 (2认同)
  • 请注意,本文中的正则表达式不处理嵌入注释的字符串;`{ "hello": "world // blah" }` 将替换为 `{ "hello": "world`,这是无效的 JSON。 (2认同)

Ale*_*tak 5

您可以使用以下函数来解码注释的 json:

function json_decode_commented($json, $assoc = false, $maxDepth = 512, $opts = 0) {
  $data = preg_replace('~
    (" (?:\\\\. | [^"])*+ ") | \# [^\v]*+ | // [^\v]*+ | /\* .*? \*/
  ~xs', '$1', $data);

  return json_decode($json, $assoc, $maxDepth, $opts);
}
Run Code Online (Sandbox Code Playgroud)

它支持所有 PHP 风格的注释:/*、#、//。字符串值按原样保留。

  • 这是比公认的解决方案更好的解决方案。顺便说一句,我创建了一个包并使用这个解决方案而不是我自己的:unional/jsonc (2认同)