Nginx+PHP程序无法写入文件、重载后源码变更不生效求助
作为习惯Python/C#、用惯Apache的开发者,刚接触Nginx+PHP-FPM确实会遇到一些专属坑,我帮你拆解这两个问题:
一、源码修改后重载服务不生效的解决步骤
PHP-FPM和Apache的运行逻辑不一样,它自带 opcode 缓存(OPCache),还很容易出现「改错文件路径」的乌龙,按下面的顺序排查:
先确认你改的是正在运行的文件
很多新手会误改本地备份或其他路径的副本,而非Nginx实际指向的文件。你可以在PHP代码里加一行调试代码:echo "当前运行文件路径:" . __FILE__;发起HTTP请求后,看返回的路径是不是你修改的那个文件。也可以用终端命令全局搜索同名文件,对比修改时间:
find / -name "你的PHP文件名.php" 2>/dev/null清空/关闭OPCache缓存
PHP7默认开启OPCache,它会把编译后的PHP代码缓存起来,单纯重载PHP-FPM不会触发缓存更新,必须做以下操作:- 直接重启PHP7.0-FPM(最稳妥):
sudo service php7.0-fpm restart - 临时关闭OPCache(适合测试阶段):编辑
/etc/php/7.0/fpm/php.ini,找到opcache_enable=1改成opcache_enable=0,然后重启服务。 - 临时清空缓存(代码层面):在PHP文件开头加
opcache_reset();,但生产环境别这么用,会影响整体性能。
- 直接重启PHP7.0-FPM(最稳妥):
确认Nginx没有缓存响应
虽然PHP是动态脚本,但Nginx偶尔会缓存旧的响应结果。你可以:- 重启Nginx:
sudo service nginx restart - 请求时加随机参数(比如
?t=12345)绕过缓存。
- 重启Nginx:
二、PHP无法写入文件的排查方案
这个问题90%以上是权限问题,因为PHP-FPM默认用www-data用户运行,而你可能没给这个用户写入目标目录/文件的权限:
确认PHP运行的用户身份
在PHP代码里加一行调试代码,明确当前运行脚本的用户:echo "PHP运行用户:" . exec('whoami');发起请求后,看返回是不是
www-data(这是PHP-FPM的默认运行用户)。检查目标文件/目录的权限
假设你要写入的文件是/var/www/html/data.txt,按下面步骤操作:- 先查看目标目录的权限信息:
如果输出里的所有者和组是ls -ld /var/www/htmlroot:root,那www-data肯定没有写入权限。 - 修改目录所有者(推荐,权限更安全):
(sudo chown -R www-data:www-data /var/www/html-R是递归修改子目录和文件,如果你只需要改某个特定子目录,替换路径即可) - 临时放宽权限(仅测试用,生产环境不建议):
sudo chmod -R o+w /var/www/html
- 先查看目标目录的权限信息:
检查PHP的
open_basedir限制
PHP的open_basedir会限制脚本只能在指定目录内读写,如果目标文件不在这个范围内,写入就会失败。
编辑/etc/php/7.0/fpm/php.ini,搜索open_basedir:- 如果有设置(比如
open_basedir = /var/www/html/:/tmp/),确认你要写入的目录在列表里; - 如果目标目录不在列表,要么添加进去,要么注释掉这行(生产环境需谨慎操作),然后重启PHP-FPM。
- 如果有设置(比如
查看PHP错误日志找具体原因
上面的步骤如果都没解决,一定要看错误日志——它会直接告诉你是权限不足、路径不存在还是磁盘已满。
编辑/etc/php/7.0/fpm/php.ini,配置日志相关参数:error_reporting = E_ALL display_errors = Off # 生产环境别开,避免泄露敏感信息 log_errors = On error_log = /var/log/php7.0-fpm.log重启PHP-FPM后,尝试发起写入请求,然后查看日志:
sudo cat /var/log/php7.0-fpm.log检查SELinux(如果开启)
Ubuntu默认SELinux是关闭的,但如果你的系统手动开启了,它可能会阻止PHP写入操作。用下面的命令查看状态:getenforce如果输出是
Enforcing,临时关闭试试:sudo setenforce 0如果能正常写入了,再去配置SELinux的允许规则(这个操作较复杂,新手可以先关闭,生产环境再深入研究)。
内容的提问来源于stack exchange,提问作者dthor

