php的memory_limit、upload_max_filesize和post_max_filesize的关系

Posted

技术标签:

【中文标题】php的memory_limit、upload_max_filesize和post_max_filesize的关系【英文标题】:Relationship between php’s memory_limit, upload_max_filesize and post_max_filesize 【发布时间】:2011-07-03 16:10:50 【问题描述】:

底线: 我需要关心设置post_max_filesize >> memory_limit吗?

详情:This answer 建议上传的文件不需要符合 php 的 memory_limit。 php docs 建议整个帖子应该适合 php 的内存限制。

我发现文档令人惊讶,我希望有人能详细说明。例如采取以下 php 配置:

; config A
memory_limit = 50M
upload_max_filesize = 100M
post_max_filesize = 1000M
max_file_uploads = 10    

; config B
memory_limit = 50M
upload_max_filesize = 10M
post_max_filesize = 1000M
max_file_uploads = 100    

通过这些配置,我希望能够:

将 10x100mb 文件上传到服务器 A, 和 100x10mb 文件上传到服务器 B。 我也希望: 处理上传到服务器 A 的 10 个文件中的任何一个都是一个问题(50M 包中的 100Ms 文件......)。 使用上传到服务器 B 的 100 个文件中的任何一个都可以 (10 在尝试使用不那么圆但相关的数字时,我发现这些期望是正确的。

这个经验会让我说“一般来说memory_limit应该大于upload_max_filesize”;相反,php docs 说:

一般来说memory_limit应该大于post_max_size

为什么,如果不是,会发生什么?

当我的 php 代码被执行时,我看不到所有发布的文件都在内存中的证据。在我看来,我所拥有的只是一个 $_FILES 数组,其中包含仅在磁盘上找到的文件的路径。在我能够自省环境之前,php 是否将整个帖子保存在内存中?我需要关心设置post_max_filesize >> memory_limit吗?

旁白: 违反手册的规则不会导致服务器严重损坏(w/php5.3 apache2.2 debian 6)。

【问题讨论】:

我认为该建议源于这样一个事实,即如果您尝试对所有文件进行任何处理(例如存储到变量),那么您将超过 PHP 的内存限制。不过不确定,所以我不会把它作为一个真正的答案。 【参考方案1】:

PHP 将接受单独小于upload_max_filesize 且合计小于post_max_size 字节的上传文件。关于 memory_limit 的 PHP 文档是错误的,它不需要保存发布的文件内容。

以下配置适用于 Apache2 模块和 CGI​​,并接受小于 1G 的文件。

 upload_max_filesize = 1G
 post_max_size = 1G
 memory_limit = 32M

【讨论】:

【参考方案2】:

我需要担心吗 设置 post_max_filesize >> 内存限制?

仅当您计划将整个文件读入内存并且您读入的文件大于您分配给 PHP 的空间(即memory_limit),在这种情况下您将耗尽内存。

【讨论】:

上传的文件不在 POST 系统中的 _FILES 系统中,并且 php 不会在上传时为您提供它们的全部文件内容,您必须阅读它们 因此“仅当您计划将整个文件读入内存时” 这似乎大致支持我的建议,即文件大小而不是帖子大小应该是相关的。您是否愿意承诺文档是错误的,并且帖子大小和内存限制实际上仅与用例和从 /tmp 读取的最大发布文件的大小有关?【参考方案3】:

我个人的经验是,你的 memory_limit 必须高于 post_max_size 和 upload_max_size。

post_max_size 指的是整个 POST 数据。这包括文件本身可能包含的任何表单字段。 upload_max_size 是该上传文件中允许的最大文件大小。

例如。 post_max_size 为 10mb,upload_max_size 为 1mb,你可以上传 9 个文件,每个文件大小为 1mb,为什么是 9 个文件?因为部分 POST 数据是文件元数据 - 文件名、mimetype、文件大小等......这都占用了一些空间,所以你的 9 个文件实际上会占用 9.01 兆字节左右。剩下的 0.99 对另一个文件来说太小了,所以你不能上传第 10 个,即使它符合 upload_max_size 限制。

至于 memory_limit,您不仅需要为上传的文件留出足够的“空间”,还必须记住此限制适用于整个脚本。 10mb 的 memory_limit 将只允许上传 9 兆字节的文件,因为 PHP 本身和所有相关的代码和库已经吸收(比如说)1 兆字节。

即使这些文件没有保存在内存中 - 它们会尽快转储到临时文件中,但它们会通过 STDIN 从 Apache 传递到 PHP。 PHP 必须从该流中读取文件并将它们复制到您在 $_FILES 数组的 ['tmp_name'] 部分中使用的临时文件中。

无论出于何种原因,PHP 似乎基本上都是在执行“file_get_contents()”并批量下载文件,而不是执行流式复制。因此需要超过最大允许文件大小的 memory_limit。

【讨论】:

承认我的设置是在真空情况下有点球形鸡,但这是故意的,以避免对字段大小、上传时间等的切线讨论。你能提供更多关于 php 行为的细节并解释我怎么有一个与你的断言明显矛盾的工作系统?

以上是关于php的memory_limit、upload_max_filesize和post_max_filesize的关系的主要内容,如果未能解决你的问题,请参考以下文章

PHP修改memory_limit的三种办法

MacOS Laravel Valet 增加 memory_limit

php书写不规范Notice: Use of undefined constant memory_limit

Kubernetes部署php 应用时候memory_limit的修改

PHP:在不改变 memory_limit 和 max_execution_time 的情况下读取和导出大数据

php的memory_limit、upload_max_filesize和post_max_filesize的关系