Как преобразовать выборку getCollection в JSON?

Здравствуйте.
Больше полгода у меня на сайте собиралась статистика геолокации, все писалось в созданную таблицу Geolocation. Теперь хочу все эти координаты наложить как метки на карту Google Maps. По клику кнопки идет Ajax-запрос на выборку из БД, возвращается json-строка с координатами меток. Ну и там дальше идет javascript для визуализации меток на карте. Так вот, не могу вернуть выборку в JSON формате. Получается 500 Internal error

Если выполнить в консоли то

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 98570240 bytes) in /var/www/web4/www/core/xpdo/xpdo.class.php on line 2414
Хотя в переменной $result есть массив объектов которые можно обработать в цикле и вывести их значения.
Что не так с этим Json?

Вот код выборки:
<?php
$modx->getService('error','error.modError');
$modx->setLogLevel(modX::LOG_LEVEL_INFO);
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
if (isset($_POST['action'])) {
    $query= $modx->newQuery('Geolocations');
    $query->where(array('acc:<' => 1000));
    $result = $modx->getCollection('Geolocations', $query);
    $json = $modx->toJSON($result);
    return $json;   
    }
?>
Сергей Росоловский
12 марта 2017, 09:12
modx.pro
1
2 797
0

Комментарии: 8

Марат Марабар
12 марта 2017, 09:57
+1
Не хватает памяти на выполнение скрипта. Попробуй в начале скрипта установить своё значение memory_limit
ini_set('memory_limit', '500');
А много вообще записей в БД?
    Сергей Росоловский
    12 марта 2017, 12:18
    0
    Записей порядка 1000. Но почитав статьи Василия про xPDO, понял что лучше выборку делать через PDO и работать с массивами, а не с объектами. Оказывается объекты жрут память нехило. Ну и работу с Ajax запросами в MODx тоже переосмыслил. Теперь все работает и памяти хватает :) Спасибо.
      Волков Николай
      12 марта 2017, 15:09
      0
      Объекты, действительно жрут много памяти, если использовать getCollection в том виде, как у вас. В случае использования getIterator с памятью все значительно лучше. Также можно использовать такой способ:
      foreach($modx->getCollection('Geolocations', $q) as & $obj) {
      .....
      }
      Знак & после as и указание метода getCollection внутри foreach аналогично позволяет значительно снизить потребление памяти:-)
    Волков Николай
    12 марта 2017, 14:39
    0
    $result = $modx->getCollection('Geolocations', $query);
    $json = $modx->toJSON($result);
    Адский ад какой-то. Зачем в JSON нужно хранить массив классов? Нужно, вроде данные только нужны? Поэтому:

    foreach($modx->getCollection('Geolocations', $query) as & $geo) {
    	$arr[] = $get->toArray();
    }
    $result = $modx->toJSON($arr);
    Если с памятью беда остается, то можно прогнать через getIterator:

    $geos = $modx->getIterator('Geolocations', $query);
    foreach($geos as $geo) {
    	$arr[] = $get->toArray();
    }
    $result = $modx->toJSON($arr);
    Если и это не спасает, то вообще без объектов обойтись и работать на PDO.
      Сергей Росоловский
      12 марта 2017, 14:45
      0
      Спасибо, видимо я не совсем понял объектную модель MODx.
      Сделал попроще:

      $q = $modx->newQuery('Geolocations', array('acc:<' => 1000));
              $q->prepare();
              $q->stmt->execute();
              $res = $q->stmt->fetchAll(PDO::FETCH_ASSOC);
              $res = json_encode($res);
        Волков Николай
        12 марта 2017, 15:03
        0
        Собственно некое подобие этого кода я и подразумевал третьим пунктом:-) Единственное в if условиями запихнуть prepare и execute и остальное в случае успеха.
        Сергей Росоловский
        12 марта 2017, 15:02
        0
        Зачем в JSON нужно хранить массив классов?
        $result = $modx->getCollection('Geolocations', $query);
        Мне кажется на выходе будет массив объектов. Массив классов, по моему вы не это имели ввиду.
      Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
      8