Почему PHP 7.2 fopen (/ tmp, a) не записывает в файл? - PullRequest
2 голосов
/ 06 марта 2019

У меня есть старая функция "PHPDBG", которая позволяет мне "printf" в текстовый файл.

У меня был PHPDBG.inc"с тех пор навсегда" (по крайней мере, начиная с дней PHP 4.x), но, похоже, он не работает в моей текущей конфигурации (ubuntu18, Apache 2.4. 29 и PHP 7.2).

В частности:

  • Я не могу открыть файл ($ fp равен нулю) ...
  • / tmp / PHPDBG.txt никогда не создается (из-за ошибки fopen)
  • / tmp должен быть доступен для записи во всем мире ... и ...
  • Кажется, я не могу получить ошибку PHP в файле Apache error.log или получить что-либо значимое из 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 был нулевым, значимых сообщений об ошибках и /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. Ибу указал на глупую опечатку в исходной версии кода, который я разместил. Упс! Он закрался в последнюю минуту, опечатка НЕ проблема. Я до сих пор не могу "fopen ()" файл в / tmp и писать в него из PHP 7.2. Раньше я мог делать это в более ранних (НАМНОГО раньше!) Версиях PHP.

  2. Я просто дважды проверил: я AM могу записать в файл, если он находится в локальном каталоге:

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

Q: Почему ????

Обновление

Причина, по которой он "работал", заключается в том, что systemd был введен в (более новые версии) Linux с "PrivateTmp".

Мой обходной путь - отключение этой "функции" для Apache / PHP. Я отредактировал /etc/systemd/system/multi-user.target.wants/apache2.service следующим образом:

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

Дополнительные примечания здесь .

Ответы [ 2 ]

3 голосов
/ 06 марта 2019

Ваше состояние полностью изменено: 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 голосов
/ 06 марта 2019

Я нашел файл, который, похоже, не был создан:

  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"
...