亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > PHP > 正文

php中__destruct與register_shutdown_function執行的先后順序問題

2024-05-04 23:26:10
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了php中__destruct與register_shutdown_function執行的先后順序問題,需要的朋友可以參考下
 
 

根據php手冊的解析。

__destruct是

析構函數會在到某個對象的所有引用都被刪除或者當對象被顯式銷毀時執行。

register_shutdown_function

Registers a callback to be executed after script execution finishes or exit() is called. 注冊一個回調函數,此函數在腳本運行完畢或調用exit()時執行。

從字面上理解,__destruct是對象層面的,而register_shutdown_function是整個腳本層面的,理應register_shutdown_function的級別更高,其所注冊的函數也應最后執行。為證實我們的猜測,我們寫一段腳本:

 

復制代碼代碼如下:

register_shutdown_function(function(){echo 'global';});
    class A {
        public function __construct(){
        }
        public function __destruct()
        {
            echo __class__,'::',__function__,'<br/>';
        }
    }
    new A;

 

執行結果:

 

復制代碼代碼如下:

A::__destruct 
global

 

完全證實了我們的猜測,它按照對象->腳本的順序被執行了。

但如果我們在對象中注冊了register_shutdown_function呢?它還是一樣的順序嗎?!

 

復制代碼代碼如下:

class A {
        public function __construct(){
            register_shutdown_function(function(){echo 'local', '<br/>';});
        }
        public function __destruct()
        {
            echo __class__,'::',__function__,'<br/>';
        }
    }
    new A;

 

結果:

 

復制代碼代碼如下:

local 
A::__destruct

 

可以看到register_shutdown_function先被調用了,最后才是執行對象的__destruct。這表明register_shutdown_function注冊的函數被當作類中的一個方法?!不得而知,這可能需要查看php源代碼才能解析了。

我們可以擴大范圍查看情況:

 

復制代碼代碼如下:

register_shutdown_function(function(){echo 'global', '<br/>';});
    class A {
        public function __construct(){
            register_shutdown_function(array($this, 'op'));
        }
        public function __destruct()
        {
            echo __class__,'::',__function__,'<br/>';
        }
        public function op()
        {
            echo __class__,'::',__function__,'<br/>';
        }
    }
    class B {
        public function __construct()
        {
            register_shutdown_function(array($this, 'op'));
            $obj = new A;
        }
        public function __destruct()
        {
            echo __class__,'::',__function__,'<br/>';
        }
        public function op()
        {
            echo __class__,'::',__function__,'<br/>';
        }
    }
    $b = new B;

 

我們在全局注冊一個register_shutdown_function函數,在類AB中又各注冊了一個,而且類中分別還有析構方法。最后運行結果會怎樣呢?

 

復制代碼代碼如下:

global 
B::op 
A::op 
A::__destruct 
B::__destruct

 

結果完全顛覆了我們的想像,register_shutdown_function函數無論在類中注冊還是在全局注冊,它都是先被執行,類中執行的順序就是它們被注冊的先后順序。如果我們再仔細研究,全局的register_shutdown_function函數無論放在前面還是后面都是這個結果,事情似乎有了結果,那就是register_shutdown_function比__destruct先執行,全局的register_shutdown_function函數又先于類中注冊的register_shutdown_function先執行。

且慢,我無法接受這個結果,按照這樣的結論,難道說腳本已經結束后還可以再執行__destruct?!因此,我還要繼續驗證這個結論---去掉類中注冊register_shutdown_function,而保留全局register_shutdown_function:

 

復制代碼代碼如下:

class A {
        public function __destruct()
        {
            echo __class__,'::',__function__,'<br/>';
        }
    }
    class B {
        public function __construct()
        {
            $obj = new A;
        }
        public function __destruct()
        {
            echo __class__,'::',__function__,'<br/>';
        }
    }
    register_shutdown_function(function(){echo 'global', '<br/>';});

 

輸出:

 

復制代碼代碼如下:

A::__destruct 
global 
B::__destruct

 

結果令人茫然,A、B兩個類的析構函數執行順序無可質疑,因為B中調用了A,類A肯定比B先銷毀,但全局的register_shutdown_function函數又怎么夾在它們中間被執行?!費解。

按照手冊的解析,析構函數也可在調用exit時執行。

析構函數即使在使用 exit()終止腳本運行時也會被調用。在析構函數中調用 exit() 將會中止其余關閉操作的運行。

如果在函數中調用exit,它們又如何被調用的呢?

 

復制代碼代碼如下:

class A {
        public function __construct(){
            register_shutdown_function(array($this, 'op'));
            exit;
        }
        public function __destruct()
        {
            echo __class__,'::',__function__,'<br/>';
        }
        public function op()
        {
            echo __class__,'::',__function__,'<br/>';
        }
    }
    class B {
        public function __construct()
        {
            register_shutdown_function(array($this, 'op'));
            $obj = new A;
        }
        public function __destruct()
        {
            echo __class__,'::',__function__,'<br/>';
        }
        public function op()
        {
            echo __class__,'::',__function__,'<br/>';
        }
    }
    register_shutdown_function(function(){echo 'global', '<br/>';});
    $b = new B;

 

輸出:

 

復制代碼代碼如下:

global 
B::op 
A::op 
B::__destruct 
A::__destruct

 

這個順序與上述第三個例子相似,不同的且令人不可思議的是B類的析構函數先于類A執行,難道銷毀B后類A的所有引用才被全部銷毀?!不得而知。

