摘要:媒体库或插件安装提示文件过大、浏览器出现 HTTP 413,或请求只传到一半时,先分清是 PHP 的 upload_max_filesize / post_max_size,还是 Nginx 的 client_max_body_size。依据 PHP、Nginx 与 WordPress 官方文档整理核对顺序、默认值和配置加载路径。查询日期 2026-11-11。只放官网普通链接(affiliate_later)。

依据:PHP 手册《php.ini 核心指令说明》(upload_max_filesize、post_max_size、memory_limit、file_uploads)、PHP 手册《配置文件》、Nginx 模块 ngx_http_core_module:client_max_body_size、WordPress 开发手册《PHP Optimization》、WordPress 函数 wp_max_upload_size()。查询日期:2026-11-11(北京时间)。只放官网普通链接(affiliate_later: 1)。默认值以这些官方页当前写法为准;主机面板上的点击路径、某云厂商未核对的默认上传上限,本文不写。不构成运维建议,改配置前先备份,改完以你服务器上实际加载的值为准。

后台媒体库上传一张图,或在「安装插件/安装主题」里传一个压缩包,页面提示文件太大、请求返回 HTTP 413,或进度条走到一半就停了。这类问题常常被当成磁盘写满。磁盘空间不足会报 No space left on device,核对应先看 df -h 和 df -i,步骤见云服务器报 No space left:df、inode 与日志/容器占用怎么核对。能正常新建小文件、只是较大的上传失败,更应该先核对体积限制:PHP 允许单个文件和整次 POST 有多大,以及 Nginx 允许请求体有多大。

这和固定链接 404、伪静态循环不是同一类问题,后者见WordPress 伪静态与固定链接:404 循环与 Nginx rewrite 核对。对象存储跨域导致的浏览器预检失败,见本站 CORS 专文。本文只处理上传体积这一层。

1. 先看失败长什么样,再决定先查哪一层

上传请求会先经过 Nginx(或前面的反向代理),再交给 PHP(常见是 PHP-FPM),最后由 WordPress 读取 PHP 当前允许的上限。哪一层先拒绝,提示就不一样。

你看到的现象更可能卡在哪一层接下来先核对什么
浏览器或访问日志里是 413(Request Entity Too Large / Payload Too Large)请求体在进入 PHP 之前就被 Web 服务器拒了Nginx 的 client_max_body_size(若前面还有反代或 CDN,也要看那一层的请求体上限)
WordPress 后台提示超过允许的最大上传大小,或媒体库显示出一个比你文件更小的上限请求已经到了 PHP / WordPressPHP 的 upload_max_filesize、post_max_size,以及 WordPress 用 wp_max_upload_size() 取到的较小值
表单提交后页面像没收到文件,$_FILES / $_POST 是空的,没有明确的 413整次 POST 可能超过了 post_max_sizePHP 手册写明:POST 数据大于 post_max_size 时,$_POST 和 $_FILES 超全局变量为空
小文件能传、大文件不能;服务器上还能新建文件偏体积限制,不像盘满按上面两行继续查,不必先扩容云盘

WordPress 官方《PHP Optimization》在「File Upload Sizes」一节写得很直接:后台上传媒体和其他内容时,WordPress 借助 PHP 处理上传;PHP 会限制单个文件大小,也会限制一次可以交给 PHP 处理的请求大小。这两项需要和服务器超时设置对齐。共享主机上这些值常常在服务器级写死,你未必改得了,或只能改到主机允许的上限。那种情况要问主机服务商,而不是在主题里反复传同一个大文件。

2. 先核对 PHP:upload_max_filesize 和 post_max_size

打开 PHP 手册核心指令 的「文件上传」和「数据处理」两节,先把官方默认值和关系记下来。这些是「未加载 php.ini 时使用的默认值」,开发或生产环境的 php.ini 里可能已经改过,所以只能当作对照,不能当成你这台机器的现值。

