2009-11-14 4 views
1

Я использую сценарий загрузки изображений/обрезки/изменения размера для файлов размером до 10 МБ.Ограничение памяти PHP 25MB Исчеркнуто - загрузка файла/обрезка/изменение размера

При тестировании я устанавливаю предел памяти php_ini в 25M, и он исчерпан при загрузке файла только около 1,4 МБ.

"Allowed memory size of 26214400 bytes exhausted (tried to allocate 10368 bytes)" 

Это мне кажется странным, не 10368 < 26214400? (Риторический вопрос)

Или это означает, что я пошел 10368 байт за 25 МБ? Должен ли мой скрипт использовать эту большую память?

Код:

function make_thumbnails($updir, $img) 
{ 
    $thumbnail_width = 200; 
    $thumbnail_height = 150; 
    $thumb_preword = "thumb_"; 

    $arr_image_details = GetImageSize($updir.$img); 
    $original_width = $arr_image_details[0]; 
    $original_height = $arr_image_details[1]; 

    if($original_width > $original_height){ 
     $new_width = $thumbnail_width; 
     $new_height = intval($original_height*$new_width/$original_width); 
    } else { 
     $new_height = $thumbnail_height; 
     $new_width = intval($original_width*$new_height/$original_height); 
    } 

    $dest_x = intval(($thumbnail_width - $new_width)/2); 
    $dest_y = intval(($thumbnail_height - $new_height)/2); 

    if($arr_image_details[2]==1) { $imgt = "ImageGIF"; $imgcreatefrom = "ImageCreateFromGIF"; } 
    if($arr_image_details[2]==2) { $imgt = "ImageJPEG"; $imgcreatefrom = "ImageCreateFromJPEG"; } 
    if($arr_image_details[2]==3) { $imgt = "ImagePNG"; $imgcreatefrom = "ImageCreateFromPNG"; } 

    if($imgt) 
    { 
     $old_image = $imgcreatefrom($updir.$img); 
     $new_image = imagecreatetruecolor($thumbnail_width, $thumbnail_height); 
     imageCopyResized($new_image,$old_image,$dest_x, 
     $dest_y,0,0,$new_width,$new_height,$original_width,$original_height); 
     $imgt($new_image,$updir.$thumb_preword.$img); 

     // Added by your suggestions: 
     imagedestroy($old_image); 
     imagedestroy($new_image); 
    } 
} 
+1

Вы только что достигли предела памяти, пытаясь выделить еще 10368 байт. Пожалуйста, покажите нам какой-то код, чтобы мы могли вам помочь. – Gumbo

+0

Спасибо за ваш ввод, код отправлен –

+0

Действительно сложно решить лучший ответ, в совокупности вы все ответили именно на то, что я искал. Благодаря!! –

ответ

4

сообщение об ошибке говорит, что он пытался выделить еще 10368 байт, но он не был доступен. Другими словами, ваш пул из 25 МБ был исчерпан, и скрипт не смог выделить 10368 байт, в которых он нуждался.

Вы можете увеличить этот лимит в файле php.ini, путем добавления или обновления строки, аналогичный следующему:

memory_limit = 64M 

Насколько «если 25MB достаточно,» это сложный вопрос для нас ответ ... Конечно, есть некоторые сценарии, которые на законных основаниях нуждаются в 64 МБ или даже больше. Если вы обнаружите, что вам нужно постоянно увеличивать размер пула памяти, я бы начал изучать то, что занимает столько места.

Here is a related question, который имеет хорошее обсуждение размера вашего пула памяти.

EDIT Увидев ваш код, вы можете использовать большой объем памяти при работе с изображениями. Вы можете помочь своему скрипту, вызвав imagedestroy после того, как вы закончите работу с ресурсом изображения.

1

Это означает, что в тот момент, когда вы превысили лимит, ваш скрипт пытался выделить 10368 байт, но это не удалось. Это не означает, что у вас больше не будет этой проблемы, если вы увеличите предел до 26 МБ. Ошибка может возникнуть в некоторой более поздней точке. Вы можете попытаться увеличить его на более мелкие шаги (например, 32 МБ, 48 МБ и т. Д.), Пока вы больше не получите эту ошибку.

2

Или это означает, что я пошел 10368 байт за 25 МБ?

Нет. Ваш скрипт пытается выделить 10368 байт, 10368 + alreadyallocated> 25MB

Если мой сценарий использовать это много памяти?

Если вы используете GD для изменения размера, да. Я бы попытался использовать другие библиотеки или консольные инструменты для обработки изображений, они могут дать больше возможностей. И, вы можете решить, использовать очереди для обработки изображений, а не изменять размер изображения только по времени, если это общедоступный веб-сайт

+0

Я рассмотрю это, спасибо –

2

Используйте imagedestroy, чтобы освободить память после использования:

if($imgt) 
{ 
    $old_image = $imgcreatefrom($updir.$img); 
    $new_image = imagecreatetruecolor($thumbnail_width, $thumbnail_height); 
    imageCopyResized($new_image,$old_image,$dest_x, 
    $dest_y,0,0,$new_width,$new_height,$original_width,$original_height); 
    imagedestroy($old_image); 
    $imgt($new_image,$updir.$thumb_preword.$img); 
    imagedestroy($new_image); 
} 
+0

Сладкий, это привело к уменьшению использования моей памяти. Я должен отметить для других этот вопрос, правильный синтаксис imagedestroy ($ new_image); Спасибо! –

+0

@Paul Silvis: Спасибо. К счастью, PHP.net показал правильную функцию, поскольку я фактически ввел 'image_destroy'. – Gumbo

14

В дополнение к тому, уже было сказано:

Не забывайте, что обработка сжатых форматов файлов (например, JPEG) требует гораздо большей памяти, чем фактический размер файла.Файл размером 3000 x 3000 пикселей в формате JPG может весить всего 500 кбайт, но потребуется (примерно) 3000 x 3000 x 3 (по одному байту для красного, зеленого и синего цветов и в зависимости от режима еще один для Alpha) = не менее 27 МБ ,

+0

Спасибо, это действительно приносит оценку «приемлемой» эффективности в фокус. –

+0

+1 Я поставил, проверил свой код через отладчик, он заработает в '$ imgcreatefrom ($ updir. $ Img);' (если эта строка еще не указана частью сообщения об ошибке, он не вставлял). – timdev

Смежные вопросы