


php中__destruct与register_shutdown_function执行的先后顺序问题,destruct_PHP教程
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,并把所有动作放在一个函数里。
敬请大家指正。
析构函数是在对象销毁时调用的代码。
当这个对象用完之后,会自动执行这个函数中的语句。
把数据库关闭的代码放在这里。就是在对象被销毁的时候顺便把数据库连接关闭了。
可以做些操作的,比如关闭文件,关闭数据库等等。比如word程序就很傻,打开文件自己不会关的,你运行几次,然后打开任务管理器就可以看到,好多word在进程里,你必须自己手动关掉。

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Mit dem Linux-Befehl „shutdown“ kann der Computer sofort heruntergefahren werden. Der Root-Benutzer muss lediglich den Befehl „shutdown -h now“ ausführen. Der Shutdown-Befehl kann verwendet werden, um den Shutdown-Vorgang durchzuführen und vor dem Herunterfahren Nachrichten an alle von Benutzern ausgeführten Programme zu senden. Der Shutdown-Befehl erfordert die Verwendung durch den Systemadministrator-Root-Benutzer.

Funktion bedeutet Funktion. Es handelt sich um einen wiederverwendbaren Codeblock mit bestimmten Funktionen. Er kann Eingabeparameter akzeptieren, bestimmte Operationen ausführen und Ergebnisse zurückgeben. Code, um die Wiederverwendbarkeit und Wartbarkeit des Codes zu verbessern.

In einer geschäftigen Welt möchten wir Dinge automatisieren, die Sie regelmäßig oder zeitnah auslösen möchten. Automatisierung hilft bei der Steuerung von Aufgaben und reduziert Ihren Aufwand bei deren Ausführung. Eine dieser Aufgaben könnte darin bestehen, Ihren Computer herunterzufahren. Möglicherweise möchten Sie, dass Ihr Computer regelmäßig heruntergefahren wird, oder Sie möchten, dass er zu einer bestimmten Tageszeit oder an bestimmten Wochentagen herunterfährt, oder Sie möchten, dass er auf einmal herunterfährt. Sehen wir uns an, wie Sie einen Timer einstellen, damit das System automatisch herunterfährt. Methode 1: Verwenden Sie das Dialogfeld „Ausführen“. Schritt 1: Drücken Sie Win+R, geben Sie „shutdown-s-t600“ ein und klicken Sie auf „OK“. Hinweis: Im obigen Befehl steht 600 für die Zeit in Sekunden. Sie können es nach Bedarf ändern. Es sollte immer in Sekunden angegeben werden, nicht in Minuten oder Stunden

MySQL ist ein häufig verwendetes relationales Datenbankverwaltungssystem, das in verschiedenen Websites und Anwendungen weit verbreitet ist. Bei der Verwendung von MySQL können jedoch verschiedene Probleme auftreten, darunter das unerwartete Schließen von MySQL. In diesem Artikel besprechen wir die Behebung von MySQL-Fehlern und stellen einige spezifische Codebeispiele bereit. Wenn MySQL unerwartet heruntergefahren wird, sollten wir zuerst das MySQL-Fehlerprotokoll überprüfen, um den Grund für das Herunterfahren zu verstehen. Normalerweise befindet sich das MySQL-Fehlerprotokoll im MySQL-Installationsverzeichnis.

Was ist der Befehl zum geplanten Herunterfahren von Linux? Wenn wir ein Linux-System verwenden, müssen wir häufig ein Herunterfahren planen, z. B. das automatische Herunterfahren nach dem Herunterladen einer großen Anzahl von Dateien oder das automatische Herunterfahren des Servers, wenn er nicht mehr verwendet wird. In Linux-Systemen kann das geplante Herunterfahren mit dem Befehl „shutdown“ implementiert werden. Mit dem Befehl „shutdown“ kann der Benutzer das System herunterfahren oder neu starten und eine Verzögerungszeit festlegen. Durch das Hinzufügen von Parametern zum Befehl können Sie die Funktion zum geplanten Herunterfahren implementieren. Das Grundformat des Befehls lautet wie folgt: Herunterfahren

Destruktoren sind im C++-Polymorphismus von entscheidender Bedeutung und stellen sicher, dass abgeleitete Klassenobjekte den Speicher ordnungsgemäß bereinigen, wenn sie zerstört werden. Polymorphismus ermöglicht es Objekten unterschiedlichen Typs, auf denselben Methodenaufruf zu reagieren. Der Destruktor wird automatisch aufgerufen, wenn ein Objekt zerstört wird, um seinen Speicher freizugeben. Der abgeleitete Klassendestruktor ruft den Basisklassendestruktor auf, um sicherzustellen, dass der Basisklassenspeicher freigegeben wird.

In diesem Artikel lernen wir die Funktion enumerate() und den Zweck der Funktion „enumerate()“ in Python kennen. Was ist die Funktion enumerate()? Die Funktion enumerate() von Python akzeptiert eine Datensammlung als Parameter und gibt ein Aufzählungsobjekt zurück. Aufzählungsobjekte werden als Schlüssel-Wert-Paare zurückgegeben. Der Schlüssel ist der Index, der jedem Element entspricht, und der Wert sind die Elemente. Syntax enumerate(iterable,start) Parameter iterable – Die übergebene Datensammlung kann als Aufzählungsobjekt namens iterablestart zurückgegeben werden – Wie der Name schon sagt, wird der Startindex des Aufzählungsobjekts durch start definiert. wenn wir es ignorieren

Detaillierte Erläuterung der Rolle und Funktion der MySQL.proc-Tabelle. MySQL ist ein beliebtes relationales Datenbankverwaltungssystem. Wenn Entwickler MySQL verwenden, müssen sie häufig gespeicherte Prozeduren erstellen und verwalten. Die MySQL.proc-Tabelle ist eine sehr wichtige Systemtabelle. Sie speichert Informationen zu allen gespeicherten Prozeduren in der Datenbank, einschließlich des Namens, der Definition, der Parameter usw. der gespeicherten Prozeduren. In diesem Artikel erklären wir ausführlich die Rolle und Funktionalität der MySQL.proc-Tabelle
