我有一个旧的“PHPDBG”函数,可以让我“printf”到文本文件。
我“从永远”开始使用PHPDBG.inc(至少从 PHP 4.x 时代起),但它似乎无法在我当前的配置(ubuntu18、Apache 2.4.29 和 PHP 7.2)中工作。
具体来说:
error_get_last()内容$php_errormsg。这是测试代码:
测试.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');
?>
Run Code Online (Sandbox Code Playgroud)
问题:
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
Run Code Online (Sandbox Code Playgroud)
补充笔记:
Ibu 指出了我发布的代码的原始版本中的一个愚蠢的拼写错误。哎呀!它是在最后一刻悄悄出现的,打字错误不是问题所在。我仍然无法在 /tmp 中“fopen()”文件并从 PHP 7.2 写入该文件。我曾经能够在早期(非常早期!)版本的 PHP 中做到这一点。
我刚刚仔细检查过:如果该文件恰好位于本地目录中,我就能够写入该文件:
// $fp = fopen ("/tmp/PHPDBG.txt", "a"); // Opens, but fails to write anything
$fp = fopen ("PHPDBG.txt", "a"); // Works OK
Run Code Online (Sandbox Code Playgroud)更新
“它曾经有效”的原因是 systemd 被引入(较新版本的)Linux,并带来了“PrivateTmp”。
我的解决方法是禁用Apache/PHP 的此“功能”。我编辑/etc/systemd/system/multi-user.target.wants/apache2.service如下:
[Service]
...
PrivateTmp=true <-- Changed this to "false"
Run Code Online (Sandbox Code Playgroud)
附加说明请参见此处。
我发现似乎没有创建的文件:
PHP代码:$fp = fopen ("/tmp/PHPDBG.txt", "a");
预计地点:/tmp/PHPDBG.txt.
实际位置:/tmp/systemd-private-c6f7629309e647818680f8a6ee1105d6-apache2.service-lGKGc6/tmp/PHPDBG.txt
相关链接:
所以听起来这是某种 systemd“功能”(咕噜!!!)。这解释了为什么它“曾经有效”(在 Apache、PHP 和 Linux 的早期版本中)。
解决方法
我编辑/etc/systemd/system/multi-user.target.wants/apache2.service:
[Service]
...
PrivateTmp=true <-- Changed this to "false"
Run Code Online (Sandbox Code Playgroud)