Array и timestamp.  Allowed memory size of N bytes exhausted

Array и timestamp. Allowed memory size of N bytes exhausted

Сегодня случилось странное. Один из методов объекта заказы стал падать с ошибкой:

 Fatal error: Allowed memory size of 134217728 bytes exhausted  (tried to allocate 1620896713 bytes)

Что по русски звучит как:

Фатальная ошибка: Допустимый объем памяти 134217728 байт (128 МБ) исчерпан (попытался выделить 1620896713 байт (1,51 ГБ !) )

Метод выглядел следующим образом:

    public function addSate(OrderStates $new_state)
    {
        $this->_fields['status']["".strtotime('now')] = $new_state->id;
        $this->_fields['curStatus'] = $new_state;
    }

Фатальная ошибка возникала в строке 3.
Не понятно, как этой строчке могло понядобиться 1,5 ГБ памяти. Так же, стоит сказать, что данный метод достался системе в наследство от предыдущей версии и все работало прекрасно, ровно до сегодняшнего дня.

Покопавшись несколько часов в коде, я, наконец то, обратил внимание на необычный размер памяти, которую пытался выделить себе PHP. Это и было решением!

PHP конвертировал результат этой операции "".strtotime('now') обратно в int, при создании ключа массива! В итоге, для этого нового массива ему становилось нужно 1620896713 байт памяти, что в точности соответствовало текущему unixtime.
Мне не удалсь понять, как до сегодняшеного дня это не глючило, заменив такой ключ ключем строковым (например "d".strtotime('now') или date('d/m/Y')) удалось избавиться от этой ошибки.

В итоге метод теперь выглядит так:

    public function addSate(OrderStates $new_state)
    {
        $this->_fields['status'][date('d.m.Y i:s')] = $new_state->id;
        $this->_fields['curStatus'] = $new_state;
    }

Все работает прекрасно. Правда, пришлось привести БД в соответствие и переписать пару шаблонов интерфейса, но это было гораздо проще ?

Теги: PHP

Комментарии ()