对于可写目录,PHP is_writeable()函数始终返回false

对于可写目录,PHP is_writeable()函数始终返回false,php,linux,amazon-ec2,redhat,rhel7,Php,Linux,Amazon Ec2,Redhat,Rhel7,我正在尝试在Red Hat 7 Amazon EC2实例(ami-8cff51fb)中安装一个基于PHP的应用程序,该实例已使用yum安装了Apache 2.4.6和PHP 5.4.16。安装失败,因为它表示特定目录需要由具有0755或0775权限的Web服务器写入 该目录拥有0775个权限,拥有root:apache所有权。我已经验证了httpd进程是由apache用户运行的,并且apache用户是apache组的成员 如果我编辑/etc/passwd临时给apache用户一个登录shell,

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

该目录拥有0775个权限,拥有
root:apache
所有权。我已经验证了httpd进程是由apache用户运行的,并且apache用户是apache组的成员

如果我编辑
/etc/passwd
临时给apache用户一个登录shell,然后
su
给该帐户,我可以使用
touch
命令在目录中以apache用户的身份手动创建文件

我查看了安装程序脚本的源代码,发现它失败了,因为PHP的
is_writable()
函数对所讨论的目录返回false。我创建了一个单独的测试PHP脚本来隔离和验证我看到的行为:

<?php
  $dir = '/var/www/html/limesurvey/tmp';
  if (is_writable($dir)) {
    echo $dir, ' is writable';
  } else {
    echo $dir, ' is NOT writable';
  }
?>
运行
namei-l/var/www/html/limesurvey/tmp
给出:

[ec2-user@ip-x-x-x-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

要写入目录,还需要对上面的目录具有执行权限

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 -m u:"$HTTPDUSER":rwX -m u:`whoami`:rwX tmp
sudo setfacl -dR -m u:"$HTTPDUSER":rwX -m u:`whoami`:rwX tmp

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

在默认情况下是可写的,仅检查用户,而不是组。 因此,即使您的组是匹配的,并且具有可写权限,也将返回false。 要放松此检查,您需要设置

safe_mode_gid = On

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

经过反复的思考,发现SELinux正在阻止写入目录。我找到了一个新的。我可以通过运行以下命令来修复它:

sudo chcon -R -t httpd_sys_rw_content_t tmp

CentOS6中,上述内容应为SELinuxenable

setenforce Permissive
检查状态

sestatus

参考

这可能是一个愚蠢的问题,但是你验证过目录存在吗?@Flosculus根本不是一个愚蠢的问题,但是是的,目录确实存在。我用
0777
实现了你的
/test
目录示例,使用了你的代码,效果很好。你能为那个目录打印出
ls-al
吗?@Flosculus我已经编辑了这个问题,将目录列表包括在内。为了澄清,你能在你的PHP测试文件中运行它吗:
exec('whoami',$output);打印(输出)
,或者更好的
exec('id',$output)。对比系统的用户列表,验证以apache身份运行的用户是真实的。我已经编辑了这个问题,以包含
namei
输出。如您所见,整个目录树具有所有者和组执行权限。谢谢。我只是尝试了一下(并重新启动了Apache服务),但不幸的是,它没有帮助。谢谢,但它不起作用。根据,该选项在PHP5.4.0中被删除。我使用的是PHP5.4.16。你是我的救星你救了我的命:)
sestatus