Простой For-Loop приводит к ошибке исчерпания памяти - PullRequest
0 голосов
/ 06 июля 2018

Проработав более 4 часов над локализацией проблемы, я наконец нашел часть своего кода, которая приводит к следующей ошибке:

Неустранимая ошибка PHP: исчерпан допустимый объем памяти 268435456 байт (попытался выделить 8388608 байт) в

Я получаю данные из моей базы данных. Запрос возвращает массив данных с 33 записями (не так уж много ...) Я перебираю этот массив с помощью цикла for, чтобы получить разницу во времени и помечать массив, если разница слишком велика (просто if-else) .... Это довольно сложно объяснить, но я думаю, вы понимаете, что я имею в виду глядя на мой код ... все довольно просто:

for($i = 0; $i <= count($customerList); $i++) {

        $date1 = date_create($customerList[$i]["lastUpdate"]);
        $interval = date_diff($date1, $date2);

        $min=$interval->format('%i');
        $sec=$interval->format('%s');
        $hour=$interval->format('%h');
        $mon=$interval->format('%m');
        $day=$interval->format('%d');
        $year=$interval->format('%y');

        $date3 = date("H");

        if(($year > 0) || ($mon > 0) || ($day > 0)) {
            $customerList[$i]["flag"] = 1;
        }
        else {
            if($date3 >= 6 && $date3 <= 21) {
                if(($hour > 0) || ($min > 29)) {
                    $customerList[$i]["flag"] = 1;
                }
            }
        }
}

Переменная $date2 определена перед циклом for со следующей строкой кода:

$date2 = date_create($lastUpdateTime["lastUpdate"]);

К сожалению, я действительно не понимаю, как этот код может привести к этой ошибке, так как, на мой взгляд, это не должно использовать столько памяти ...

Я на 100% уверен, что ошибка происходит из-за этого цикла for, поскольку, когда я его удаляю, ошибка исчезает. Кроме того, когда я помещаю этот цикл for в другие представления, это приводит к той же самой ошибке.

Я решил проблему, увеличив максимальный предел памяти PHP, но мне все еще интересно, как этот цикл for может вызвать эту проблему.

Буду очень признателен за любые объяснения, так как в интернете ничего не нахожу ...

О, я просто добавлю сюда запрос, чтобы вы могли видеть, что я не получаю много данных (сайт обрабатывает гораздо большие запросы без проблем ...):

SELECT c.id, c.type, c.name, c.environment, cd.customer, MAX(cd.createdAt) AS lastUpdate FROM customerdata AS cd JOIN customers c ON cd.customer = c.id GROUP BY customer ORDER BY c.name ASC

Спасибо!

1 Ответ

0 голосов
/ 06 июля 2018

Состояние вашего for цикла $i<=count($customerList) вместо $i<count($customerList). Это означает, что ваш доступ к $customerList[$i] проходит один конец конца массива, создавая новый элемент на этом пути. Теперь count($customerList) на один больше, поэтому цикл занимает еще одну итерацию, ad infinum, тем самым используя все больше ОЗУ для растущего массива.

Вы также должны получить предупреждение о том, что элемент (пока) не существует при первом обращении к нему, когда вы читаете "lastUpdate". Позже, когда вы устанавливаете элемент "flag", вы создаете элемент массива.

Чтобы упростить чтение условий цикла и предотвратить опечатки, подобные этой, вы можете использовать цикл foreach:

foreach ($customerList as $customer) {
    $date1 = date_create(customer["lastUpdate"]);
    $interval = date_diff($date1, $date2);
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...