我有一个旧的“PHPDBG”函数,它让我“printf”到一个文本文件。
我已经拥有PHPDBG.inc“永远”(至少从PHP 4.x天开始),但它似乎不适用于我当前的配置(ubuntu18,Apache 2.4.29和PHP 7.2)。
特别:
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
补充说明:
// $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。
你的情况正好相反: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');
?>
我找到了似乎没有创建的文件:
$fp = fopen ("/tmp/PHPDBG.txt", "a");
/tmp/PHPDBG.txt
。/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"