指令官方默认可修改范围手册里和上传直接相关的说明
file_uploads"1"(开启)INI_SYSTEM是否允许 HTTP 文件上传
upload_max_filesize"2M"INI_PERDIR上传文件的最大大小;post_max_size 必须大于此值
post_max_size"8M"INI_PERDIR允许的 POST 数据最大大小,此设置也会影响文件上传;要上传大文件,此值必须大于 upload_max_filesize
memory_limit"128M"INI_ALL脚本可分配的最大内存。手册在 post_max_size 条写明:一般来说,memory_limit 应该大于 post_max_size
max_file_uploads20INI_PERDIR允许同时上传的最大文件数;留空的上传字段不计入
WordPress 上传文件过大:upload_max_filesize、post_max_size 与 Nginx client_max_body_size 怎么核对(2026)-有序
PHP 手册「文件上传配置项」:upload_max_filesize 默认 2M,可修改范围为 INI_PERDIR;file_uploads 默认开启,max_file_uploads 默认 20(2026-11-11 截自 php.net 中文手册)
WordPress 上传文件过大:upload_max_filesize、post_max_size 与 Nginx client_max_body_size 怎么核对(2026)-有序
PHP 手册「数据处理配置选项」:post_max_size 默认 8M,可修改范围为 INI_PERDIR(2026-11-11 截自 php.net 中文手册)

两层含义要分开。upload_max_filesize 限制单个文件。post_max_size 限制整次 POST,里面除了文件本身,还有表单字段和 multipart 分隔符。只把前者改到 32M、后者仍是 8M,一个 20M 的插件包仍然进不来。WordPress 开发手册也写了同一条约束:post_max_size 必须大于或等于 upload_max_filesize;超过 post_max_size 的请求,PHP 不会处理。

WordPress 上传文件过大:upload_max_filesize、post_max_size 与 Nginx client_max_body_size 怎么核对(2026)-有序
PHP 手册对 post_max_size 的说明:此设置影响文件上传,必须大于 upload_max_filesize;一般来说 memory_limit 应该更大;POST 超过上限时 $_POST 和 $_FILES 为空;可使用 K、M、G 简写(2026-11-11 截自 php.net 中文手册)

它还提醒:post_max_size 对每一次 PHP 请求都生效,不只是上传。站点如果会提交很大的表单或接口数据,这个值也要单独评估。max_input_time 限制的是 Web 服务器把数据传给 PHP 的时间,常用来限制上传耗时,并且和 max_execution_time 是分开计算的。超时设太短,大文件还在传,请求就被掐掉,看起来也会像「只传到一半」。具体秒数以你服务器当前配置为准,本文不编一个通用推荐值。

upload_max_filesize 和 post_max_size 的可修改范围是 INI_PERDIR,意思是可以在系统级、目录级配置里改,不能在运行中的脚本里用 ini_set() 临时抬上去碰运气。改完还要确认真正处理网站请求的那个 PHP 进程已经重新加载配置,下一节会写怎么确认加载路径。

3. 先确认改到了实际加载的那份 php.ini

PHP 手册《配置文件》写明:配置文件在 PHP 启动时被读取。对服务器模块版本的 PHP,只在 Web 服务器启动时读一次;对 CGI 和 CLI 版本,每次调用都会读。搜索路径按顺序包括:SAPI 指定的位置、PHPRC 环境变量、当前工作目录(CLI)、Web 服务器目录或编译时指定的路径等。如果存在 php-SAPI.ini(例如 php-cli.ini、php-fpm.ini),会用它替代 php.ini。另外还可能扫描 PHP_INI_SCAN_DIR 或编译时指定的目录里的额外 .ini。命令行加 --ini 可以查看加载了哪些文件,php_ini_scanned_files() 也能列出被扫进去的附加文件。

这一段对排障很关键,因为你在 SSH 里运行的 php --ini,用的往往是 CLI 这套 SAPI;网站请求走的常常是 PHP-FPM 或别的 SAPI。两套程序完全可能指向不同的 php.ini。只改了 CLI 那份,后台上传上限不会变。

