首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么PHP7.2fopen(/tmp,a)不写入文件?

为什么PHP7.2fopen(/tmp,a)不写入文件?
EN

Stack Overflow用户
提问于 2019-03-06 02:01:08
回答 3查看 3.3K关注 0票数 6

我有一个旧的"PHPDBG“函数,它允许我将"printf”转到文本文件中。

我已经“永远”使用了PHPDBG.inc (至少从PHP4.x天开始),但是它在我当前的配置(ubuntu18、Apache2.4.29和PHP7.2)中似乎不起作用。

具体地说:

  • 我无法打开文件($fp为null) .
  • /tmp/PHPDBG.txt从未被创建(因为fopen失败)
  • /tmp应该是可写的.还有..。
  • 我似乎无法在Apache中获得error.log错误,也无法从error_get_last()$php_errormsg获得任何有意义的信息。

下面是测试代码:

test.php:

代码语言:javascript
复制
<?php
  function PHPDBG ($s) {
    $fp = fopen ("/tmp/PHPDBG.txt", "a");
    if ($fp) {
      // Successful open ... but nothing written!
      fputs($fp, $s . "\n");
      fclose($fp);
    } else {
      echo "<h3>FILE OPEN ERROR</h3>\n";
      echo "<p>" . print_r(error_get_last()) . "</p>\n";
      echo "<p>" . $php_errormsg . "</p>\n";
    }
  }

  PHPDBG('>>Hello');
  phpinfo();
  PHPDBG('<<Goodbye');
 ?>

问题:

Q1:知道$fp = fopen ("/tmp/PHPDBG.txt", "a");有什么问题吗?

Q2:如果"fopen()“失败,我能做什么才能得到有意义的错误消息?

附加信息:假设error_get_last()返回"1: EPERM 1 /*操作不允许*/",然后手动创建/tmp/PHPDBG.txt、chmod +rw,并再次尝试"test.php“。No-go:我得到了完全相同的结果:$fp为null,没有有意义的错误消息,/tmp/PHPDBG.txt保持不变:

代码语言:javascript
复制
root@ubuntu18:/tmp# umask 0
root@ubuntu18:/tmp# touch PHPDBG.txt
root@ubuntu18:/tmp# ls -l PHPDBG.txt
-rw-rw-rw- 1 root root 0 Mar  5 18:13 PHPDBG.txt
 <= Re-ran test here... failed exactly like before...
root@ubuntu18:/tmp# ls -l PHPDBG.txt
-rw-rw-rw- 1 root root 0 Mar  5 18:13 PHPDBG.txt

附加注释:

  1. Ibu在我发布的代码的原始版本中指出了一个愚蠢的错误。哇哦!它在最后一刻悄悄地出现了,错误不是问题所在。我仍然无法在/tmp中"fopen()“一个文件并从PHP7.2中写入它。我以前可以在更早的时候(更早)做这件事!PHP的版本。
  2. 我只是重复检查:如果文件恰好位于本地目录中,我就可以写入该文件: // $fp = fopen ("/tmp/PHPDBG.txt","a");//打开,但没有编写任何$fp = fopen ("PHPDBG.txt","a");//工作正常

问:为什么?

更新

“它曾经起作用”的原因是,systemd引入了Linux的更新版本,并带来了"PrivateTmp“。

我的解决办法是禁用Apache/PHP的这个“特性”。我编辑了/etc/systemd/system/multi-user.target.wants/apache2.service如下:

代码语言:javascript
复制
[Service]
...
PrivateTmp=true  <-- Changed this to "false"

附加的注释是here

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-03-06 06:32:10

我发现似乎没有创建的文件:

  1. PHP代码:$fp = fopen ("/tmp/PHPDBG.txt", "a");
  2. 预期位置:/tmp/PHPDBG.txt
  3. 实际位置:/tmp/systemd-private-c6f7629309e647818680f8a6ee1105d6-apache2.service-lGKGc6/tmp/PHPDBG.txt

相关链接:

这听起来像是某种系统的“特性”(Grrr!)。这解释了为什么它“过去工作”(在早期版本的Apache,PHP和Linux)。

解决方案

我编辑了/etc/systemd/system/multi-user.target.wants/apache2.service

代码语言:javascript
复制
[Service]
...
PrivateTmp=true  <-- Changed this to "false"
票数 6
EN

Stack Overflow用户

发布于 2019-03-06 02:29:29

你的情况是相反的:if (!$fp)

您的意思是,如果没有处理,则将其写入文件。应该是相反的。

代码语言:javascript
复制
<?php
  function PHPDBG ($s) {
    $fp = fopen ("/tmp/PHPDBG.txt", "a");
    if ($fp) { // fixed condition.
      fputs($fp, $s . "\n");
      fclose($fp);
    } else {
      echo "<h3>FILE OPEN ERROR</h3>\n";
      echo "<p>" . print_r(error_get_last()) . "</p>\n";
      echo "<p>" . $php_errormsg . "</p>\n";
    }
  }

  PHPDBG('>>Hello');
  phpinfo();
  PHPDBG('<<Goodbye');
?>
票数 3
EN

Stack Overflow用户

发布于 2021-01-16 22:52:40

真正的问题是权限问题。

当创建私有tmp文件时,它只对root具有权限。

httpd的权限应该是httpd,依此类推。

这是一个系统可配置的项目吗?似乎systemd已经解决了一个问题,只是为了防止实际使用,而这个问题是存在的。httpd的/tmp应该是可以由httpd写的,但它不是。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55014399

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档