Límite de memoria PHP de 25 MB agotado – Carga de archivos / recorte / cambio de tamaño

Estoy usando un script de carga / recorte / cambio de tamaño de una sola imagen para archivos de hasta 10MB.

Al probar, establezco el límite de memoria de php_ini en 25M y se agota al cargar un archivo de solo 1,4 MB.

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

Esto me parece extraño, ¿no es 10368 <26214400? (Pregunta retórica)

¿O eso significa que fui 10368 bytes más de 25 MB? ¿Debería mi script usar esta cantidad de memoria?

Código:

 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); } } 

El mensaje de error dice que intentó asignar otros 10368 bytes, pero no estaba disponible. En otras palabras, su grupo de 25MB estaba agotado y el script no podía asignar los 10368 bytes que necesitaba.

Puede boost este límite en su archivo php.ini agregando o actualizando una línea similar a la siguiente:

 memory_limit = 64M 

En cuanto a “si 25 MB es suficiente”, esa es una pregunta difícil de responder … Sin duda hay algunos guiones que legítimamente necesitan 64 MB o incluso más. Si encuentra que tiene que boost constantemente el tamaño de su conjunto de memoria, empezaría a investigar qué es lo que ocupa tanto espacio.

Aquí hay una pregunta relacionada que tiene una buena discusión sobre el tamaño de su grupo de memoria.

EDITAR Al ver su código publicado, definitivamente es posible consumir una gran cantidad de memoria cuando trabaja con imágenes. Puede ayudar a su secuencia de comandos llamando a imagedestroy después de que haya terminado con un recurso de imagen.

Además de lo que ya se ha dicho:

Nunca olvide que el procesamiento de formatos de archivos comprimidos (como JPEG) necesita mucha más memoria que el tamaño real del archivo. Un archivo JPG de 3000 x 3000 píxeles puede pesar solo 500 kb, pero requerirá (aproximadamente) 3000 x 3000 x 3 (un byte cada uno para rojo, verde y azul, y según el modo, uno más para Alpha) = al menos 27 MB .

Use imagedestroy para liberar la memoria después del uso:

 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); } 

¿O eso significa que fui 10368 bytes más de 25 MB?

No. Su script estaba tratando de asignar 10368 bytes, 10368 + ya asignados> 25MB

¿Debería mi script usar esta cantidad de memoria?

Si está usando GD para cambiar el tamaño, sí. Trataría de usar otras librerías o herramientas de consola para el procesamiento de imágenes, pueden dar más rendimiento. Y, puede decidir utilizar una cola para el procesamiento de imágenes y no cambiar el tamaño de las imágenes justo a tiempo, si es un sitio web público

Eso significa que en el momento en que excedió el límite, su secuencia de comandos intentaba asignar 10368 bytes pero no tuvo éxito. Eso no significa que ya no tendrá este problema si aumenta el límite a 26 MB. El error puede ocurrir en algún momento posterior. Puede intentar boostlo en pasos más pequeños (por ejemplo, 32 MB, 48 MB, etc.) hasta que ya no tenga este error.