可以按这个顺序核对:

  1. 在服务器上分别执行网站用的 PHP 二进制和命令行 PHP 的 php --ini(路径以你机器为准),记下「Loaded Configuration File」和「Scan for additional .ini files」那两行。
  2. 若能安全地临时查看网站 SAPI 的配置(例如临时的 phpinfo() 页面,用完立刻删除),对准 Loaded Configuration File,以及页面里 upload_max_filesize、post_max_size、memory_limit 的 Local Value。本地值和主配置不一致时,说明还有 .user.ini、扫描目录里的附加 ini,或其他目录级覆盖。
  3. WordPress 官方也提到,有的环境允许用 .htaccess 或 .user.ini 调整 PHP 配置。PHP 手册里 user_ini.filename 的默认值是 ".user.ini"。能否这样改、能改到多大,以主机说明为准。共享主机经常改不了,或只能到服务商设定的上限。
  4. 改的是 php.ini 或 FPM 池配置时,要让真正处理站点请求的进程重新加载。服务器模块版 PHP 只在 Web 服务器启动时读一次配置;使用 PHP-FPM 时,通常需要重载对应的 PHP-FPM 服务。具体服务名、面板按钮以你的系统为准,本文不编某云厂商控制台的点击路径。只重启 Nginx、不重载 PHP-FPM,PHP 指令可能还是旧值。

核对时把三个数字放在一起看:upload_max_filesize、post_max_size、memory_limit。后两个按官方说明应依次更大。然后回到 WordPress 后台,看媒体库显示的最大上传体积有没有跟着变。

PHP 手册还写明:如果存在 php-SAPI.ini(SAPI 是当前所用的 SAPI 名称,例如 php-cli.ini 或 php-fpm.ini),会用它替代 php.ini。当前 SAPI 可以用 php_sapi_name() 测定。网站和命令行看到的文件名不一致时,先对一下 SAPI 名称,再决定改哪一份。附加的扫描目录文件可用 php --ini 或 php_ini_scanned_files() 列出,避免只改了主配置、却被后面扫进去的 .ini 又覆盖回去。

4. 再核对 Nginx:client_max_body_size,默认 1m

请求还没到 PHP,就可能在 Nginx 被挡下来。Nginx 官方文档 对 client_max_body_size 的说明是:

WordPress 上传文件过大:upload_max_filesize、post_max_size 与 Nginx client_max_body_size 怎么核对(2026)-有序
Nginx 官方文档 client_max_body_size:默认 1m,上下文为 http、server、location;超过则返回 413 Request Entity Too Large;size 设为 0 将关闭这项检查(2026-11-11 截自 nginx.org)
  • 作用:设置客户端请求体的最大允许大小。
  • 默认值:client_max_body_size 1m;
  • 上下文:http、server、location,可以写在这三层里。
  • 超过配置值时,向客户端返回 413 (Request Entity Too Large)。文档特别写了一句:浏览器往往不能正确显示这个错误。
  • 把 size 设为 0 会关闭这项检查。

默认 1m 比 PHP 官方默认的 upload_max_filesize 2M、post_max_size 8M 更小。只改 PHP、不看 Nginx,一个 3MB 的文件仍然可能在入口被 413 掉。反过来,只把 Nginx 放到 64m,PHP 仍是 2M,请求能进 PHP,但单个文件还是过不了 upload_max_filesize。

核对时注意作用范围:

  1. 在生效的 Nginx 配置里搜索 client_max_body_size,看它写在 http、server 还是某个 location。更具体的 location 会覆盖外层。WordPress 的上传入口通常是后台的 admin-ajax.php、异步上传接口或 wp-admin 相关路径,要确认你改的那个块确实覆盖这些请求。
  2. 若站点前面还有一层反向代理、负载均衡或网关,请求体会在最外层先被限制。每一层都可能返回 413。只改源站 Nginx、外层仍是更小的值,浏览器看到的还是 413。
  3. 改完后重载 Nginx,使新配置生效。再用一个略大于旧上限、小于新上限的文件试传。不要一上来就用几百兆的安装包做第一次验证。
  4. 官方允许设为 0 以关闭检查。把检查关掉等于不再在 Nginx 这一层限制请求体,是否合适要按站点自己的风险来评估,本文不给「一律改成 0」的写法。

