Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Для профи > Allowed memory size of XXX bytes exhausted


Автор: Alex13 1.7.2008, 12:45
Собственно, интересует возможность обработки этой ошибки.
Есть такой код:
Код

        $wh = getimagesize($file);
        $this->width = $wh[0];
        $this->height = $wh[1] + 25;
        
    try {
        $this->img = imagecreatetruecolor($wh[0], $wh[1]+25);
    }
    catch (Exception $e)
    {
        return false;
    }
        if(!$this->img)
            return false;

При этом ри работе с большими картинками частенько не хватает памяти и выбрасывается исключение типа
Код

Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 6400 bytes) in /***/includes/functions_watermark.php on line 32 (32 строка - это вызов imagecreatetruecolor())

Проблема в том, что блок try-catch не срабатывает должным образом. Можно ли как-то по-другому перехватить это исключение или хотябы спрогнозировать его и отказаться от выполнения дальнейшего кода?

Автор: IZ@TOP 1.7.2008, 13:07
Alex13, посчитайте, каких максимальных размеров, при выделенном объеме памяти, могут быть обрабатываемые изображения и ограничьте загрузку до этого размера. Или наоборот, увеличьте размер памяти выделяемый для PHP.

Автор: skyboy 1.7.2008, 13:09
Цитата(Alex13 @  1.7.2008,  11:45 Найти цитируемый пост)
 блок try-catch 

относится к исключениям. исключениям, которые должны генерироваться кодом. fatal error генерирует не функция imagecreatetruecolor, а ядром РНР.
Цитата(Alex13 @  1.7.2008,  11:45 Найти цитируемый пост)
Можно ли как-то по-другому перехватить это исключение

єто не исключение.
Цитата(Alex13 @  1.7.2008,  11:45 Найти цитируемый пост)
или хотябы спрогнозировать его и отказаться от выполнения дальнейшего кода?

навряд ли. http://php.net/set_error_handler не распространяется на ошибки уровня ядра(всякие там fatal, compile и parse)

Добавлено через 2 минуты и 10 секунд
IZ@TOP, обрати внимание: он пытается выделить 6400 байт, всего лишь. так что там особо рассчитывать нечего. просто память забита(а лимит - аж 16 Мб). 

Автор: d06osipov 1.7.2008, 16:20
Измените memory_limit в PHP.ini --- если его сделать достаточно большим ошибки не будет. А ещё вариант --- просто проверяйте размер картинки. Если он больше половины доступной памяти, выдавайте ошибку (если одновременно грузится в память не более одной картинки). Может, есть способ узначть количество задействованной памяти.

Автор: Sannis 1.7.2008, 17:29
Цитата(d06osipov @  1.7.2008,  16:20 Найти цитируемый пост)
А ещё вариант --- просто проверяйте размер картинки. Если он больше половины доступной памяти, выдавайте ошибку
Если вы пользуетесь таким способом, не забудьте учесть сжатие. кроме того GD значительно больше требует памяти, чем это показывают рассчёты :(

Автор: IZ@TOP 2.7.2008, 11:32
skyboy, как знать, куда у него память делась. Я бы порекомендовал ограничить размер изображений, или посоветовал использовать сторонние библиотеки для обработки изображений (к примеру, отличным решением для того же Watermark был бы ImageMagic).

Автор: MuToGeN 11.7.2008, 04:26
Спрогнозировать можно по формуле x * y * 4. Полностью оно выглядит как mem_size = x * y * bytes_per_pixel * (1 + c1) + c2, где bytes_per_pixel = 4 для большинства версий GD, c1 и c2 подбираются опытным путем, но в большинстве случаев ничтожно малы.

Насчет перехвата фатальных ошибок был какой-то механизм, основанный на недокументированных фичах буферизации вывода.

Автор: sTa1kEr 12.7.2008, 02:44
Цитата(MuToGeN @  11.7.2008,  05:26 Найти цитируемый пост)
Насчет перехвата фатальных ошибок был какой-то механизм, основанный на недокументированных фичах буферизации вывода. 

Да, у Котерова есть статья и библиотечка для этого. http://dklab.ru/chicken/nablas/45.html Вот только это очень не надежный метод, особено при не хватке памяти (для обработчика фатальных ошибок тоже память нужна). Имхо, он больше подходит для отладки, что бы выводить фатальные ошибки с бэктрейсом и дополнительной информацией в удобочитаемом виде. А на продакшене лучше настроить apache с собственным html для 500-ой ошибки.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)