AI摘要:文章讲述了作者在升级Ubuntu系统后,Typecho博客上传图片失败的排障过程。问题源于升级后目录权限丢失,导致PHP-FPM无法写入。通过检查日志、确认目录权限和属主,最终通过修改目录属主为`www:www`解决问题。文章总结了排查步骤和注意事项,强调权限问题通常是上传失败的原因。
2026-11-06 · 技术排障
站点:02博客网(Typecho 1.3.0 + Joe 主题,宝塔面板,PHP 8.4)
起因:换系统后,上传功能突然罢工
2026 年 10 月底,我把博客服务器从 Ubuntu 20.04 升级到 Ubuntu 24.04,宝塔面板、PHP 版本、Typecho、Joe 主题、插件全部沿用之前的配置。一切看起来正常,网站访问、后台登录、文章编辑都没问题。
直到 11 月 5 日,在后台编辑文章时上传图片,弹出一句冷冰冰的提示:"1.png 上传失败"。
换默认主题、禁用插件、重启 PHP-FPM——全都试过,问题依旧。之前Typecho 的上传机制一直很稳定。
过程:一次层层剥开的排查
第一步:确认不是插件的问题
先怀疑是图片压缩插件(SwitchImges,自动转 WebP)在捣乱。禁用插件后上传依然失败,说明问题在更底层的 Typecho 原生上传路径。
第二步:定位到 move_uploaded_file 失败
在 Typecho 的 var/Widget/Upload.php 里加了 DEBUG 日志,跟踪上传流程:
[Upload DEBUG] upload() called, method=POST, files=1
[Upload DEBUG] file: name=1.png err=0 tmp=/tmp/phpxxx
[Upload DEBUG] is_uploaded=true
[UploadHandle DEBUG] ext=png
[UploadHandle DEBUG] checkFileType=true
[UploadHandle DEBUG] upload path=/www/wwwroot/book.02clouds.cn/usr/uploads/2026/11, is_dir=true
[UploadHandle DEBUG] about to move file, path=/www/wwwroot/book.02clouds.cn/usr/uploads/2026/11/xxxx.png
[UploadHandle DEBUG] move_uploaded_file result=false
[UploadHandle DEBUG] move failed! src_exists=true
[UploadHandle DEBUG] move failed! dest_dir_exists=true
[UploadHandle DEBUG] move failed! dest_dir_writable=false关键就在最后一行:dest_dir_writable=false。 上传目录对 PHP-FPM 来说不可写。
第三步:找到权限丢失的根因
lsattr /www/wwwroot/book.02clouds.cn/.user.ini
# 输出:----i---------e------- (immutable 属性,宝塔保护)
namei -l /www/wwwroot/book.02clouds.cn/usr/uploads/2026/11/
# 输出:drwxr-xr-x root root ... (属主是 root,不是 www)Ubuntu 20 → 24 升级时,宝塔重建了 www 用户(新 UID 1000),但旧站点目录的属主没有同步更新——目录还是 root:root,PHP-FPM 以 www 用户运行,没有写入权限。
Ubuntu 20 上这些目录属主是 www,所以一切正常。升级后用户重建,目录没跟着改,上传功能就悄悄挂了。
第四步:修复
chown -R www:www /www/wwwroot/你的站点目录一条命令,上传功能立即恢复。
修复方法总结
如果你也遇到 Typecho(或 WordPress 等 PHP 博客)上传图片失败,按这个顺序排查:
- 看 PHP 错误日志:宝塔面板 → PHP 设置 → 错误日志,找
move_uploaded_file或is_uploaded_file相关报错 - 检查目录权限:
ls -la看 uploads 目录属主,应该是www:www,如果是root:root就是问题 - 确认 PHP-FPM 用户:宝塔 PHP 8.4 的 FPM 进程以
www用户运行,ps aux | grep php-fpm能看到 - 修复权限:
chown -R www:www /www/wwwroot/你的站点目录 - 重启 PHP-FPM:宝塔面板 → 软件商店 → PHP 8.4 → 重启(让权限生效)
如果用的是其他面板(aaPanel、1Panel 等),原理一样:站点目录属主必须和 PHP-FPM 运行用户一致。
警示:这些坑我替你踩过了
坑 1:系统升级后,权限不会自动迁移
这是最隐蔽的坑。从 Ubuntu 20 升 24、或者换了服务器重装宝塔,www 用户的 UID 可能变了,但已有站点目录的属主不会自动更新。升级后第一件事,检查所有站点的目录属主。
坑 2:宝塔的 .user.ini 有 immutable 保护
.user.ini 被宝塔设了 chattr +i(immutable 属性),直接 echo > 或 cp 覆盖会报 Operation not permitted。改之前要先 chattr -i /www/wwwroot/你的站点/.user.ini,改完可以再 chattr +i 恢复保护。
坑 3:PHP 8.4 的 open_basedir 限制
如果 .user.ini 里设了 open_basedir,注意它限制的是 PHP 进程能访问的路径范围。如果插件需要调用外部工具(如 FFmpeg、ImageMagick),要把工具路径也加进 open_basedir,否则插件里的 is_file('/usr/local/bin/ffmpeg') 会被 PHP 拒绝。
坑 4:换主题、换编辑器都没用
上传失败时,换默认主题、换编辑器都没用,因为问题在 Typecho 原生的 Widget\Upload 层,不在主题或编辑器。先看日志,再猜原因,别乱换东西。
坑 5:改代码加 DEBUG 是最快的排查方式
在 var/Widget/Upload.php 的 uploadHandle 方法里加 error_log,把每个关键步骤的返回值打到日志里,比看 nginx access log 猜快得多。日志会告诉你 $_FILES 有没有数据、is_uploaded_file 返回什么、move_uploaded_file 成功还是失败、失败时目录可不可写——所有答案都在日志里。
一句话总结
上传失败 90% 是权限问题,不是代码问题。 看到"上传失败"先查目录属主,比折腾插件、换主题、重启 PHP 都管用。
本文基于真实排障记录整理,站点信息已脱敏。如果你也遇到类似问题,欢迎留言交流。

暂无评论内容