DEVDIY |独立站外贸跨境电商开发头像
WordPress 媒体库上传失败(HTTP 错误):目录权限、php.ini 与 open_basedir 排查封面图

WordPress 媒体库上传失败(HTTP 错误):目录权限、php.ini 与 open_basedir 排查

署名:DEVDIY
原文/延伸阅读:https://devdiy.cn/wordpress/

典型现象:后台「媒体 → 添加」选图后进度条跑完,提示「HTTP 错误」;或者「无法创建目录」「上传目录不可写」;有时小图能传、大图失败,有时只有某个月份目录失败。

多数不是「WordPress 坏了」,而是 PHP 上传限制、wp-content/uploads 权限、磁盘配额,或 open_basedir/upload_tmp_dir 把临时文件拦在外面。下面按「先看浏览器/服务器错误 → 再查 PHP 限制 → 再查目录与 SELinux → 最后排插件」走。

0. 先把真实错误拿出来

浏览器里只显示「HTTP 错误」往往不够。打开开发者工具(F12)→ Network,重新上传一次,点 async-upload.php(或 admin-ajax.php)那条请求:

  1. Status 是 413 → 反向代理 / Nginx client_max_body_size 太小;
  2. Status 是 500 → 看 PHP / Web 服务器错误日志;
  3. Status 是 200,但响应体是 HTML 或 {“success”:false,…} → 看返回 JSON 里的 data.message。

服务器日志优先看:

# PHP-FPM 常见路径(按发行版调整)
tail -n 100 /var/log/php*-fpm.log
# 或 Nginx / Apache 错误日志
tail -n 100 /var/log/nginx/error.log
tail -n 100 /var/log/apache2/error.log

日志里出现 Allowed memory size、POST Content-Length exceeds、Failed to open stream、Permission denied,就能直接定位,不必盲目改权限。

1. 核对 PHP 上传与内存限制

在站点根放一个临时 phpinfo 页(查完立刻删),或在 WP 后台装只读信息类插件,确认这三项:

配置项建议起步值说明
upload_max_filesize≥ 32M单文件上限
post_max_size≥ upload_max_filesize整次 POST 上限,必须 ≥ 上传限制
memory_limit≥ 256M图片缩放、生成缩略图时更吃内存
max_execution_time≥ 60大图或慢磁盘时避免超时

改配置位置因环境而异:

  • 宝塔 / 面板:软件商店 → PHP → 配置修改 / 上传限制;
  • 自建 PHP-FPM:改 php.ini 后 systemctl reload php-fpm;
  • 仅当前站点可用时,可在站点根 .user.ini(部分面板)写:
upload_max_filesize = 32M
post_max_size = 40M
memory_limit = 256M

改完后重新打开 phpinfo 确认生效。只改了 upload_max_filesize、没改 post_max_size,大图仍会失败。

WordPress 侧还可在 wp-config.php(That’s all, stop editing! 之前)加:

define('WP_MEMORY_LIMIT', '256M');
define('WP_MAX_MEMORY_LIMIT', '512M');

这只影响 WP 申请的内存上限,不能突破 PHP 的 memory_limit,两者都要够。

2. 检查 uploads 目录是否可写、是否按月生成

标准路径:wp-content/uploads/。WordPress 默认按 年/月 建子目录。

在服务器上(路径按实际站点根调整):

cd /var/www/html/wp-content
ls -ld uploads
ls -ld uploads/$(date +%Y) uploads/$(date +%Y)/$(date +%m) 2>/dev/null
# PHP-FPM 用户常见为 www-data / nginx / www
namei -l uploads

经验值:

  • 目录属主应是跑 PHP 的那个用户(如 www-data);
  • 目录权限常见 755,文件 644;不要一上来就 777;
  • 若当月目录不存在且父目录不可写,后台就会报「无法创建目录」。

修复示例(用户名按环境改):

chown -R www-data:www-data /var/www/html/wp-content/uploads
find /var/www/html/wp-content/uploads -type d -exec chmod 755 {} \;
find /var/www/html/wp-content/uploads -type f -exec chmod 644 {} \;

磁盘与 inode 也要看一眼:

df -h /var/www/html
df -i /var/www/html

Use% 到 100% 或 inode 耗尽时,上传会表现为随机 HTTP 错误。

3. open_basedir、upload_tmp_dir 与 SELinux

部分主机把 PHP 限制在站点目录内。若 upload_tmp_dir 指向 /tmp,而 open_basedir 不含 /tmp,上传临时文件会写失败。

在 phpinfo 里查:

  • open_basedir
  • upload_tmp_dir
  • sys_temp_dir

处理思路:

  1. 把 upload_tmp_dir 改到站点内可写目录,例如 /var/www/html/wp-content/tmp,并确保该目录存在且属主正确;或
  2. 在 open_basedir 中追加系统临时目录(按主机商文档操作,勿随意放开整盘)。

CentOS / RHEL 上若开启 SELinux,还可能出现「权限看着对、仍 Permission denied」:

getenforce
# 临时验证(确认后再做持久化上下文,勿长期停 SELinux)
ausearch -m avc -ts recent | grep uploads

把上下文设回 httpd_sys_rw_content_t(具体命令以发行版文档为准)后再测上传。

4. Nginx / 反向代理的 body 大小

Nginx 默认 client_max_body_size 往往是 1m。超过就会 413,浏览器端可能仍显示成笼统的上传失败。

在对应 server 或 http 块:

client_max_body_size 40m;

重载:

nginx -t && systemctl reload nginx

前面若还有 CDN / 负载均衡,同样要查它们的请求体上限。

5. 排除插件与图片处理冲突

若「关掉所有插件、换默认主题」后就能上传:

  1. 逐个启用,定位安全类、图片压缩、对象存储(OSS/S3)插件;
  2. 对象存储插件若配错 Bucket / 密钥,常在本地写入成功后的「远程同步」阶段失败,表现仍像上传失败;
  3. 用 WP_DEBUG_LOG 抓堆栈:
// wp-config.php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

日志一般在 wp-content/debug.log。复现一次上传后查看最新几行,查完将 WP_DEBUG 改回 false。

6. 验证清单(做完打勾)

  1. Network 里 async-upload.php 不再是 413/500;
  2. phpinfo 中 upload_max_filesize ≤ post_max_size,且大于你要传的文件;
  3. uploads/年/月 存在且 PHP 用户可写;
  4. 磁盘与 inode 未满;
  5. 默认主题 + 停用插件后,同一张图能进媒体库并生成缩略图。

缩略图:上传成功后,在 uploads/年/月/ 下应能看到带 -150x150、-300x300 等后缀的衍生文件。只有原图、没有衍生文件时,再回头查 memory_limit 与 GD/Imagick 扩展是否启用。


本文由 DEVDIY 整理。我们日常更多时间花在 WordPress / Shopify 外贸站与微信小程序的开发和线上排查上,把这类「看起来像玄学、其实能逐步复现」的问题写成可执行步骤。

原文/延伸阅读:https://devdiy.cn/wordpress/

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/lgm252008/article/details/168859062

文章来源转载

评论

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--