PHP is_writable()函数对于可写目录总是返回false

我正在尝试在使用yum安装Apache 2.4.6和PHP 5.4.16的Red Hat 7 Amazon EC2实例(ami-8cff51fb)中安装基于PHP的软件包。 安装失败,因为它表示一个特定的目录需要由具有0755或0775权限的Web服务器写入。

有问题的目录具有root:apache权限的0775权限root:apache所有权。 我已经validation了httpd进程正在由apache用户运行,并且apache用户是apache组的成员。

如果我编辑/etc/passwd临时给apache用户一个loginshell然后su到那个帐户,我可以使用touch命令在目录内以apache用户的方式手动创build文件。

我查看了安装程序脚本的源代码,发现它失败了,因为PHP的is_writable()函数正在为有问题的目录返回false。 我创build了一个单独的testingPHP脚本来隔离和validation我看到的行为:

 <?php $dir = '/var/www/html/limesurvey/tmp'; if (is_writable($dir)) { echo $dir, ' is writable'; } else { echo $dir, ' is NOT writable'; } ?> 

这将输出NOT可写消息。 如果我将$dir改为/tmp那么它正确地输出那个/tmp是可写的。

如果我将目录权限更改为0777和/或将所有权更改为apache:apache则PHP仍然报告该目录不可写。 我甚至尝试创build一个具有相同权限和所有权的/test目录,我的testing脚本仍然报告它不可写。

我真的无法解释这种行为,所以任何想法都会受到欢迎!

提前致谢。


下面给出了/var/www/html/limesurvey的目录列表。 根据Lime Survey的安装说明 , tmpupload目录拥有0775权限。 test.php是我上面提到的testing脚本。

 [ec2-user@ip-xx-xx-xxx limesurvey]$ pwd /var/www/html/limesurvey [ec2-user@ip-xx-xx-xxx limesurvey]$ ls -al total 80 drwxr-xr-x. 20 root apache 4096 Mar 30 11:25 . drwxr-xr-x. 3 root root 23 Mar 25 14:41 .. drwxr-xr-x. 2 root apache 38 Mar 10 12:56 admin drwxr-xr-x. 16 root apache 4096 Mar 10 12:56 application drwxr-xr-x. 3 root apache 4096 Mar 10 12:56 docs drwxr-xr-x. 2 root apache 4096 Mar 10 12:56 fonts drwxr-xr-x. 19 root apache 4096 Mar 10 12:56 framework -rw-r--r--. 1 root apache 429 Mar 10 12:56 .gitattributes -rw-r--r--. 1 root apache 399 Mar 10 12:56 .gitignore -rw-r--r--. 1 root apache 296 Mar 10 12:56 .htaccess drwxr-xr-x. 4 root apache 4096 Mar 10 12:56 images -rw-r--r--. 1 root apache 6652 Mar 10 12:56 index.php drwxr-xr-x. 5 root apache 39 Mar 10 12:56 installer drwxr-xr-x. 89 root apache 4096 Mar 10 12:56 locale drwxrwxr-x. 2 root apache 39 Mar 25 14:41 logs drwxr-xr-x. 4 root apache 49 Mar 10 12:56 plugins -rw-r--r--. 1 root apache 61 Mar 10 12:56 README drwxr-xr-x. 4 root apache 4096 Mar 10 12:56 scripts -rw-r--r--. 1 root apache 380 Mar 10 12:56 .scrutinizer.yml drwxr-xr-x. 5 root apache 4096 Mar 10 12:56 styles drwxr-xr-x. 5 root apache 4096 Mar 10 12:56 styles-public drwxr-xr-x. 12 root apache 4096 Mar 10 12:56 templates -rw-r--r--. 1 root apache 159 Mar 30 11:11 test.php drwxr-xr-x. 3 root apache 20 Mar 10 12:56 themes drwxr-xr-x. 26 root apache 4096 Mar 10 12:56 third_party drwxrwxr-x. 5 root apache 80 Mar 26 13:45 tmp drwxrwxr-x. 6 root apache 79 Mar 10 12:57 upload 

运行namei -l /var/www/html/limesurvey/tmp给出:

 [ec2-user@ip-xxx-xxx ~]$ namei -l /var/www/html/limesurvey/tmp f: /var/www/html/limesurvey/tmp drwxr-xr-x root root / drwxr-xr-x root root var drwxr-xr-x root root www drwxr-xr-x root root html drwxr-xr-x root apache limesurvey drwxrwxr-x root apache tmp 

Solutions Collecting From Web of "PHP is_writable()函数对于可写目录总是返回false"

经过多次的搔痒之后,发现SELinux阻止了目录的写入。 我找到了一个很好的教程来解释发生了什么事情 。 我能够通过运行这个命令来解决它:

 sudo chcon -R -t httpd_sys_rw_content_t tmp 

CentOS 6上面应该是SELinux启用强制执行的

 setenforce Permissive 

检查状态

 sestatus 

请参阅https://wiki.centos.org/HowTos/SELinux

要写入一个目录,您还需要对上面的目录执行权限。

 namei -l /var/www/html/limesurvey/tmp 

应该显示哪一步你没有正确的权限。

 HTTPDUSER=`ps aux | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | head -1 | cut -d\ -f1` sudo setfacl -R -mu:"$HTTPDUSER":rwX -mu:`whoami`:rwX tmp sudo setfacl -dR -mu:"$HTTPDUSER":rwX -mu:`whoami`:rwX tmp 

直接从Symfony2安装指南中,这解决了Apache和CLI工具之间的缓存写入访问共享问题。 这可能也适用于你的tmp目录。

is_writable默认情况下只对用户进行检查,而不对组进行检查。 所以,即使你的组是匹配的,并有权限is_writable将返回false。 放松这个检查你需要设置

 safe_mode_gid = On 

在PHP配置或相应地更改用户。