복붙노트

PHP로 큰 JSON 파일 처리하기

PHP

PHP로 큰 JSON 파일 처리하기

JSON 파일 (아마도 최대 200M)을 다소 처리하려고합니다. 파일의 구조는 기본적으로 객체 배열입니다.

그래서 라인을 따라 뭔가 :

[
  {"property":"value", "property2":"value2"},
  {"prop":"val"},
  ...
  {"foo":"bar"}
]

각 객체는 임의의 속성을 가지므로 배열의 다른 객체와 공유 할 필요가 없습니다 (동일한 경우와 마찬가지로).

배열의 각 객체에 처리를 적용하고 파일이 잠재적으로 거대하므로 JSON을 디코딩하고 PHP 배열을 반복하여 메모리에있는 전체 파일 내용을 버릴 수는 없습니다.

그래서 이상적으로 파일을 읽고 각 객체에 대한 충분한 정보를 가져 와서 처리하고 싶습니다. JSON에 사용할 수있는 유사한 라이브러리가 있다면 SAX 유형의 접근 방식은 괜찮습니다.

이 문제를 가장 잘 처리 할 수있는 방법에 대한 제안이 있으십니까?

해결법

  1. ==============================

    1.나는 이벤트 기반 파서 (parser) 기반의 작업에 착수했다. 아직 완료되지 않았으며 만족스러운 버전을 출시 할 때 내 작업에 대한 링크로 질문을 편집합니다.

    나는 이벤트 기반 파서 (parser) 기반의 작업에 착수했다. 아직 완료되지 않았으며 만족스러운 버전을 출시 할 때 내 작업에 대한 링크로 질문을 편집합니다.

    편집하다:

    마침내 만족 스럽다는 파서의 버전을 만들었습니다. GitHub에서 사용할 수 있습니다.

    https://github.com/kuma-giyomu/JSONParser

    아마도 개선의 여지가 있고 피드백을 환영합니다.

  2. ==============================

    2.필자는 XMLReader에 기반한 API를 사용하여 PHP 7 용 스트리밍 JSON 끌어 오기 파서 (parser) 인 pcrov / JsonReader를 작성했습니다.

    필자는 XMLReader에 기반한 API를 사용하여 PHP 7 용 스트리밍 JSON 끌어 오기 파서 (parser) 인 pcrov / JsonReader를 작성했습니다.

    콜백을 설정하고 파서가 그 일을 처리하는 대신 파서에서 메소드를 호출하여 원하는대로 데이터를 이동하거나 검색 할 수 있다는 점에서 이벤트 기반 파서와 상당히 다릅니다. 원하는 비트를 찾았으며 파싱을 중단 하시겠습니까? 그런 다음 구문 분석을 중단하고 (할 수있는 좋은 일이기 때문에 close ()를 호출하십시오.)

    (pull-vs 이벤트 기반 파서에 대한 좀 더 긴 개관을 보려면 XML reader 모델 : SAX 대 XML pull 파서를 참조하십시오.)

    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을 가장 잘 읽는 방법은 JSON의 구조와 원하는 작업에 따라 다릅니다. 이 예제는 시작해야 할 곳을 제공해야합니다.

  3. ==============================

    3.이 같은 것이 있지만 C ++과 Java에서만 존재합니다. PHP에서 이러한 라이브러리 중 하나에 액세스 할 수 없다면 PHP에서는 구현이 아니라 json_read ()에서 알 수 있습니다. 그러나 json이 단순한 구조로되어 있다면 다음 번까지 파일을 읽고 json_read ()를 통해받은 JSON을 처리하는 것이 쉽습니다. 그러나 10kb를 읽는 것과 같이 흩어져서 읽는 것과 같이 버퍼링 된 것을 더 잘 수행해야합니다. 찾지 못하면 다른 10k를 읽은 다음 발견 된 값을 처리해야합니다. 그런 다음 다음 블록을 읽습니다.

    이 같은 것이 있지만 C ++과 Java에서만 존재합니다. PHP에서 이러한 라이브러리 중 하나에 액세스 할 수 없다면 PHP에서는 구현이 아니라 json_read ()에서 알 수 있습니다. 그러나 json이 단순한 구조로되어 있다면 다음 번까지 파일을 읽고 json_read ()를 통해받은 JSON을 처리하는 것이 쉽습니다. 그러나 10kb를 읽는 것과 같이 흩어져서 읽는 것과 같이 버퍼링 된 것을 더 잘 수행해야합니다. 찾지 못하면 다른 10k를 읽은 다음 발견 된 값을 처리해야합니다. 그런 다음 다음 블록을 읽습니다.

  4. ==============================

    4.이것은 큰 JSON 문서를 처리하기위한 간단한 스트리밍 파서입니다. 매우 큰 JSON 문서를 구문 분석하여 전체 내용을 메모리에로드하는 것을 피하십시오. 이는 PHP의 다른 모든 JSON 파서가 작동하는 방식입니다.

    이것은 큰 JSON 문서를 처리하기위한 간단한 스트리밍 파서입니다. 매우 큰 JSON 문서를 구문 분석하여 전체 내용을 메모리에로드하는 것을 피하십시오. 이는 PHP의 다른 모든 JSON 파서가 작동하는 방식입니다.

    https://github.com/salsify/jsonstreamingparser

  5. ==============================

    5.http://github.com/sfalvo/php-yajl/입니다. 직접 사용하지 않았습니다.

    http://github.com/sfalvo/php-yajl/입니다. 직접 사용하지 않았습니다.

  6. from https://stackoverflow.com/questions/4049428/processing-large-json-files-in-php by cc-by-sa and MIT license