【问题标题】:Can't write to /tmp with php, despite 777 permissions and no open_basedir value尽管有 777 权限且没有 open_basedir 值,但无法使用 php 写入 /tmp
【发布时间】:2012-05-31 22:00:27
【问题描述】:

我正在尝试使用 php fopen 函数将文件写入我的 /tmp 目录(在 apache 服务器上),但它失败了:

<?php
$handle = fopen("/tmp/test.txt", "x");
if ($handle) 
   echo "Success!";
else 
    print_r(error_get_last());

这会返回错误信息:

打开流失败:没有这样的文件或目录。

/tmp 目录的权限设置为drwxrwxrwt,我可以看到 Web 用户正在向其写入其他文件。奇怪的是,如果我将脚本指向另一个具有777 权限的文件夹,它会返回成功。但是我的open_basedir 没有任何价值。我有safe_mode=onallow_url_fopen=off,但我认为这不应该解释它?

这是 Apache Httpd 2.0 上的 PHP 5.3.10。

【问题讨论】:

  • 不,上面脚本的目的是测试我是否可以在我的 /tmp 文件夹中创建文件。我已经尝试了带有“x”和“w”标志的脚本。
  • 感谢 Robus - 这听起来很可能 - 服务器位于一个大型、相当复杂的大学网络上。我如何验证这是否是问题所在?
  • 尝试执行“ls -l /tmp”或等效命令。我在 Perl 上遇到了这个问题,脚本看到的 /tmp 目录与我实际的 /tmp 目录中的目录非常不同。

标签: php fopen tmp php-safe-mode


【解决方案1】:

根据显示的错误信息,没有文件夹/tmp/。也许 tmp 文件夹不是根目录?

如果文件实际上不存在,则不会显示此错误,因为它会尝试创建它。

如果文件已经存在,方法x 也会返回警告。 (文档:http://www.php.net/manual/en/function.fopen.php

我认为这还有另一个可能出错的原因,即执行 PHP 的用户无权在 /tmp/ 文件夹中写入。

【讨论】:

  • 正如我在问题中所写,我的服务器上有一个名为 /tmp 的文件夹,是的,它位于根目录上,据我所知,执行 php 的用户确实将文件写入 / tmp 文件夹不断。
【解决方案2】:

尝试将/tmp 添加到open_basedir。例如:

    php_admin_value open_basedir /some/path:/another/path:/tmp

我不确定这是您实际面临的问题,但我在寻找此解决方案时发现了您的问题,所以我想这可能对其他人有所帮助。

【讨论】:

    【解决方案3】:

    我遇到了完全相同的问题。 PHP 报告在/tmp/myoutputfile 中打开文件没有问题,但该路径中没有文件。然后我做了

    find / -name "myoutputfile"
    

    并在/tmp/systemd-…/myoutputfile 中找到它。 我在 Google 上找到了this article
    所以,就我而言,它是 Systemd 和 Apache Httpd 的组合。我希望这会对某人有所帮助。

    【讨论】:

    • 这是巨大的!在 Drupal RHEL 6 到 RHEL 7 升级中导致很难找到错误,其中 Drupal file_temp_directory 设置为 /var/tmp/drupal 但由于尚未创建 drupal 目录而无法生成图像样式。一旦进入创建目录的管理页面(例如 admin/config),就会正确生成图像样式。重新启动服务器导致错误再次出现,但事后才意识到,很难重现。
    • 使用 PHP-FPM 时,请记住检查 php-fpm.service 单元中的 PrivateTmp 标志,而不是 Httpd 或 NGINX 标志。
    • 虽然没有解释原始问题中的“没有这样的文件或目录”错误
    • 这个问题怎么也一样。 OP 说他不能写信 /tmp 而你显然写信 /tmp 就好了。由于 PrivateTmp 设置,它只是映射到不同的文件夹。在我看来,这是一个完全不同的问题!
    【解决方案4】:

    您的问题可能是由 systemd 和 apache 的组合引起的。这是一个名为 PrivateTmp 的安全功能,显然它是一个选择退出。

    如果你不想要它,你可以像这样禁用它:

    1. 注释掉相应的开关 /etc/systemd/system/multi-user.target.wants/apache2.service: #PrivateTmp=true
    2. 重启systemd:sudo systemctl daemon-reload
    3. 重启apache:sudo systemctl restart apache2

    【讨论】:

    • /etc/systemd/system/multi-user.target.wants/httpd.service 我在 Centos 7 和 Apache 2.4 上。
    • PrivateTmp 不应该破坏您的 PHP 脚本。
    猜你喜欢
    • 2011-07-22
    • 2011-05-01
    • 2010-12-24
    • 1970-01-01
    • 2021-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多