PHP:析构函数vs register_shutdown_function

Mil*_*kov 12 php destructor memory-leaks image-processing

我有一个PHP类,可以动态创建PNG图像并将其发送到浏览器.PHP手册说我需要确保在结束时调用imagedestroy函数来释放内存.现在,如果我没有使用类,我会得到一些像这样的代码:

function shutdown_func() 
{
    global $img;
    if ($img)
        imagedestroy($img);
}
register_shutdown_function("shutdown_func");
Run Code Online (Sandbox Code Playgroud)

但是,我认为我班级的适当位置是在类'析构函数中调用imagedestroy.

我没有发现析构函数是否以与关闭函数相同的方式调用?例如,如果用户在浏览器中按下STOP按钮,则执行停止.

注意:无论您在答案中写什么,请指向支持它的一些文章或手册页(URL).

Mil*_*kov 13

我刚用Apache测试过,PHP用作Apache模块.我创建了一个无限循环,如下所示:

<?php
class X
{
    function __destruct()
    {
        $fp = fopen("/var/www/htdocs/dtor.txt", "w+");
        fputs($fp, "Destroyed\n");
        fclose($fp);
    }
};

$obj = new X();
while (true) {
    // do nothing
}
?>
Run Code Online (Sandbox Code Playgroud)

这是我发现的:

  • 在Firefox中按STOP按钮不会停止此脚本
  • 如果我关闭Apache,析构函数不会被调用
  • 它在达到PHP max_execution_time时停止,并且不会调用destuctor

但是,这样做:

<?php
function shutdown_func() {
    $fp = fopen("/var/www/htdocs/dtor.txt", "w+");
    fputs($fp, "Destroyed2\n");
    fclose($fp);
}
register_shutdown_function("shutdown_func");

while (true) {
    // do nothing
}
?>
Run Code Online (Sandbox Code Playgroud)

shutdown_func被调用.所以这意味着类destuctor不如关闭函数那么好.