PHP内存限制25MB耗尽 - 文件上载/裁剪/调整大小

时间:2009-11-14 18:09:39

标签: php upload resize crop memory-limit

我正在使用单个图片上传/裁剪/调整大小脚本来处理最大10MB的文件。

测试时,我将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);
    }
}

5 个答案:

答案 0 :(得分:14)

除了已经说过的话:

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

答案 1 :(得分:4)

错误消息说它试图分配另一个10368字节,但它不可用。换句话说,您的25MB池已用完,脚本无法分配所需的10368个字节。

您可以在php.ini文件中增加此限制,方法是添加或更新类似于以下内容的行:

memory_limit = 64M

至于“如果25MB足够”,这对我们来说是一个难以回答的问题......当然有一些合法需要64MB甚至更多的脚本。如果您发现必须不断增加内存池的大小,我会开始研究占用这么多空间的内容。

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

编辑看到您发布的代码,在处理图片时绝对有可能消耗大量内存。完成图像资源后,您可以通过调用imagedestroy来帮助您编写脚本。

答案 2 :(得分:2)

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

没有。您的脚本正在尝试分配10368个字节,10368 +已分配> 25MB

我的脚本应该使用这么多内存吗?

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

答案 3 :(得分: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);
}

答案 4 :(得分:1)

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