为什么PHP 7.2 fopen(/ tmp,a)没有写入文件?

问题描述 投票:2回答:2

我有一个旧的“PHPDBG”函数,它让我“printf”到一个文本文件。

我已经拥有PHPDBG.inc“永远”(至少从PHP 4.x天开始),但它似乎不适用于我当前的配置(ubuntu18,Apache 2.4.29和PHP 7.2)。

特别:

  • 我无法打开文件($ fp为null)...
  • 永远不会创建/tmp/PHPDBG.txt(因为fopen失败)
  • / tmp应该是世界可写的...并且......
  • 我似乎无法在Apache error.log中获得PHP错误,或从error_get_last()$php_errormsg获得任何有意义的内容。

这是测试代码:

test.php的:

<?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”。不行:我得到完全相同的结果:$ fp为null,没有有意义的错误消息,并且/tmp/PHPDBG.txt未更改:

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()”文件并从PHP 7.2中写入它。我曾经能够在之前的(早期版本)PHP版本中做到这一点。
  2. 我只是仔细检查:我能够写入文件,如果它恰好在本地目录中: // $fp = fopen ("/tmp/PHPDBG.txt", "a"); // Opens, but fails to write anything $fp = fopen ("PHPDBG.txt", "a"); // Works OK

问:为什么????

更新

“它以前工作”的原因是systemd被引入到(较新版本的)Linux中,带来了“PrivateTmp”。

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

[Service]
...
PrivateTmp=true  <-- Changed this to "false"

附加说明是here

php fopen systemd
2个回答
3
投票

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

你是说如果不处理,那么写入文件。应该是相反的。

<?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');
?>

2
投票

我找到了似乎没有创建的文件:

  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

[Service]
...
PrivateTmp=true  <-- Changed this to "false"
© www.soinside.com 2019 - 2024. All rights reserved.