register_shutdown_function()和__destruct()触发时机及顺序探讨

发布于2017-04-13 | 16337 阅读 | 1 喜欢 | php destruct

触发时机

register_shutdown_function()触发时机

  1. 当页面因异常或错误意外终止时
  2. 当PHP脚本运行超时时
  3. 当PHP脚本执行完成时(此时内存还没有自动释放)

__destruct()触发时机

  1. 对象的所有引用都被删除时
  2. 对象被显式销毁时
  3. 页面加载完成时(此时内存已经被GC机制自动释放,所有实例化的类自然也被销毁,最后实例化的类先销毁,最先实例化的类最后被销毁)

触发顺序

PHP类实例化的对象未被显式销毁或该对象的引用未被全部删除时,先执行register_shutdown_function(),后执行__destruct()

示例一:

register_shutdown_function(function(){echo '页面加载完了'.'<br>';});

class GC {
    public  function __construct(){
        echo __class__.'类被初始化了'.'<br>';
    }

    public  function test(){
        echo __function__.'方法被执行了'.'<br>';
    }
    public  function __destruct()
    {
        echo __class__.'类被销毁了<br/>';
    }
}

$GC = new GC;

$GC->test();

echo '其他操作'.'<br>';

执行结果为

GC类被初始化了
test方法被执行了
其他操作
页面加载完了
GC类被销毁了

示例二:

register_shutdown_function(function(){echo '页面加载完了'.'<br>';});

class GC {
    public  function __construct(){
        echo __class__.'类被初始化了'.'<br>';
    }

    public  function test(){
        echo __function__.'方法被执行了'.'<br>';
    }
    public  function __destruct()
    {
        echo __class__.'类被销毁了<br/>';
    }
}

$GC1 = new GC;

$GC2 = new GC;

$GC1 = null;

echo '其他操作'.'<br>';

执行结果为

GC类被初始化了
GC类被初始化了
GC类被销毁了
其他操作
页面加载完了
GC类被销毁了

PHP类实例化的对象被显式销毁(类被赋值或null或被unset)或该对象所有的引用都被删除时,先执行register_shutdown_function(),后执行__destruct() 示例一:

register_shutdown_function(function(){echo '页面加载完了'.'<br>';});

class GC {
    public  function __construct(){
        echo __class__.'类被初始化了'.'<br>';
    }

    public  function test(){
        echo __function__.'方法被执行了'.'<br>';
    }
    public  function __destruct()
    {
        echo __class__.'类被销毁了<br/>';
    }
}

$GC = new GC;

$GC->test();

$GC = null;

echo '其他操作'.'<br>';

执行结果为

GC类被初始化了
test方法被执行了
GC类被销毁了
其他操作
页面加载完了

示例二:

register_shutdown_function(function(){echo '页面加载完了'.'<br>';});

class GC {
    public  function __construct(){
        echo __class__.'类被初始化了'.'<br>';
    }

    public  function test(){
        echo __function__.'方法被执行了'.'<br>';
    }
    public  function __destruct()
    {
        echo __class__.'类被销毁了<br/>';
    }
}

$GC1 = new GC;

$GC2 = new GC;


$GC1 = null;
$GC2 = null;

echo '其他操作'.'<br>';

执行结果为

GC类被初始化了
GC类被初始化了
GC类被销毁了
GC类被销毁了
其他操作
页面加载完了