防止 GD 图像库内存不足的故障安全方法? (PHP)
有没有办法防止 PHP GD 图像库 内存不足? 如果上传的图像太大,GD 往往会耗尽内存,从而终止脚本。 我希望它抛出一个可捕获的异常或类似的东西,但可惜它没有。
现在我正在使用一个拼凑在一起的脚本,它首先发出一个 ini_set('memory_limit', '128M')
,如果有效的话我通常就准备好了。 根据服务器配置,尽管这可能是不可能的,所以我依靠一种算法来尝试估计所需的内存量(考虑分辨率、颜色深度、通道和模糊因素),然后将其与memory_get_usage()
如果该函数存在,否则进行粗略估计。
到目前为止,整个事情都是有效的,但它远非优雅,并且在某些边缘情况下会失败,我确信。 有没有更好的方法来做到这一点,即让 GD 在必要时优雅地失败,而不是让一切都陷入停顿?
Is there a way to prevent the PHP GD image library from running out of memory? If too large an image is uploaded, GD tends to run out of memory, terminating the script. I'd like it to throw a catchable exception or something to that extend, but alas it doesn't.
Right now I'm using a cobbled-together script that first issues an ini_set('memory_limit', '128M')
, if that works I'm usually all set. Depending on the server configuration though that may not be possible, so I'm falling back on an algorithm that tries to estimate the amount of memory needed (taking resolution, color depth, channels and a fudge factor into account), then compares it to memory_get_usage()
if the function exists, otherwise does a rough estimate.
The whole thing works so far, but it's far from elegant and will fail in some edge cases, I'm sure. Is there any better way to do this, i.e. have GD fail gracefully if it has to, instead of grinding everything to a halt?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
多买点内存吧! :-P
说真的,内存不足是不可能处理的,因为你采取的任何操作都需要更多的内存。
最好的办法是根据当前内存设置限制上传图像的大小。
Buy more memory! :-P
Seriously though, it is impossible to handle being out of memory because any action you take would require more memory.
Your best bet is to limit the size of image being uploaded based on the current memory settings.
创建图像后。
将消除内存问题
After you create an image.
will remove the memory problem
还有另一种方法可以做到这一点,但它可能很耗时,因为图像编辑过程的某些部分会重复多次,但您可以将内存限制设置为您的估计值,然后尝试处理图像,如果失败,则捕获异常,增加内存限制,然后再次处理图像 - 重复此操作,直到成功或达到某个内存限制 - 此时您会向用户抛出一条错误消息,解释他们的图像太大要使用的。
编辑:要捕获内存不足错误,您可以使用以下解决方案:https://www.php.net/set_error_handler#35622" php.net/set_error_handler#35622
There is another way to do it, but it can be time consuming, as certain parts of the image editing process would be repeated a number of times, but you can set the memory limit to your estimated value, then try to process the image, if it fails catch the exception, increase the memory limit, then process the image again - repeating this until you succeed or reach a certain memory limit - at which point you'd throw an error message to the user explaining that their image is too big to be used.
Edit: To catch the out-of-memory error, you could use this solution: https://www.php.net/set_error_handler#35622
要捕获 PHP 的致命错误,例如“内存不足”或“PHP 致命错误:允许的内存大小为 8388608 字节耗尽(试图分配 … 字节)”,请参见此处: http://php.net/manual/en/function.set-error-handler.php#88401
To catch PHP's fatal errors, like "Out of memory" or "PHP Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate … bytes) in", see here : http://php.net/manual/en/function.set-error-handler.php#88401
做一些测试来检查每个 gd 函数需要多少内存。
imagecreatetruecolor
似乎需要width*height*5 字节
。imagepng
似乎需要width*height*4 字节
。Do some tests to check how much memory each
gd
function need.imagecreatetruecolor
seems to needwidth*height*5 bytes
.imagepng
seems to needwidth*height*4 bytes
.最好的办法是停止尝试计算需要多少 RAM,而从一开始就将其最大化 - 如果您有 4 GB 可用内存,请告诉映像脚本使用 2 到 4 GB 左右的内存,并且当脚本结束后,让它恢复正常,这将掩盖所有潜在的致命情况。 无论如何,这是我能想到的唯一“万无一失”的方法......
Your best bet is to stop trying to figure out how much ram it will need, and just max it out at the outset - if you have 4 GB available, tell the image script to use between 2 and 4 GB or so, and when the script ends, have it go back to normal, that will cover off all potentially fatal situations. That's the only "Fail-safe" way I can think of anyway ...