访问日志或错误日志里如果已经出现 413,优先把这一层看完,再回头改 PHP。否则你会在 php.ini 里改来改去,请求其实从未到达 PHP。

5. WordPress 显示的上限:取两者中较小的那个

PHP 放行之后,WordPress 还要决定后台展示和实际允许的最大上传体积。官方函数 wp_max_upload_size() 的说明是:确定 php.ini 中允许的最大上传大小。源码做了三件事:

  1. 用 ini_get('upload_max_filesize') 取出单个文件上限,并换成字节。
  2. 用 ini_get('post_max_size') 取出 POST 上限,并换成字节。
  3. 通过过滤器 upload_size_limit 返回 min($u_bytes, $p_bytes),也就是两者中较小的那个。
WordPress 上传文件过大:upload_max_filesize、post_max_size 与 Nginx client_max_body_size 怎么核对(2026)-有序
WordPress 开发手册《PHP Optimization》的 File Upload Sizes 一节:后台上传走 PHP;post_max_size 必须大于或等于 upload_max_filesize;超过 post_max_size 的请求 PHP 不会处理;共享主机上这些值常常改不了(2026-11-11 截自 developer.wordpress.org)

所以,后台媒体库或「添加媒体」界面上看到的「最大上传大小」,并不是 WordPress 另外写死的一个官方固定值。它跟随当前 PHP 配置,并且以较小的那一项为准。只抬其中一个指令,另一个更小,界面上的数字不会变。

WordPress 上传文件过大:upload_max_filesize、post_max_size 与 Nginx client_max_body_size 怎么核对(2026)-有序
WordPress 函数 wp_max_upload_size():说明为确定 php.ini 中允许的最大上传大小;源码用 ini_get 读取 upload_max_filesize 和 post_max_size(2026-11-11 截自 developer.wordpress.org)

这个值还会再经过 upload_size_limit 过滤器。主题、插件或多站点配置有可能再把它调低。如果你已经确认 php.ini 里两项都够大,Nginx 也放行,后台显示却仍偏小,就要在站点里查有没有插件或自定义代码挂了这个过滤器,而不能继续无限制地加大 PHP 配置。

WordPress《PHP Optimization》还写了和后台相关的内存项:WP_MEMORY_LIMIT、WP_MAX_MEMORY_LIMIT 可在 wp-config.php 里设置;WordPress 在有权限时会把 PHP 的 memory_limit 提升到这些值,但如果 php.ini 里本身更高,它不会再往下调。文档写明,后端通常更吃内存,媒体上传是其中一个原因。内存不够和「文件过大」不是同一条报错,不过大文件在生成缩略图、解码图片时也会碰到内存上限。改 wp-config.php 解决不了 upload_max_filesize 本身偏小的问题。

6. 改完以后怎么验证,以及不要和盘满搞混

建议按这一条最短路径做完再收工:

  1. 先用一个很小的文件确认媒体库或插件安装本身能用。小文件也失败,先看权限、磁盘、PHP 报错日志,而不是先把上限改到很大。磁盘和 inode 的核对见云服务器报 No space left。
  2. 再看失败请求的 HTTP 状态码。413 就先搜 Nginx(及前置代理)的 client_max_body_size。官方默认是 1m。
  3. 不是 413 时,核对网站 SAPI 实际加载的 upload_max_filesize、post_max_size、memory_limit。官方默认分别是 2M、8M、128M,你机器上的现值以 php --ini / phpinfo() 为准。记住 CLI 和 PHP-FPM 可能不是同一份配置。
  4. 改 php.ini 或附加 .ini 之后,重载处理站点请求的 PHP 进程;改 Nginx 之后重载 Nginx。再回到媒体库,看显示的最大上传大小是否已更新。
  5. 用一枚略大于旧上限的真实文件试传。成功后再处理更大的主题包或视频,避免一次跨过太多层限制,出了问题说不清卡在哪。
  6. 共享主机改不了这些值时,按 WordPress 官方建议联系主机支持,问清当前上限和是否允许调整,不要把来路不明的「一键放大上传」插件当作解决问题的第一步。

