(Источник из здесь .)
Обозначение в квадратных скобках позволяет использовать символы, которые нельзя использовать с точечными обозначениями:
var foo = myForm.foo[]; // incorrect syntax var foo = myForm["foo[]"]; // correct syntax
, включая не-ASCII (UTF-8) символы, как в myForm["ダ"]
( больше примеров ).
Во-вторых, нотация в квадратных скобках полезна при работе с именами свойств, которые изменяются предсказуемым образом:
for (var i = 0; i < 10; i++) { someFunction(myForm["myControlNumber" + i]); }
Сводка новостей:
- Точечная запись быстрее пишется и чище.
- Обозначение в квадратных скобках позволяет получить доступ к свойствам, содержащим специальные символы, и выбрать свойства с помощью переменных
Еще один пример символов, которые нельзя использовать с точечными обозначениями, - имена свойств, которые сами содержат точку .
Например, ответ json может содержать свойство под названием bar.Baz
.
var foo = myResponse.bar.Baz; // incorrect syntax
var foo = myResponse["bar.Baz"]; // correct syntax
Я решил поработать над анализатором событий. Это еще не совсем сделано, и я отредактирую вопрос со ссылкой на мою работу, когда я выложу удовлетворительную версию.
РЕДАКТИРОВАТЬ:
Я наконец разработал версию синтаксического анализатора, который меня устраивает. Он доступен на GitHub:
https://github.com/kuma-giyomu/JSONParser
Возможно, есть место для некоторых улучшений, и я приветствую отзывы.
Я написал потоковый синтаксический анализатор JSON pcrov / JsonReader для PHP 7 с API, основанным на XMLReader .
Он значительно отличается от синтаксических анализаторов на основе событий тем, что вместо настройки обратных вызовов и предоставления возможности анализатору выполнять свои функции, вы вызываете методы синтаксического анализатора для перемещения вперед или извлечения данных по желанию. Нашли нужные вам биты и хотите прекратить разбор? Затем прекратите синтаксический анализ (и вызовите close()
, потому что это хорошо.)
(Для более длинного обзора парсеров, основанных на событиях, по сравнению с событиями см. Модели чтения XML: SAX против XML pull parser .)
Считывание каждого объекта целиком из вашего JSON.
use pcrov\JsonReader\JsonReader;
$reader = new JsonReader();
$reader->open("data.json");
$reader->read(); // Outer array.
$depth = $reader->depth(); // Check in a moment to break when the array is done.
$reader->read(); // Step to the first object.
do {
print_r($reader->value()); // Do your thing.
} while ($reader->next() && $reader->depth() > $depth); // Read each sibling.
$reader->close();
Array
(
[property] => value
[property2] => value2
)
Array
(
[prop] => val
)
Array
(
[foo] => bar
)
Объекты возвращаются в виде массивов со строковыми ключами из-за (частично) крайних случаев, когда допустимый JSON будет производить имена свойств, которые не разрешены в объектах PHP. Обойти эти конфликты не стоит, так как анемичный объект stdClass в любом случае не имеет значения по сравнению с простым массивом.
Чтение каждого названного элемента в отдельности.
$reader = new pcrov\JsonReader\JsonReader();
$reader->open("data.json");
while ($reader->read()) {
$name = $reader->name();
if ($name !== null) {
echo "$name: {$reader->value()}\n";
}
}
$reader->close();
property: value
property2: value2
prop: val
foo: bar
Прочитать каждое свойство с заданным именем. Бонус: чтение из строки вместо URI, плюс получение данных из свойств с повторяющимися именами в одном и том же объекте (что допустимо в JSON, как весело.)
$json = <<<'JSON'
[
{"property":"value", "property2":"value2"},
{"foo":"foo", "foo":"bar"},
{"prop":"val"},
{"foo":"baz"},
{"foo":"quux"}
]
JSON;
$reader = new pcrov\JsonReader\JsonReader();
$reader->json($json);
while ($reader->read("foo")) {
echo "{$reader->name()}: {$reader->value()}\n";
}
$reader->close();
foo: foo
foo: bar
foo: baz
foo: quux
Как лучше всего прочитать ваш JSON, зависит от его структуры и того, что вы хотите с ним делать. Эти примеры должны дать вам место для начала.
Существует нечто подобное, но только для C ++ и Java . Если вы не можете получить доступ к одной из этих библиотек из PHP, в PHP нет реализации для этого, но, насколько я знаю, json_read()
. Однако, если json структурирован так просто, легко просто прочитать файл до следующего }
и затем обработать JSON, полученный через json_read()
. Но вам лучше сделать это в буфере, например, прочитать 10 КБ, разделить на}, если не найдено, прочитать еще 10 КБ и обработать найденные значения. Затем прочитайте следующий блок и т. Д.
Это простой потоковый анализатор для обработки больших JSON-документов. Используйте его для анализа очень больших JSON-документов, чтобы избежать загрузки всего этого в память, как работает практически любой другой JSON-анализатор для PHP.
Недавно я создал библиотеку под названием JSON Machine, которая эффективно анализирует непредсказуемо большие файлы JSON. Использование через простой foreach
. Я сам использую его для своего проекта.
Пример:
foreach (JsonMachine::fromFile('employees.json') as $employee) {
$employee['name']; // etc
}
Существует http://github.com/sfalvo/php-yajl/ Я не использовал его сам.
Я знаю, что JSON потоковая передача синтаксического анализатора https://github.com/salsify/jsonstreamingparser был уже упомянут. Но поскольку я недавно имею (выход), добавил новый слушатель его, чтобы попытаться помочь использовать из поля, я думал, что (для разнообразия) произведу некоторую информацию тем, что он делает...
существует очень хорошая запись об основном синтаксическом анализаторе в [1 115] https://www.salsify.com/blog/engineering/json-streaming-parser-for-php, но проблема, которую я имею со стандартной установкой, была то, что всегда необходимо было писать слушателю для обработки файла. Это - не всегда простая задача и может также взять определенное количество обслуживания если/когда измененный JSON. Таким образом, я записал RegexListener
.
основной принцип должен позволить Вам говорить, какие элементы Вы интересуетесь (через regex выражение) и даете ему обратный вызов для высказывания, что сделать, когда оно находит данные. При чтении JSON это отслеживает путь к каждому компоненту - подобный структуре каталогов. Так /name/forename
или для массивов /items/item/2/partid
- это - то, против чего соответствует regex.
пример (от источник на github)...
$filename = __DIR__.'/../tests/data/example.json';
$listener = new RegexListener([
'/1/name' => function ($data): void {
echo PHP_EOL."Extract the second 'name' element...".PHP_EOL;
echo '/1/name='.print_r($data, true).PHP_EOL;
},
'(/\d*)' => function ($data, $path): void {
echo PHP_EOL."Extract each base element and print 'name'...".PHP_EOL;
echo $path.'='.$data['name'].PHP_EOL;
},
'(/.*/nested array)' => function ($data, $path): void {
echo PHP_EOL."Extract 'nested array' element...".PHP_EOL;
echo $path.'='.print_r($data, true).PHP_EOL;
},
]);
$parser = new Parser(fopen($filename, 'r'), $listener);
$parser->parse();
Просто несколько объяснений...
'/1/name' => function ($data)
Так эти /1
второй элемент в массиве (0 базирующихся), таким образом, это позволяет получать доступ к конкретным экземплярам элементов. /name
name
элемент. Значение затем передается закрытию как [1 111]
"(/\d*)" => function ($data, $path )
, Это выберет каждый элемент массива и передаст его по одному, поскольку он использует группу получения, эта информация будет передана как [1 112]. Это означает, когда ряд записей присутствует в файле, можно обработать каждый объект по одному. И также знайте который элемент, не имея необходимость отслеживать.
последний
'(/.*/nested array)' => function ($data, $path):
эффективно сканирования для любых элементов, названных nested array
и передачи каждый наряду с тем, где это находится в документе.
Другая полезная функция, которую я нашел, была то, что, если в большом файле JSON, Вы просто хотели сводные детали наверху, можно захватить те биты и затем просто остановиться...
$filename = __DIR__.'/../tests/data/ratherBig.json';
$listener = new RegexListener();
$parser = new Parser(fopen($filename, 'rb'), $listener);
$listener->setMatch(["/total_rows" => function ($data ) use ($parser) {
echo "/total_rows=".$data.PHP_EOL;
$parser->stop();
}]);
Это экономит время, когда Вы не интересуетесь остающимся содержанием.
Одна вещь отметить состоит в том, что они будут реагировать на содержание, так, чтобы каждый был инициирован, когда конец контента соответствия найден и может быть в различных заказах. Но также и что синтаксический анализатор только отслеживает содержание, которым Вы интересуетесь, и отбрасывает что-либо еще.
при нахождении каких-либо интересных функций (иногда ужасно знают как ошибки), сообщите мне или сообщите о проблеме на странице GitHub.