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

发布于 2024-08-11 07:52:03 字数 1808 浏览 8 评论 0原文

我对最大 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);
    }
}

I'm using a single image upload/crop/resize script for files up to 10MB.

When testing, I set php_ini memory limit to 25M and that is exhausted when uploading a file only about 1.4MB.

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

This seems strange to me, isn't 10368 < 26214400? (Rhetorical Question)

Or does that mean I went 10368 bytes over 25MB? Should my script be using this much memory?

Code:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

≈。彩虹 2024-08-18 07:52:03

除了已经说过的内容之外:

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

In addition to what has been said already:

Never forget that processing compressed file formats (like JPEG) needs much more memory than the actual file size. A 3000 x 3000 Pixel JPG file can weigh only 500kb, but will require (roughly) 3000 x 3000 x 3 (One byte each for Red, Green, and Blue, and depending on mode even one more for Alpha) = at least 27 MB.

み青杉依旧 2024-08-18 07:52:03

错误消息表明它尝试分配另外 10368 字节,但不可用。换句话说,您的 25MB 池已耗尽,脚本无法分配所需的 10368 字节。

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

memory_limit = 64M

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

这是一个相关问题,其中对内存大小进行了一些很好的讨论水池。

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

The error message says that it tried to allocate another 10368 bytes, but it wasn't available. In other words, your 25MB pool was exhausted and the script couldn't allocate the 10368 bytes it needed.

You can increase this limit in your php.ini file, by adding or updating a line similar to the following:

memory_limit = 64M

As far as "if 25MB is enough," that is a difficult question for us to answer... There are certainly some scripts out there that legitimately need 64MB or even more. If you find that you have to constantly increase the size of your memory pool, I'd start looking into what's taking so much space.

Here is a related question that has some good discussion on the size of your memory pool.

EDIT Seeing your code posted, it is definitely possible to consume a large amount of memory when you are working with images. You can help your script by calling imagedestroy after you are done with an image resource.

红焚 2024-08-18 07:52:03

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

Use imagedestroy to free the memory after usage:

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);
}
对你而言 2024-08-18 07:52:03

或者这是否意味着我在 25MB 上占用了 10368 字节?

否。您的脚本尝试分配 10368 字节,10368 + 已分配 > 25MB

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

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

Or does that mean I went 10368 bytes over 25MB?

No. Your script was trying to allocate 10368 bytes, 10368 + alreadyallocated > 25MB

Should my script be using this much memory?

If you're using GD for resizing, yes. I'd try to use other libs or console tools for image processing, they can give more perfomance. And, you can decide to use a queue for image processing and not resize images just-in-time, if it's public website

风流物 2024-08-18 07:52:03

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

That means that at the moment when you exceeded the limit, your script was trying to allocate 10368 bytes but it didn't succeed. That doesn't mean that you won't have this problem anymore if you increase the limit to 26MB. The error might occur at some later point. You might try to increase it in smaller steps (e.g. 32MB, 48MB, etc.) until you don't get this error anymore.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文