2009-11-14 91 views
1

我使用单个图像上传/裁剪/调整大小脚本文件高达10MB。PHP内存限制25MB用尽 - 文件上传/裁剪/调整大小

测试时,我将php_ini内存限制设置为25M,上传文件时仅用了1.4MB左右。

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

这对我来说很奇怪,是不是10368 < 26214400? (修辞问题)

或者这是否意味着我超过25MB 10368字节?我的脚本应该使用这么多的内存吗?

代码:

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 2009-11-14 18:12:38

+0

感谢您的参与,代码已发布 – 2009-11-14 18:20:08

+0

真的很难确定最佳答案,总体而言,您都回答了我正在寻找的内容。谢谢!! – 2009-11-14 18:36:55

回答

4

该错误消息说,它试图分配另一个字节10368,但它是不可用。换句话说,你的25MB池已经耗尽,脚本无法分配它需要的10368字节。

您可以增加此限制在php.ini文件中,通过添加或更新类似于下面的一行:

memory_limit = 64M 

至于“如果25MB的是不够的,”这对我们来说是一个很难回答的问题答案......肯定有一些脚本需要64MB甚至更多。如果你发现你必须不断增加你的记忆池的大小,我会开始考虑需要这么多空间的东西。

Here is a related question这对你的内存池的大小有一些很好的讨论。

编辑看到您的代码发布后,当您使用图像时肯定会消耗大量内存。完成图像资源后,您可以通过拨打imagedestroy来帮助您的脚本。

1

这意味着,当你超出限制时,你的脚本试图分配10368字节,但它没有成功。这并不意味着如果你将限制增加到26MB,你就不会再有这个问题了。该错误可能稍后发生。您可以尝试以较小的步骤增加它(例如32MB,48MB等),直到您不再遇到此错误。

2

或者这是否意味着我超过了25MB的10368字节?

号你的脚本试图分配10368个字节,10368 + alreadyallocated> 25MB

如果我的脚本是用这么多内存?

如果您使用GD进行调整大小,是的。我会尝试使用其他库或控制台工具进行图像处理,它们可以提供更多的性能。而且,您可以决定使用队列进行图像处理,而不是将图像尺寸调整刚刚在时间,如果它是公共网站

+0

我会研究一下,谢谢 – 2009-11-14 18:33:16

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); 谢谢! – 2009-11-14 18:30:53

+0

@Paul Silvis:谢谢。幸运的是,当我实际输入'image_destroy'时,PHP.net显示了正确的功能。 – Gumbo 2009-11-14 18:35:21

14

除了什么已经说过:

永远不要忘记,处理压缩文件格式(如JPEG)需要比实际文件大小更多的内存。一个3000 x 3000像素的JPG文件可以仅重500kb,但需要(大致)3000 x 3000 x 3(红,绿和蓝各一个字节,根据模式,甚至还有一个用于Alpha)=至少27 MB 。

+0

谢谢,这确实将估算“可接受”的效率带入了重点。 – 2009-11-14 18:29:28

+0

+1我打赌通过调试器运行他的代码,他会在'$ imgcreatefrom($ updir。$ img);'(如果该行尚未显示部分错误消息指示他没有粘贴)。 – timdev 2009-11-15 04:18:34