Search code examples
phpjsoncomments

A JSON parser for PHP that supports comments


Can anyone suggest a JSON parser that allows any kind of comments, with PHP bindings - need the comments badly for config files but json_decode doesn't support them.

(I am aware of: 1. other format such as YAML, 2. comments are not part of the standard)

Update:

Why don't we use:

  • YAML: Benchmarks show it's slower - and we might want to send the data over the wire - not sure if YAML is best for that.

  • XML: too verbose - simple human editing is a requirement. And no need for the extended features of XML.

  • INI: there is hierarchy and nesting of variable depth in the data. And we need a ubiquitous format as the data might be distributed with apps or work with apps in other languages.

  • Pre-processing: data can be contributed and shared by users, tough to impose a requirement to pre-process before adding data to an app.


Solution

  • YAML

    If you need portability and don't want any pre-processing or non-standard syntax, then YAML is probably the way to go. Though, beware of the dangers and caveats of YAML.

    Most, if not all, of JSON is compatible with YAML (YAML is a superset of JSON), and it supports comments. So the initial switch is easy.

    JSON with comments

    I recently needed to migrate from INI files in PHP to something that has support for integers and booleans, but still supported comments as well.

    JSON seemed like a good format, except for supporting comments. If you want to make this work, you don't need a whole custom JSON parser. It can be made to work with simple wrapper that strips the comments uses the native json_decode after that. (This works for sane content that trusted people author. If you allow crazy inputs there is probably a way to break this.)

    Code from github.com/countervandalism/stillalive, with the regex from @makaveli_lcf:

    class JsonUtil {
        /**
         * From https://stackoverflow.com/a/10252511/319266
         * @return array|false
         */
        public static function load( $filename ) {
            $contents = @file_get_contents( $filename );
            if ( $contents === false ) {
                return false;
            }
            return json_decode( self::stripComments( $contents ), true );
        }
        /**
         * From https://stackoverflow.com/a/10252511/319266
         * @param string $str
         * @return string
         */
        protected static function stripComments( $str ) {
            return preg_replace( '![ \t]*//.*[ \t]*[\r\n]!', '', $str );
        }
    }