固定链接出现 404、或伪静态循环,不会表现为 413 或「文件过大」。那种情况去核 Nginx rewrite 和固定链接设置,见伪静态与固定链接核对。

7. 用一组对照数字把三层串起来

下面只用官方写明的默认值和规则做对照,方便判断「现在卡在哪一层」。你机器上的现值仍以实际加载的配置为准。

假设网站 PHP 仍是手册默认:upload_max_filesize = 2M,post_max_size = 8M,memory_limit = 128M;Nginx 也仍是默认 client_max_body_size 1m。这时传一个 1.5MB 的图片,请求体会在 Nginx 被拒,浏览器或日志里常见 413。后台媒体库即使写着「最大上传文件大小 2M」,这个 1.5MB 的文件也到不了 PHP。把 Nginx 调整到不小于你计划允许的 POST 大小之后,1.5MB 才能进入 PHP,并受 2M 的单文件上限约束。

再假设已经把 Nginx 放到 32m,PHP 只改了 upload_max_filesize = 32M,post_max_size 仍是 8M。传一个 20MB 的插件压缩包时,单个文件看起来低于 32M,但整次 POST 已经超过 8M。按 PHP 手册,$_POST 和 $_FILES 会是空的,WordPress 也就读不到这个文件。wp_max_upload_size() 取的是两项中较小的值,后台显示的上限这时应对齐到 8M 附近(若没有过滤器再往下压)。把 post_max_size 一并提高到大于 upload_max_filesize,并确认 memory_limit 更大,三项才站在同一条线上。

单位按 PHP 手册可以使用 K、M、G 这类简写。写配置时保持同一风格,避免把 32M 和没有单位的字节数混在一份文件里却没换算。Nginx 的 1m 同样是大小写法,和 PHP 的 1M 是同一量级的「1 兆」,但两套软件要分别改、分别重载。

PHP 手册还写了一句容易忽略的话:如果 POST 超过上限,可以用给处理脚本额外传递 GET 参数再检查是否被设置的方法,追踪这次请求有没有真正进到业务逻辑。排障时除了看页面提示,也可以在 Web 服务器访问日志里对一下状态码和请求大小,在 PHP 错误日志里看有没有与上传、内存相关的记录。日志路径以你当前环境为准。

媒体库、主题 zip、插件 zip 走的都是同一组 PHP 指令和同一道 Nginx 请求体限制。某一类能传、另一类不能,优先比较文件体积和后台显示的上限,而不是先换主题。若只有从远程 URL 侧载图片失败、本地上传正常,那是另一条路径(wp_max_upload_size() 也会被 REST 附件接口用到),先确认远程文件本身是否超过同一上限,再查抓取或超时问题。

核对清单(可勾)

  1. □ 已分清是体积限制还是磁盘/inode 用尽;小文件能创建、只是大文件上传失败,才继续下面几项
  2. □ 失败请求的状态码已经看过:413 先查 client_max_body_size,官方默认 1m,上下文可能在 http / server / location
  3. □ 已确认核对的是网站 SAPI 的配置,而不是只看了命令行 php --ini 的 CLI 文件
  4. □ upload_max_filesize、post_max_size、memory_limit 三项已对照过;后两项按官方说明应更大;file_uploads 为开启
  5. □ 改完 php.ini 后已重载 PHP-FPM 或相应 PHP 进程;只重载 Nginx 不够
  6. □ WordPress 后台显示的最大上传大小已对上 wp_max_upload_size() 的逻辑(取 PHP 两项中较小者);若仍偏小,已检查 upload_size_limit 过滤器或插件限制
  7. □ 前置反代或网关如果存在,其请求体上限也已核对,没有只改源站
  8. □ 没有把 client_max_body_size 随便设成 0 当作常规做法;也没有编某块云面板里未核过的默认值

相关阅读

官网入口(普通链接,无返利):PHP:php.ini 核心指令说明、PHP:配置文件、Nginx:client_max_body_size、WordPress:PHP Optimization、WordPress:wp_max_upload_size()。