PHP:文件写权限

zeg*_*jan 5 php file-permissions

因为这个事我已经头疼好久了……

\n\n

我正在尝试在我的虚拟服务器(CentOS 7、apache http 服务器、php 5.4.3)上安装 MyBB 论坛,但遇到了文件权限问题。MyBB 需要两个文件可写,其中一个是config.php,第二个是settings.php,它们都在目录 中inc

\n\n

我将两个文件的权限都设置为 666。我编写了一个简单的测试 php 页面,它模仿 MyBB 测试写入能力的方式:

\n\n
<?php\necho(\'config: \');\n$configwritable = @fopen(\'forum/inc/config.php\', \'w\');\nif ($configwritable) {\n        echo(\'yes\');\n} else {\n        echo(\'no\');\n}\necho(\'<br/>\');\necho(\'settings: \');\n$configwritable = @fopen(\'forum/inc/settings.php\', \'w\');\nif ($configwritable) {\n    echo(\'yes\');\n} else {\n    echo(\'no\');\n}\n?>\n
Run Code Online (Sandbox Code Playgroud)\n\n

页面输出为

\n\n
config: no\nsettings: yes\n
Run Code Online (Sandbox Code Playgroud)\n\n

但如果我列出文件,它们会像这样显示

\n\n
root@localhost# ls -l forum/inc/config.php forum/inc/settings.php \n-rw-rw-rw-. 1 krkavec krkavec 0  2.\xc2\xa0\xc5\x99\xc3\xadj 22.49 forum/inc/config.php\n-rw-rw-rw-. 1 krkavec krkavec 0  2.\xc2\xa0\xc5\x99\xc3\xadj 22.51 forum/inc/settings.php\n
Run Code Online (Sandbox Code Playgroud)\n\n

这怎么可能?这两个文件属于同一用户,同一组,具有相同的大小(零),位于同一目录中,具有相同的权限,具有几乎相同的修改时间(相差两分钟)以及几乎所有其他内容,除了他们的名字是相同的。

\n\n

为了让事情变得更奇怪,我尝试再次删除和创建文件,请观看:

\n\n

1:删除两个文件

\n\n
root@localhost# rm -f forum/inc/config.php forum/inc/settings.php\n
Run Code Online (Sandbox Code Playgroud)\n\n

和页面输出:

\n\n
config: no\nsettings: no\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是可以的,因为该inc目录不应该是可写的。

\n\n

2:创建settings.php

\n\n
root@localhost# F=forum/inc/settings.php ; touch $F ; chown krkavec:krkavec $F ; chmod 666 $F\nroot@localhost# ls -l forum/inc/settings.php forum/inc/config.php\nls: cannot access forum/inc/config.php: No such file or directory\n-rw-rw-rw-. 1 krkavec krkavec 0  2.\xc2\xa0\xc5\x99\xc3\xadj 23.15 forum/inc/settings.php\n
Run Code Online (Sandbox Code Playgroud)\n\n

和页面输出:

\n\n
config: no\nsettings: yes\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是完全正常和预期的 - 文件在那里并且具有可写权限。

\n\n

3:创建config.php

\n\n
root@localhost# F=forum/inc/config.php ; touch $F ; chown krkavec:krkavec $F ; chmod 666 $F\nroot@localhost# ls -l forum/inc/settings.php forum/inc/config.php\n-rw-rw-rw-. 1 krkavec krkavec 0  2.\xc2\xa0\xc5\x99\xc3\xadj 23.23 forum/inc/config.php\n-rw-rw-rw-. 1 krkavec krkavec 0  2.\xc2\xa0\xc5\x99\xc3\xadj 23.15 forum/inc/settings.php\n
Run Code Online (Sandbox Code Playgroud)\n\n

和页面输出:

\n\n
config: no\nsettings: yes\n
Run Code Online (Sandbox Code Playgroud)\n\n

嘭!我完全希望配置是可写的。

\n\n

任何帮助是极大的赞赏。

\n\n

编辑:我根据Marc B和draw010的建议修改了测试页面

\n\n
<?php\nerror_reporting(E_ALL);\nini_set(\'display_errors\', 1);\n\necho(\'config var_dump: \');\nvar_dump(stat(\'forum/inc/config.php\'));\necho(\'<br/>config: \');\n$configwritable = fopen(\'forum/inc/config.php\', \'w\');\nif ($configwritable) {\n    echo(\'yes\');\n} else {\n    echo(\'no\');\n}\necho(\'<br/>\');\necho(\'settings var_dump: \');\nvar_dump(stat(\'forum/inc/settings.php\'));\necho(\'<br/>settings: \');\n$configwritable2 = fopen(\'forum/inc/settings.php\', \'w\');\nif ($configwritable2) {\n    echo(\'yes\');\n} else {\n    echo(\'no\');\n}\n?>\n
Run Code Online (Sandbox Code Playgroud)\n\n

页面的输出(两个文件都存在)是:

\n\n
config var_dump: array(26) { [0]=> int(64768) [1]=> int(19155212) [2]=> int(33206) [3]=> int(1) [4]=> int(1000) [5]=> int(1000) [6]=> int(0) [7]=> int(0) [8]=> int(1443821772) [9]=> int(1443821772) [10]=> int(1443821772) [11]=> int(4096) [12]=> int(0) ["dev"]=> int(64768) ["ino"]=> int(19155212) ["mode"]=> int(33206) ["nlink"]=> int(1) ["uid"]=> int(1000) ["gid"]=> int(1000) ["rdev"]=> int(0) ["size"]=> int(0) ["atime"]=> int(1443821772) ["mtime"]=> int(1443821772) ["ctime"]=> int(1443821772) ["blksize"]=> int(4096) ["blocks"]=> int(0) } \nconfig: \nWarning: fopen(forum/inc/config.php): failed to open stream: Permission denied in /var/www/html/test.php on line 8\nno\nsettings var_dump: array(26) { [0]=> int(64768) [1]=> int(19155069) [2]=> int(33206) [3]=> int(1) [4]=> int(1000) [5]=> int(1000) [6]=> int(0) [7]=> int(0) [8]=> int(1443821763) [9]=> int(1443823158) [10]=> int(1443823158) [11]=> int(4096) [12]=> int(0) ["dev"]=> int(64768) ["ino"]=> int(19155069) ["mode"]=> int(33206) ["nlink"]=> int(1) ["uid"]=> int(1000) ["gid"]=> int(1000) ["rdev"]=> int(0) ["size"]=> int(0) ["atime"]=> int(1443821763) ["mtime"]=> int(1443823158) ["ctime"]=> int(1443823158) ["blksize"]=> int(4096) ["blocks"]=> int(0) } \nsettings: yes\n
Run Code Online (Sandbox Code Playgroud)\n

zeg*_*jan 3

由于某些神奇的、未知的原因,当我重命名settings.phpconfig.php然后创建新文件settings.php并适当设置权限时,这两个文件都是可写的。

但是,我不知道为什么必须重命名该文件。结果与问题中描述的步骤 3 后的结果相同,只是它有效。

非常欢迎任何关于为什么要做这顶帽子及其背后原因的建议。

编辑:这是由 SELinux 安全上下文引起的,它阻止 apache 写入文件。跑步chcon -t httpd_sys_rw_content_t config.php解决了这个问题。