結論:
1、盡量不要在腳本中將register_shutdown_function與__destruct混搭使用,它們的行為完全不可預測。
1、因為對象在相互引用,因此我們無法測知對象幾時被銷毀,當需要按順序輸出內容時,不應把內容放在析構函數__destruct里;
2、盡量不要在類中注冊register_shutdown_function,因為它的順序難以預測(只有調用這個對象時才會注冊函數),而且__destruct完全可以代替register_shutdown_function;
3、如果需要在腳本退出時執行相關動作,最好在腳本開始時注冊register_shutdown_function,并把所有動作放在一個函數里。
敬請大家指正。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产欧美精品在线播放| 中文字幕亚洲欧美在线| 久久久久免费精品国产| 亚洲精品久久7777777| 精品国产乱码久久久久酒店| 中文亚洲视频在线| 成人免费午夜电影| 亚洲色图17p| 欧美二区在线播放| 深夜福利一区二区| 欧美一区二区.| 成人午夜在线视频一区| 91精品国产91久久久久久最新| 欧美网站在线观看| 国产精品福利网| 日韩视频免费在线观看| 亚洲自拍偷拍色片视频| 成人性教育视频在线观看| 亚洲一区中文字幕在线观看| 国产午夜一区二区| 亚洲无av在线中文字幕| 疯狂做受xxxx高潮欧美日本| 日韩中文字幕视频在线观看| 欧美性猛交丰臀xxxxx网站| 国产97在线|日韩| 欧美激情小视频| 日韩精品视频在线观看免费| 国产精品美女网站| 亚洲第一中文字幕在线观看| 国产午夜精品理论片a级探花| 中文字幕欧美专区| 亚洲自拍偷拍色图| 亚洲色图校园春色| 国产中文字幕日韩| 中文综合在线观看| 91av在线国产| 亚洲最新av在线| 91视频免费网站| 欧美做受高潮1| 亚洲精品一区二区在线| 91日本在线观看| 亚洲国产精品久久久久秋霞不卡| 日本精品视频在线播放| 欧美一区三区三区高中清蜜桃| 2019中文字幕在线观看| 久久精品中文字幕一区| 久久久久久久久中文字幕| 精品自在线视频| 亚洲精品视频免费在线观看| 国产在线a不卡| 欧美高清自拍一区| 高跟丝袜欧美一区| 一区二区三区无码高清视频| 成人免费淫片视频软件| 在线日韩中文字幕| 97精品一区二区视频在线观看| 97av视频在线| 高清日韩电视剧大全免费播放在线观看| 久久免费视频在线观看| 欧美高清一级大片| 欧美精品久久久久久久| 97在线看免费观看视频在线观看| 欧美亚洲另类激情另类| 亚洲男女性事视频| 日本免费一区二区三区视频观看| 久久在线免费观看视频| 欧美高清理论片| 日韩精品在线视频| 热久久免费国产视频| 久久久久久999| 精品久久在线播放| 国产精品福利无圣光在线一区| 国产精品免费小视频| 91精品综合久久久久久五月天| 91成人在线播放| 97久久精品人人澡人人爽缅北| 日韩欧美中文字幕在线观看| 亚洲精品国产美女| 国产成人av在线| 欧美日韩一区二区免费视频| 91香蕉亚洲精品| 亚洲精品一区av在线播放| 欧美性猛交xxxx久久久| 欧美极品少妇xxxxⅹ裸体艺术| 亚洲精品欧美日韩专区| 久久久亚洲成人| 久久久久久这里只有精品| 久久最新资源网| 日韩免费观看av| 亚洲女成人图区| 国产精品久久77777| 欧美与欧洲交xxxx免费观看| 成人xvideos免费视频| 日韩中文字幕在线播放| 日韩激情片免费| 久青草国产97香蕉在线视频| 亚洲黄色在线看| 美日韩在线视频| 国产一区二区久久精品| 永久免费精品影视网站| 九九九热精品免费视频观看网站| 久久91亚洲人成电影网站| 成人欧美在线观看| 91亚洲人电影| 成人日韩在线电影| 91av国产在线| 两个人的视频www国产精品| 精品视频在线播放色网色视频| 91精品国产网站| 亚洲欧美激情四射在线日| 欧美性视频在线| 亚洲第一中文字幕| 国产精彩精品视频| 国产精品自拍偷拍视频| 亚洲老板91色精品久久| 国产精品美女www爽爽爽视频| 热久久这里只有精品| 国产成人综合一区二区三区| 青青在线视频一区二区三区| 色综合男人天堂| 一区二区在线视频播放| 欧美亚洲激情视频| 亚洲人高潮女人毛茸茸| 亚洲欧美另类国产| 一二美女精品欧洲| 亚洲精品日韩丝袜精品| 51色欧美片视频在线观看| 亚洲精品视频久久| 日本成人精品在线| 欧美视频在线看| 日韩电影在线观看永久视频免费网站| 深夜精品寂寞黄网站在线观看| 日韩人在线观看| 亚洲国产天堂网精品网站| 91av在线国产| www.xxxx精品| 亚洲国产精品免费| 欧美高清视频免费观看| 欧美午夜激情在线| 精品动漫一区二区三区| 91色p视频在线| 欧美日韩国产综合新一区| 中文字幕日本精品| 九九精品在线视频| 欧美精品制服第一页| 色诱女教师一区二区三区| 最近更新的2019中文字幕| 亚洲a一级视频| 91网站在线免费观看| 亚洲国产精品推荐| 色婷婷久久一区二区| 成人黄色av播放免费| 亚洲国产精品人人爽夜夜爽| 国产精品免费一区豆花| 日韩av在线直播| 国产精品自在线| 国产狼人综合免费视频| 久久天天躁狠狠躁夜夜爽蜜月| 欧美另类老肥妇| 中文字幕在线成人| 神马久久桃色视频| 中文字幕日韩在线观看| 日产精品99久久久久久| 2018日韩中文字幕|