在与systemd

时间:2016-07-16 20:01:49

标签: php fopen systemd temp

我尝试使用fopen(“name”,“a”)创建一个跟踪文件并写入它,但是虽然fopen成功,并返回一个句柄,并且所有的fwrite调用都成功,我找不到该文件文件名参数指定的位置为f​​open。

$trace      = fopen("/var/tmp/billing.log", "a");
if ($trace)
    echo "opened /var/tmp/billing.log<br>\n";
else
    echo "unable to open /var/tmp/billing.log<br>\n";
...
fwrite($trace, __FILE__ . ': ' . __LINE__ . "ce(" .
    "\$aid=$aid, " .
    "\$level=$level, " .
    "\$id=$id, " .
    "\$mode=$mode, " .
    "\$nocache=$nocache)\n");
echo __FILE__ . ': ' . __LINE__ . "ce(" .
    "\$aid=$aid, " .
    "\$level=$level, " .
    "\$id=$id, " .
    "\$mode=$mode, " .
    "\$nocache=$nocache)<br>\n";

表示已返回句柄的回显显示,每次调用fwrite后立即显示回声,但请求的文件/var/tmp/billing.log 不存在。像往常一样/ var / tmp是:

drwxrwxrwt. 35 root root 4096 Jul 15 20:06 tmp

因此允许写入目录。我通过手动创建文件来测试这个:

cat > /var/tmp/test

这似乎是使用systemd的系统上PHP的文档记录或解释不足的功能。而不是创建我指定PHP的文件,而是在私有目录中创建文件的另一层!

$ cd /var/tmp
$ sudo find -name *.log
[sudo] password for jcobban: 
./systemd-private-DGOkBT/tmp/recur-billing.log
./systemd-private-DGOkBT/tmp/process-registration.log
./systemd-private-uEF6lO/tmp/recur-billing.log
./systemd-private-uEF6lO/tmp/billing.log
./systemd-private-uEF6lO/tmp/process-registration.log
$ ls systemd-private-uEF6lO/
ls: cannot open directory systemd-private-uEF6lO/: Permission denied

观察我必须使用sudo甚至查看该文件,因为我没有使用PHP进程的用户标识运行。这是PHP决定使用systemd的私有临时目录服务的结果。 PHP文档中似乎没有描述此操作。如果你调用函数sys_get_temp_dir,它甚至会对临时文件的位置进行调整。请注意,使用私有临时目录的决定会影响PHP脚本本身,因为临时文件名始终是映射的。从脚本的角度来看,文件位于程序指定的位置。那是fopen(“/ var / tmp / billing.log”,“r”);将读取该文件。问题仅在于临时文件的外部可见性。我没有检查,但我怀疑在Windows PHP上映射/ tmp和/ var / tmp到Windows临时目录C:\ Windows \ Temp \以便于移植。

这是一个痛苦,因为为了使这些跟踪文件可见以进行外部分析,我现在必须定义和管理我自己的目录以放入跟踪文件,这一操作很复杂,因为在我的网站上'DOCUMENT_ROOT'不是有效路径所以我必须弄清楚文档根目录的真实路径是什么。

$document_root  = substr(__FILE__, 0, -strlen($_SERVER['PHP_SELF']));
$trace      = fopen($document_root . "/log/billing.log", "a");

1 个答案:

答案 0 :(得分:1)

实际上这是 systemd 安全功能:PrivateTmp

您可以针对特定的 httpd 服务禁用它。在Arch Linux上:

juergen@samson:/tmp → grep PrivateTmp /usr/lib/systemd/system/httpd.service 
PrivateTmp=true