目錄
php中__destruct与register_shutdown_function执行的先后顺序问题,destruct
对于php析构函数__destruct()的问题
PHP中的__destruct()析构函数是一个空方法,还是会执行什功可以?
首頁 後端開發 php教程 php中__destruct与register_shutdown_function执行的先后顺序问题,destruct_PHP教程

php中__destruct与register_shutdown_function执行的先后顺序问题,destruct_PHP教程

Jul 13, 2016 am 10:16 AM
function shutdown 析構函數

php中__destruct与register_shutdown_function执行的先后顺序问题,destruct

根据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__,'
';
        }
    }
    new A;

执行结果:

复制代码 代码如下:

A::__destruct
global

完全证实了我们的猜测,它按照对象->脚本的顺序被执行了。

但如果我们在对象中注册了register_shutdown_function呢?它还是一样的顺序吗?!

复制代码 代码如下:

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

结果:

复制代码 代码如下:

local
A::__destruct

可以看到register_shutdown_function先被调用了,最后才是执行对象的__destruct。这表明register_shutdown_function注册的函数被当作类中的一个方法?!不得而知,这可能需要查看php源代码才能解析了。

我们可以扩大范围查看情况:

复制代码 代码如下:

register_shutdown_function(function(){echo 'global', '
';});
    class A {
        public function __construct(){
            register_shutdown_function(array($this, 'op'));
        }
        public function __destruct()
        {
            echo __class__,'::',__function__,'
';
        }
        public function op()
        {
            echo __class__,'::',__function__,'
';
        }
    }
    class B {
        public function __construct()
        {
            register_shutdown_function(array($this, 'op'));
            $obj = new A;
        }
        public function __destruct()
        {
            echo __class__,'::',__function__,'
';
        }
        public function op()
        {
            echo __class__,'::',__function__,'
';
        }
    }
    $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__,'
';
        }
    }
    class B {
        public function __construct()
        {
            $obj = new A;
        }
        public function __destruct()
        {
            echo __class__,'::',__function__,'
';
        }
    }
    register_shutdown_function(function(){echo 'global', '
';});

输出:

复制代码 代码如下:

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__,'
';
        }
        public function op()
        {
            echo __class__,'::',__function__,'
';
        }
    }
    class B {
        public function __construct()
        {
            register_shutdown_function(array($this, 'op'));
            $obj = new A;
        }
        public function __destruct()
        {
            echo __class__,'::',__function__,'
';
        }
        public function op()
        {
            echo __class__,'::',__function__,'
';
        }
    }
    register_shutdown_function(function(){echo 'global', '
';});
    $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,并把所有动作放在一个函数里。
敬请大家指正。

对于php析构函数__destruct()的问题

析构函数是在对象销毁时调用的代码。
当这个对象用完之后,会自动执行这个函数中的语句。
把数据库关闭的代码放在这里。就是在对象被销毁的时候顺便把数据库连接关闭了。
 

PHP中的__destruct()析构函数是一个空方法,还是会执行什功可以?

可以做些操作的,比如关闭文件,关闭数据库等等。比如word程序就很傻,打开文件自己不会关的,你运行几次,然后打开任务管理器就可以看到,好多word在进程里,你必须自己手动关掉。
 

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/895116.htmlTechArticlephp中__destruct与register_shutdown_function执行的先后顺序问题,destruct 根据php手册的解析。 __destruct是 析构函数会在到某个对象的所有引用都被删...
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

linux關機指令shutdown可以實現立刻關機嗎 linux關機指令shutdown可以實現立刻關機嗎 Jan 28, 2023 pm 05:26 PM

linux關機指令shutdown可以實現立刻關機,只需要root使用者執行「shutdown -h now」指令即可。 shutdown指令可以用來進行關機程序,並且在關機以前傳送訊息給所有使用者正在執行的程序,shutdown指令需要係統管理者root使用者來使用。

function是什麼意思 function是什麼意思 Aug 04, 2023 am 10:33 AM

function是函數的意思,是一段具有特定功能的可重複使用的程式碼區塊,是程式的基本組成單元之一,可以接受輸入參數,執行特定的操作,並傳回結果,其目的是封裝一段可重複使用的程式碼,提高程式碼的可重複使用性和可維護性。

在 Windows 10 / 11 中設定自動關機的 3 種方法 在 Windows 10 / 11 中設定自動關機的 3 種方法 May 01, 2023 pm 10:40 PM

在繁忙的世界中,我們希望自動化一些您希望定期或及時觸發的事情。自動化有助於控制任務並減少您執行任務的努力。其中一項任務可能是關閉您的電腦。您可能希望您的電腦定期關閉,或者您希望它在一天中的特定時間關閉,或在一周中的特定日子關閉,或者您想要關閉一次。讓我們看看如何設定計時器,以便系統自動關閉。方法一:使用執行對話方塊步驟1:按Win+R,鍵入shutdown-s-t600並點選OK。注意:在上面的命令中,600表示以秒為單位的時間。您可以根據需要更改它。它應該始終以秒為單位,而不是幾分鐘或幾小

如何在Linux中設定定時關機指令 如何在Linux中設定定時關機指令 Feb 18, 2024 pm 11:55 PM

Linux定時關機命令是什麼在使用Linux系統時,我們經常需要定時關機,例如在下載大量文件後自動關機,或者在伺服器不再使用時自動關閉等。在Linux系統中,定時關機可以使用「shutdown」指令來實作。 「shutdown」指令允許使用者將系統關閉或重新啟動,並設定一個延遲時間。透過在命令中新增參數,可以實現定時關機的功能。指令的基本格式如下:shutdow

MySQL shutdown unexpectedly - 如何解決MySQL報錯:MySQL意外關閉 MySQL shutdown unexpectedly - 如何解決MySQL報錯:MySQL意外關閉 Oct 05, 2023 pm 02:42 PM

MySQL是一款常用的關聯式資料庫管理系統,廣泛應用於各種網站和應用程式。然而,使用MySQL時可能會遇到各種問題,其中之一就是MySQL意外關閉。在這篇文章中,我們將討論如何解決MySQL報錯的問題,並提供一些具體的程式碼範例。當MySQL意外關閉時,我們首先應該查看MySQL的錯誤日誌,以了解關閉的原因。通常,MySQL的錯誤日誌位於MySQL安裝目錄的da

C++ 中析構函式在多態性中扮演什麼角色? C++ 中析構函式在多態性中扮演什麼角色? Jun 03, 2024 pm 08:30 PM

析構函數在C++多態性中至關重要,它確保衍生類別物件在銷毀時正確清理記憶體。多態性允許不同類型的物件回應相同方法呼叫。析構函數在物件銷毀時自動調用,釋放其記憶體。衍生類別析構函數呼叫基底類別析構函數,確保釋放基底類別記憶體。

'enumerate()'函數在Python中的用途是什麼? 'enumerate()'函數在Python中的用途是什麼? Sep 01, 2023 am 11:29 AM

在本文中,我們將了解enumerate()函數以及Python中「enumerate()」函數的用途。什麼是enumerate()函數? Python的enumerate()函數接受資料集合作為參數並傳回一個枚舉物件。枚舉物件以鍵值對的形式傳回。 key是每個item對應的索引,value是items。語法enumerate(iterable,start)參數iterable-傳入的資料集合可以作為枚舉物件傳回,稱為iterablestart-顧名思義,枚舉物件的起始索引由start定義。如果我們忽

MySQL.proc表的作用與功能詳解 MySQL.proc表的作用與功能詳解 Mar 16, 2024 am 09:03 AM

MySQL.proc表的功能與功能詳解MySQL是一種流行的關係型資料庫管理系統,開發者在使用MySQL時常常會涉及到預存程序(StoredProcedure)的建立與管理。而MySQL.proc表則是一個非常重要的系統表,它儲存了資料庫中所有的預存程序的相關信息,包括預存程序的名稱、定義、參數等。在本文中,我們將詳細解釋MySQL.proc表的作用與功能

See all articles