很多人在配置PHP网站时都会遇到三个参数:memory_limit、upload_max_filesize和post_max_size。
它们经常同时出现在文件上传问题的排查过程中,所以很容易被理解成三个不同大小的文件限制。实际上,它们负责的事情完全不同。
最简单的理解方式是:upload_max_filesize限制单个上传文件有多大,post_max_size限制整个POST请求可以有多大,而memory_limit限制一个PHP脚本运行过程中最多可以使用多少内存。
三者相互有关,但并不是简单的大小排序关系。
upload_max_filesize限制单个文件
upload_max_filesize的含义最直接:它规定PHP允许上传的单个文件最大尺寸。
例如:
upload_max_filesize = 20M
通常可以理解为单个上传文件不能超过20MB。
如果一个表单同时上传三个文件,那么这个参数分别作用于每个文件,而不是把三个文件加起来以后再与20MB比较。
PHP官方文档明确将它定义为上传文件的最大尺寸,同时指出,post_max_size必须大于这个值。
因此,如果网站允许用户上传20MB的图片或者视频文件,不能只修改upload_max_filesize,还需要检查post_max_size。
post_max_size限制整个POST请求
post_max_size的概念比upload_max_filesize更大。
它限制的是一次POST请求的数据总量,而文件上传通常就是通过POST请求发送的。
例如,一个表单上传一个20MB的文件,同时还包含其他表单字段,那么整个HTTP请求的大小不只是20MB。
因此,如果设置:
upload_max_filesize = 20M
那么:
post_max_size = 20M
实际上并不是一个理想配置。
PHP官方文档明确指出,上传大文件时,post_max_size必须大于upload_max_filesize。如果POST数据超过post_max_size,PHP甚至可能不会正常填充$_POST和$_FILES。
所以实际配置通常会给post_max_size留出一定余量。
例如:
upload_max_filesize = 20M
post_max_size = 25M
或者:
upload_max_filesize = 20M
post_max_size = 30M
具体需要留多少空间,要根据网站实际的表单结构和上传需求决定,而不是机械套用某个固定倍数。
memory_limit到底限制什么
memory_limit与前两个参数最大的区别,是它限制的不是上传文件大小,而是PHP脚本运行过程中可以分配的内存。
例如:
memory_limit = 256M
意思是PHP脚本最多可以分配大约256MB的内存。
PHP官方文档将memory_limit定义为脚本能够分配的最大内存量,它的主要作用之一就是防止某个PHP脚本占用过多服务器内存。
因此,不应该简单理解成:
上传20MB文件,就必须有20MB的memory_limit。
实际情况没有这么简单。
一个20MB的图片文件,如果程序只是把文件从临时目录移动到最终存储位置,内存需求可能并不高。
但如果PHP程序把图片读取到内存,然后进行解码、缩放、旋转、重新编码,那么实际内存消耗可能远远高于文件本身的20MB。
这也是为什么处理图片、PDF、视频或者大型数据文件时,程序的内存消耗不能只看文件大小。
三个参数是怎样互相影响的
假设网站需要允许用户上传一个20MB的文件。
可以考虑这样的配置:
upload_max_filesize = 20M
post_max_size = 25M
memory_limit = 256M
这里三个数字分别代表三个不同的概念。
20M代表单个文件允许达到的最大尺寸。
25M代表整个POST请求允许达到的最大尺寸。
256M代表PHP脚本运行时可以使用的内存上限。
它们不是20M、25M、256M三个不同层级的上传限制。
尤其不要把它们理解成:
memory_limit越大,就能上传越大的文件。
这并不成立。
如果:
upload_max_filesize = 20M
即使把:
memory_limit = 1G
PHP也不会因此允许用户上传100MB文件。
反过来,如果:
upload_max_filesize = 100M
但:
post_max_size = 50M
那么100MB文件仍然无法通过正常的POST上传。
为什么通常建议memory_limit高于post_max_size
PHP官方文档指出,一般情况下,memory_limit应该高于post_max_size。
但这并不意味着两者必须按照某个固定比例配置。
例如:
memory_limit = 256M
post_max_size = 50M
是一个完全可能的配置。
至于是否需要把memory_limit提高到512M甚至更高,则取决于PHP程序本身。
如果网站只是上传普通图片,然后把文件保存到服务器,256M可能已经足够。
如果程序还需要处理大型图片、生成缩略图、解析复杂文件或者执行大量数据处理,那么内存需求可能明显增加。
因此,memory_limit应该根据程序实际的内存使用情况调整,而不是根据上传文件大小机械计算。
为什么修改upload_max_filesize以后还是上传不了
这是网站管理员最常遇到的问题之一。
例如管理员把:
upload_max_filesize = 50M
修改好了,但上传50MB文件仍然失败。
这时候首先应该检查:
post_max_size
如果仍然只有8M,那么整个POST请求仍然超过限制,上传当然无法正常完成。
PHP当前文档列出的默认值中,upload_max_filesize为2M,而post_max_size为8M,但实际服务器环境可能使用不同的配置,因此不能根据默认值判断自己的服务器。
还需要检查memory_limit、max_input_time以及服务器本身的上传限制。
PHP官方的文件上传文档也特别提醒,大文件上传除了upload_max_filesize和post_max_size之外,max_input_time也可能影响上传时间。如果用户网络较慢或者上传文件较大,接收请求所需要的时间可能超过该限制。
不要只修改php.ini而不检查实际配置
修改配置文件以后,最重要的一步不是认为自己已经改好了,而是确认PHP实际使用的配置。
可以使用phpinfo()查看当前PHP环境中的配置,也可以使用ini_get()读取特定配置值。PHP官方文档说明,ini_get()可以返回当前配置项的实际值。
例如可以检查:
ini_get('memory_limit')
ini_get('upload_max_filesize')
ini_get('post_max_size')
这样就能知道当前运行环境到底使用了什么值。
这一点对于共享主机尤其重要,因为服务器上的PHP配置不一定完全由网站管理员控制。
有时候你修改了一个php.ini文件,但网站实际运行的PHP并没有加载这个文件,于是网页上的配置仍然没有发生变化。
因此,确认实际生效值比修改配置文件本身更加重要。
为什么不建议用ini_set解决上传大小
ini_set()可以在PHP脚本运行期间修改部分配置,但并不是所有PHP配置都能够通过它修改,而且对于文件上传,修改时机也非常重要。
PHP官方文档特别指出,像upload_max_filesize这样的设置如果在脚本执行时才修改,上传文件实际上已经经过PHP的上传处理,因此修改可能已经太晚。post_max_size也存在类似问题。
所以,如果网站需要调整上传限制,更合适的做法通常是修改服务器实际使用的PHP配置,并确认配置已经生效,而不是在处理上传的PHP脚本里面临时修改。
一个实用的配置思路
假设一个网站需要上传最大20MB的图片或文件,可以从下面这种配置开始:
upload_max_filesize = 20M
post_max_size = 25M
memory_limit = 256M
如果实际测试发现图片处理过程中出现内存不足,再根据程序的实际需求提高memory_limit。
如果需要允许上传更大的文件,则首先调整upload_max_filesize和post_max_size,然后检查程序处理这些文件时的内存和执行时间。
对于非常大的文件,还应该考虑是否真的适合通过普通PHP POST请求上传。有些应用会采用分块上传、对象存储或者专门的上传服务,从架构层面解决大文件传输问题,而不是单纯把PHP的几个限制不断调大。
三个参数其实可以这样记
upload_max_filesize问的是:
一个文件最大允许多大?
post_max_size问的是:
一次POST请求最大允许多大?
memory_limit问的是:
这个PHP脚本运行时最多允许使用多少内存?
把这三个问题分开以后,很多PHP上传问题就容易理解了。
如果上传文件超过upload_max_filesize,需要检查单文件限制。
如果整个请求超过post_max_size,需要检查POST请求限制。
如果程序在处理文件的过程中出现内存不足,则需要分析PHP程序实际使用的内存,再考虑memory_limit。
因此,这三个参数虽然经常一起出现,却并不是三个互相竞争的数字。真正合理的PHP配置,也不是简单把所有限制调得越大越好,而是根据网站实际业务、文件大小、程序内存消耗和服务器资源进行配置。
对于普通网站管理员来说,记住一个原则就足够了:先弄清楚到底是哪一种限制触发了问题,再修改对应参数,而不是看到上传失败就把所有数值一起调大。
php.ini 里的 memory_limit、upload_max_filesize 和 post_max_size 怎么理解
喜欢这篇报道?
使用下面的功能,方便以后继续阅读和分享 MNewsTV
关于文章收藏
收藏不需要注册帐号,收藏信息仅保存在当前浏览器中。
删除收藏请进入「我的收藏」进行管理。
分享 Facebook | X | WhatsApp | LinkedIn
捐助(Paypal): https://www.paypal.me/observeccp 订阅中国观察电报 Telegram : https://t.me/s/ObserveCCP