Why doesn't PHP 7.2 fopen(/tmp, a) write to the file?

本小妞迷上赌 提交于 2020-01-13 13:13:07

问题


I have an old "PHPDBG" function that lets me "printf" to a text file.

I've had PHPDBG.inc "since forever" (at least since PHP 4.x days), but it doesn't seem to be working in my current configuration (ubuntu18, Apache 2.4.29 and PHP 7.2).

Specifically:

  • I can't open the file ($fp is null) ...
  • /tmp/PHPDBG.txt never gets created (because of the fopen failure)
  • /tmp should be world-writable ... and ...
  • I don't seem to be able to get a PHP error in the Apache error.log, or get anything meaningful from either error_get_last() or $php_errormsg.

Here is the test code:

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

Questions:

Q1: Any idea what might be wrong with $fp = fopen ("/tmp/PHPDBG.txt", "a");?

Q2: What can I do to get a meaningful error message if "fopen()" fails?


Additional info: assuming error_get_last() is returning "1: EPERM 1 /* Operation not permitted */", then I manually created /tmp/PHPDBG.txt, chmod +rw, and tried "test.php" again. No-go: I got exactly the same results: $fp was null, no meaningful error messages, and /tmp/PHPDBG.txt was unchanged:

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

Additional notes:

  1. Ibu pointed out a stupid typo in the original version of the code I posted. Whoops! It crept in at the last minute, the typo WASN'T the problem. I'm still not able to "fopen()" a file in /tmp and write to it from PHP 7.2. I used to be able to do this in earlier (MUCH earlier!) versions of PHP.

  2. I just double-checked: I AM able to write to the file if it happens to be in the local directory:

    // $fp = fopen ("/tmp/PHPDBG.txt", "a");  // Opens, but fails to write anything
    $fp = fopen ("PHPDBG.txt", "a");  // Works OK
    

Q: Why????

Update

The reason "it used to work" is that systemd was introduced to (newer versions of) Linux, bringing with it "PrivateTmp".

My workaround was to disable this "feature" for Apache/PHP. I edited /etc/systemd/system/multi-user.target.wants/apache2.service as follows:

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

Additional notes are here.


回答1:


Your condition is reversed: if (!$fp).

You are saying if not handle, then write to the file. It should be the opposite.

<?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:


I found the file that didn't seem to be created:

  1. PHP code: $fp = fopen ("/tmp/PHPDBG.txt", "a");

  2. Expected location: /tmp/PHPDBG.txt.

  3. Actual location: /tmp/systemd-private-c6f7629309e647818680f8a6ee1105d6-apache2.service-lGKGc6/tmp/PHPDBG.txt

Relevant links:

  • Php has its own /tmp in /tmp/systemd-private-nABCDE/tmp when accessed through nginx

  • Why PHP cannot see /tmp

So it sounds like this is some kind of systemd "feature" (Grrr!!!!). Which explains why it "used to work" (in previous versions of Apache, PHP and Linux).

Workaround

I edited /etc/systemd/system/multi-user.target.wants/apache2.service:

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


来源:https://stackoverflow.com/questions/55014399/why-doesnt-php-7-2-fopen-tmp-a-write-to-the-file

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!