Я получаю сообщение «Неустранимая ошибка: допустимый объем памяти XXXX байтов исчерпан …». Мне нужно перебрать большое количество записей и выполнить функцию для проверки соответствия записи критериям, которые объявляют множество переменных класса.
foreach ($results as $row)
{
$location = Location::parseDatabaseRow($row);
if ($location->contains($lat, $lon))
{
$found = true;
$locations[] = $location;
break;
}
}
Реализация класса Location:
public function contains($lat, $lon)
{
$polygon =& new polygon();
.... //Add points to polygons base on location polygons
$vertex =& new vertex($lat, $lon);
$isContain = $polygon->isInside($vertex);
$polygon->res(); //Reset all variable inside polygons
$polygon = null; //Let Garbage Collector clear it whenever
return ($isContain);
}
Разве $ polygon не должен быть понятен, когда метод метода visible () возвращается? Что я могу сделать, чтобы уменьшить использование памяти?
Я разработчик Java и начал изучать PHP. Пожалуйста, помогите мне понять, как управлять размером стека и распределением памяти. Заранее спасибо.
Я разработчик Java и начал изучать PHP.
Вот некоторые исправления, которые могут позволить вашему коду не исчерпать лимит памяти.
использовать некоторое время. Так как ваш результат приходит из запроса к базе данных, вы должны иметь возможность использовать fetch()
вместо fetchAll()
который я предполагаю, что вы используете, так как вы применяете foreach()
в теме.
while ($row = $result->fetch()) { // here $result is supposed to be a PDOStatatement.
$location = Location::parseDatabaseRow($row);
if ($location->contains($lat, $lon)) {
$found = true; // where is this used?
$locations[] = $location;
break;
}
}
Хотя использует меньше памяти, потому что не все результаты выбираются одновременно.
используйте амперсанд и правильный путь. Вы делаете новое в каждом цикле. Амперсанд используется, когда вы хотите передать значение посредством ссылки на функцию, чтобы на него оказывалось влияние вне этой области действия функции без необходимости его возврата.
Здесь вы используете объекты, которые несколько передано по ссылке по дизайну.
public function contains($lat, $lon) {
$polygon = new polygon();
$vertex = new vertex($lat, $lon);
return $polygon->isInside($vertex);
// no need to reset the values of your polygon, you will be creating a new one on the next loop.
}
для полноты здесь приведу версию, использующую тот же объект многоугольника. Обратите внимание, как я не использую амперсанд, потому что мы передаем объект.
$polygon = new polygon();
while ($row = $result->fetch()) { // here $result is supposed to be a PDOStatatement.
$location = Location::parseDatabaseRow($row);
if ($location->contains($lat, $lon, $polygon)) {
$found = true; // where is this used?
$locations[] = $location;
break;
}
}
public function contains($lat, $lon, $polygon) {
//Add points to the passed polygon
$vertex = new vertex($lat, $lon);
$isContain = $polygon->isInside($vertex);
$polygon->res();
// since we eill be using the same $polygon, now we need to reset it
return $isContain;
}
Других решений пока нет …