Проблемы с памятью при создании большого массива PHP для листовки - PullRequest
0 голосов
/ 27 января 2020

У меня есть MySQL 8 пространственная база данных с около 450 записями. К сожалению, я не могу использовать PostGre / PostGIS в своем веб-пространстве, с чем я более знаком. Для локального тестирования я использую Xampp с php для загрузки данных в карту листовки.

Я получил сообщение об ошибке:

Неустранимая ошибка: допустимый объем памяти 134217728 байт исчерпан (попытка выделить 135168 байт) в C: \ xampp \ htdocs \ xgis \ php \ test3. php в строке 21

Это указывает на 'geometry' => json_decode($row['geo'])

Общая длина данных всех 450 записей составляет около 11 МБ

Самый большой запись имеет 85 000 символов как json (в основном запись SHAPE). Если я уменьшу прецессию с ST_AsGeo JSON (SHAPE, 5) до 4, я получу 78.500 символов. Если я сохраню его в notepadd, это будет около 80 КБ

Если я использую локальный: ini_set('memory_limit', '1024M'); Я получил ожидаемый результат. Но я не хочу использовать это онлайн. Поэтому я попытался буферизовать результат с помощью MYSQLI_USE_RESULT, но получил сообщение об ошибке. Я прочитал несколько сообщений и php do c о проблеме, но я не нашел решения.

<?php
    //ini_set('memory_limit', '1024M');
    // mysqli_set_charset($conn,'utf8');
    $sql = "SELECT *, ST_AsGeoJSON(SHAPE,5) as geo FROM gem_grenzen;";

    $geojson = array(
       'type'      => 'FeatureCollection',
       'features'  => array()
    );


    $result = $conn->query($sql, MYSQLI_USE_RESULT);

        while($row = $result->fetch_assoc()) {
            $properties = $row;
            unset($properties['geo']);
            unset($properties['SHAPE']);

            $feature = array(
                 'type' => 'Feature',
                 'geometry' => json_decode($row['geo']), 
                 'properties' => $properties 
            );
            array_push($geojson['features'], $feature);

        }

    echo 'var $foo =';
    echo json_encode($geojson, JSON_NUMERIC_CHECK);
    echo "; \r\n";
    echo 'L.geoJSON($foo,{style:style_gem}).addTo(map);';
    ?>

1 Ответ

0 голосов
/ 27 января 2020

Я отладил / отследил свой скрипт с помощью Xdebug https://xdebug.org с настройками xdebug.auto_trace и xdebug.show_mem_delta. В результате проблема с памятью вызвана array_push($geojson['features'], $feature);

0.4779  130073936   -44160         -> json_decode() C:\xampp\htdocs\xgis\php\test3.php:22
0.4783  130459928  +385992         -> array_push() C:\xampp\htdocs\xgis\php\test3.php:25
0.4784  130459928       +0         -> mysqli_result->fetch_assoc() C:\xampp\htdocs\xgis\php\test3.php:14
0.4785  130542744   +82816         -> json_decode() C:\xampp\htdocs\xgis\php\test3.php:22
0.4798  131909512 +1366768         -> array_push() C:\xampp\htdocs\xgis\php\test3.php:25
0.4799  131909512       +0         -> mysqli_result->fetch_assoc() C:\xampp\htdocs\xgis\php\test3.php:14
0.4799  131853048   -56464         -> json_decode() C:\xampp\htdocs\xgis\php\test3.php:22
0.4806  132541400  +688352         -> array_push() C:\xampp\htdocs\xgis\php\test3.php:25
0.4806  132541400       +0         -> mysqli_result->fetch_assoc() C:\xampp\htdocs\xgis\php\test3.php:14

Так что мне нужно переписать код с помощью листовой группы объектов и добавить каждую запись в качестве собственной переменной вместо одной большой массив.

...