【问题标题】:Why does file_put_contents have permission issues when run from the browser?为什么 file_put_contents 从浏览器运行时会出现权限问题?
【发布时间】:2013-12-15 12:35:00
【问题描述】:

这个问题已经在这里问过几次了,但我还没有找到解决办法。我有一个 Fedora 19 LAMP 服务器,我只想运行简单的命令:file_put_contents('test.txt', 'Hello there'); 以确认我的 Web 服务器可以使用 PHP 将数据写入文件。我无法找出合适的权限方案。首先,只是为了开发,Apache 的文档根是/var/www/html。该目录最初归一个名为www-data 的用户和组所有,但我将目录的组更改为httpd 进程所有者的主要组,名为apache。当 PHP 运行时,此所有者处于活动状态。我已经通过以下方式确认了这一点:

如您所见,进程所有者是apache,当前目录是/var/www/html/php-console。该目录归www-data 所有,apache 组的成员对其拥有完全访问权限。

我尝试了以下方法让 PHP 在此位置实际创建文件,但无济于事:

chmod 777 /var/www/html/php-console

chown apache /var/www/html/php-console
chgrp apache /var/www/html/php-console

cd /var/www/html; > test.txt; chmod 777 test.txt;

从浏览器运行此脚本时,不会有任何效果。但是,当我在 PHP CLI 中使用file_put_contents 时,它的工作方式与我预期的一样,前提是我输入命令的用户或其组对该目录或测试文件具有写入权限。

所以,从命令行中,您可以看到 www-data 如何对我所在的文件夹具有读取、写入和执行权限。posix_getpwuidposix_geteuid 帮助您找到 Apache/PHP 的所有者进程,在这种情况下与登录控制台的用户相同。 file_put_contents 成功将 8 个字节写入指定文件。如果我将组或所有者和组更改为其他内容,我会得到 Permission denied,这绝对是有道理的。

如果这在命令行上有效,那么为什么不在我真正想要它的时候,即在实际提供网页时呢???

【问题讨论】:

  • 奇怪...所以我想我会再尝试一次chmod 777 /var/www/html/php-console,这一次它让我可以写入文件。然后我把它改回775,我仍然可以运行file_put_contents,没有权限错误。我重新启动了计算机,我仍然可以正常运行此代码。我决定将/var/www 的文件上下文从httpd_sys_rw_content_t 更改为httpd_sys_content_t,它仍然有效。然后我尝试关闭httpd_unified,我又得到了权限错误。我不完全确定它是否首先被关闭。无论如何,谢谢你的帮助,伊格纳西奥
  • 还有一点注意:当我关闭httpd_unified,那么httpd_sys_rw_content_t文件上下文确实是用PHP写文件的必要条件。很有趣...
  • 我最近不得不重新审视这个问题。我注意到在我的 Ubuntu 和 Fedora 机器上,启用file_put_contents 写入文件或目录的真正关键是确保 PHP 的进程所有者(apache 在 F19 和 www-data 在Ubuntu 13.10) 也具有对该文件或目录的写入权限。我的 Ubuntu 机器没有 SELinux,但我必须确保在 Fedora 上正确配置了策略管理器。

标签: php linux apache permissions


【解决方案1】:

因为您忘记阅读 httpd_selinux(8) 手册页并为目录提供适当的文件上下文以允许 Web 服务器在那里写入文件。

【讨论】:

  • 非常感谢您提醒我注意这一点。我一直在阅读httpd_selinux(8) 以及其他在线讨论,但我不清楚我应该设置什么文件上下文。至于 sebooleans,我系统上的 getsebool 告诉我 httpd_builtin_scripting、httpd_unified 和 httpd_enable_cgi 已打开。然后我运行: semanage fcontext -a -t httpd_sys_content_t "/var/www(/.*)?" restorecon -R -v /var/www 简单地给那里的一切 httpd sys 读/写访问权限,但我仍然被拒绝...
  • 抱歉,我不小心在评论中复制了错误的文字。我确实将/var/www 下所有内容的文件上下文设置为httpd_sys_rw_content_t。命令ls -dZ /var/www/html/php-console,关于我目前最感兴趣的目录的文件上下文,返回我所期望的:drwxrwxr-x. www-data www-data unconfined_u:object_r:httpd_sys_rw_content_t:s0 /var/www/html/php-console 但是我在 php-console 中的代码 sn-p 仍然给我“权限被拒绝”。在我的 sn-p 中通过 exec 传递的 ls -Zd 命令确认了相同的文件上下文。叹息......还有其他想法吗?
  • @williamcwilliams:试试audit2why -a -l。您可能希望将结果重定向到文件中以便于处理。
猜你喜欢
  • 2021-12-03
  • 1970-01-01
  • 1970-01-01
  • 2016-09-17
  • 1970-01-01
  • 2018-02-16
  • 1970-01-01
  • 2020-04-13
  • 1970-01-01
相关资源
最近更新 更多