Парсер JSON для PHP, который поддерживает комментарии - PullRequest
10 голосов
/ 16 ноября 2011

Может кто-нибудь предложить парсер JSON, который разрешает любые виды комментариев, с привязками PHP - очень нужны комментарии для конфигурационных файлов, но json_decode их не поддерживает.

(мне известно:1. другой формат, такой как YAML, 2. комментарии не являются частью стандарта)

Обновление:

Почему бы нам не использовать:

  • YAML: тесты показывают, что это медленнее - и мы могли бы хотеть отправлять данные по проводам - ​​не уверены, что YAML лучше для этого.

  • XML: слишком многословно - требуется простое редактирование человеком.И нет необходимости в расширенных возможностях XML.

  • INI: в данных есть иерархия и вложенность переменной глубины.И нам нужен повсеместный формат, поскольку данные могут распространяться вместе с приложениями или работать с приложениями на других языках.

  • Предварительная обработка: данные могут передаваться и распространяться пользователями, что сложно навязатьтребование предварительной обработки перед добавлением данных в приложение.

Ответы [ 4 ]

8 голосов
/ 20 апреля 2012

Если вам нужна переносимость и вы не хотите, чтобы какая-либо предварительная обработка исправляла нестандартные компоненты, тогда 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;
    }
4 голосов
/ 16 апреля 2017

Вы можете использовать следующую функцию для декодирования комментариев 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);
}

Поддерживаются все комментарии в стиле PHP: / *, #, //. Строковые значения сохраняются как есть.

2 голосов
/ 16 ноября 2011

Комментарии не являются частью JSON, поэтому для принятия комментариев не требуется "JSON-анализатор".

Я бы использовал YAML.Даже если синтаксический анализ выполняется немного медленнее (в PHP есть собственный анализатор JSON, но нет собственного синтаксического анализатора YAML), он, вероятно, игнорируется, а если нет, вы всегда можете кэшировать анализируемый объект.Кроме того, поскольку синтаксический анализатор PHP JSON не поддерживает комментарии, вам придется использовать не нативные, то есть он, скорее всего, не будет быстрее, чем синтаксический анализатор YAML (при условии, что оба написаны хорошо)

1 голос
/ 24 января 2019

Другой вариант - разрешить пользователям вставлять комментарии как неиспользуемые поля в структуру JSON:

{
  "color": "red",
  "color//": "may be red, green or blue"
}

Если вы используете только JSON для ввода, и он никогда не сохраняется на компьютере, вы можете злоупотребить форматом, чтобы использовать одно и то же поле несколько раз, случайно добиваясь почти полного удаления комментариев при разборе (как правило, только первого или последнее значение поля будет сохранено в разобранной структуре):

{
  "color": "red",      "//":"may be red, green or blue",
  "shape": "circle",   "//":"use circle, square or triangle",
  "timeout": 5,        "//":"timeout in seconds; default is 10"
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...