背景:作为项目助理接手一个项目的维护,最近运维同事帮忙调整一次报错等级到 警告 时,各种异常信息到页面。解决了一些后,有一个很头疼的,折腾了老半天的问题。页面上一直打印写日志的方法fopen($file_name,"a+")错误,没有权限。于是在打开之前判断有没有该文件,没有创建一个空的文件并用chmod($file_name,0777)给赋上权限。问题是解决了,但是产生原因却是不明所以。
纠结:主要纠结的地方的是按说这个文件是我这个php脚本创建的,当然我拥有读写权限的,怎么会报没有权限的异常了。于是又将测试好的代码注掉,在第二天的时候开始检测服务器上的该文件拥有者到底是哪个用户。用ls -l 命令后看到该文件的拥有者是root,并且是在凌晨某个时刻改变的最后状态。看到凌晨的时候,第一反应就是会不会和守护进程有关,因为这个系统属于内部系统,没人会在凌晨去访问。于是,查看守护进程的配置,在里面果然看到了root用户的出现。
理了理想法并测试了自己想法后和运维同事确认了下,特将问题出现的整个流程记录如下:
1.守护进程里配置的是凌晨的时候由root用户访问php脚本,在该脚本运行的过程中,会创建日志文件并写入内容。值得注意的是,此时文件的所有者就是root了。
2.网站开始运行,内部同事开始点击了,访问了一些敏感流程,需要记录日志了。因为日志是以日期命名的,所以开始打开同一天的日志文件,但是此时访问该脚本的用户却已经是运行这个项目的用户了(用的nginx,默认运行用户为www-data)和root不一样。
3.当用户不一样,并且在创建文件的时候并没有赋予777权限,也就意味着同组和其他用户都不可能有写入的权限,于是,页面就开始打印异常信息了。
解决方法就是上面提到的,先判断文件存在与否,不存在就创建并chmod 777权限该文件(在文件创建的时候赋权限是为了保证创建文件和赋值权限是同步的,文件存在了就不要再赋权限了。如果访问的用户不是文件的拥有者又会报chmod没有权限的异常,当然可以在chmod前面加@异常抑制符,但可避免的异常还是避免了好,当锻炼自己的逻辑思考能力了-_-)。那么,哪怕此时创建文件的用户是root也没关系,因为已经给所有用户可读写权限了。
备注:
1.确认nginx服务下运行项目的默认用户为www-data,是因为看到一些由项目运行过程中创建的文件的拥有者是www-data,是不是正确的,没有很肯定的把握,谨慎对待。
2.建议各位同猿们,有可能的话还是搭一个lnmp环境,因为像文件权限这类的问题,win下是不可能报的,想调下或者测试下自己的想法就不可能了。就像上面的我确认root用户访问php脚本,创建的文件就属于root用户,这就是在之前搭的虚拟机下写个小代码测试的。