Things to note about __construct() and __destory() in PHP
Basically all programming languages have the concepts of constructors and destructors in classes. The constructor can be used to do some initialization work when a function instance is created, while the destructor can do some cleanup work before the instance is destroyed. Relatively speaking, we use constructors a lot, while destructors are generally used to release resources, such as database links, file reading and writing handles, etc.
The use of constructors and destructors
Let’s first look at the use of normal constructors and destructors:
class A { public $name; public function __construct($name) { $this->name = $name; echo "A:构造函数被调用,{$this->name}", PHP_EOL; } public function __destruct() { echo "A:析构函数被调用,{$this->name}", PHP_EOL; } } $a = new A('$a'); echo '-----', PHP_EOL; class B extends A { public function __construct($name) { $this->name = $name; parent::__construct($name); echo "B:构造函数被调用,{$this->name}", PHP_EOL; } public function __destruct() { parent::__destruct(); echo "B:析构函数被调用,{$this->name}", PHP_EOL; } } class C extends A { public function __construct($name) { $this->name = $name; echo "C:构造函数被调用,{$this->name}", PHP_EOL; } public function __destruct() { echo "C:析构函数被调用,{$this->name}", PHP_EOL; } } class D extends A { } // unset($a); // $a的析构提前 // $a = null; // $a的析构提前 $b = new B('$b'); $c = new C('$c'); $d = new D('$d'); echo '-----', PHP_EOL;exit; // A:构造函数被调用,$a // ----- // A:构造函数被调用,$b // B:构造函数被调用,$b // C:构造函数被调用,$c // A:构造函数被调用,$d // ----- // A:析构函数被调用,$d // C:析构函数被调用,$c // A:析构函数被调用,$b // B:析构函数被调用,$b // A:析构函数被调用,$a
The above Is there something in the code that is different from what we expected? It’s okay, let’s look at it one by one:
If a subclass overrides the constructor or destructor of the parent class, and if the parent class’s constructor is not explicitly called using parent::__constuct(), then the parent class will The constructor of the class will not be executed. For example, if a C subclass does not override the constructor or destructor, the destructor of the parent class will be called by default. If the variable is not explicitly set to NULL or unset() is used, it will It is called after the script execution is completed. The calling order in the test code is similar to the stack first in last out (C->B->A, C is destructed first), but it is not necessarily the case in the server environment. That is to say, the order is not necessarily fixed
Reference problem of destructor
When the object contains its own mutual references, you want to set it to NULL or unset( ) may cause problems when calling the destructor.
class E { public $name; public $obj; public function __destruct() { echo "E:析构函数被调用," . $this->name, PHP_EOL; echo '-----', PHP_EOL; } } $e1 = new E(); $e1->name = 'e1'; $e2 = new E(); $e2->name = 'e2'; $e1->obj = $e2; $e2->obj = $e1;
Similar to this code, $e1 and $e2 are both objects of class E, and they each hold references to each other. In fact, to put it simply, similar problems will occur if you hold your own references.
$e1 = new E(); $e1->name = 'e1'; $e2 = new E(); $e2->name = 'e2'; $e1->obj = $e2; $e2->obj = $e1; $e1 = null; $e2 = null; // gc_collect_cycles(); $e3 = new E(); $e3->name = 'e3'; $e4 = new E(); $e4->name = 'e4'; $e3->obj = $e4; $e4->obj = $e3; $e3 = null; $e4 = null; echo 'E destory', PHP_EOL;
If we do not turn on the comment on the gc_collect_cycles() line, the order in which the destructor is executed is as follows:
// 不使用gc回收的结果 // E destory // E:析构函数被调用,e1 // ----- // E:析构函数被调用,e2 // ----- // E:析构函数被调用,e3 // ----- // E:析构函数被调用,e4 // -----
If we turn on the comment on gc_collect_cycles(), the destructor's The execution order is:
// 使用gc回收后结果 // E:析构函数被调用,e1 // ----- // E:析构函数被调用,e2 // ----- // E destory // E:析构函数被调用,e3 // ----- // E:析构函数被调用,e4 // -----
It can be seen that PHP must be recycled once using gc, and the destructor of the class will not be executed until all references to the object have been released. If the reference is not released, the destructor will not be executed.
Compatibility issues with low version constructors
Before PHP5, PHP's constructor was a method with the same name as the class name. That is to say, if I have a class F, then the function F(){} method is its constructor. In order to be compatible with lower versions, PHP still retains this feature. After PHP7, if there is a method with the same name as the class name, a timeout warning will be reported, but it will not affect program execution.
class F { public function f() { // Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; F has a deprecated constructor echo "F:这也是构造函数,与类同名,不区分大小写", PHP_EOL; } // function F(){ // // Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; F has a deprecated constructor // echo "F:这也是构造函数,与类同名", PHP_EOL; // } // function __construct(){ // echo "F:这是构造函数,__construct()", PHP_EOL; // } } $f = new F();
If __construc() and a class method with the same name exist at the same time, __construct() will be used first. Another thing to note is that function names are not case-sensitive, so the F() and f() methods are the same and will become constructors. Similarly, because they are not case-sensitive, f() and F() cannot exist at the same time. Of course, we do not recommend using a function with the same name as a constructor. After all, it is an outdated feature and may be canceled one day.
Constructor overloading
PHP does not run method overloading. It only supports rewriting, that is, subclasses override parent class methods, but cannot define multiple methods. Methods with the same name but different parameters. In languages such as Java, overloading methods is very convenient, especially when instantiating a class, to easily implement polymorphic capabilities.
$r1 = new R(); // 默认构造函数 $r2 = new R('arg1'); // 默认构造函数 一个参数的构造函数重载,arg1 $r3 = new R('arg1', 'arg2'); // 默认构造函数 两个参数的构造函数重载,arg1,arg2
Just like the above code, if you try to define multiple __construct(), PHP will tell you directly that it cannot run. So is there any other way to achieve the function of the above code? Of course there is, otherwise we wouldn’t write it.
class R { private $a; private $b; public function __construct() { echo '默认构造函数', PHP_EOL; $argNums = func_num_args(); $args = func_get_args(); if ($argNums == 1) { $this->constructA(...$args); } elseif ($argNums == 2) { $this->constructB(...$args); } } public function constructA($a) { echo '一个参数的构造函数重载,' . $a, PHP_EOL; $this->a = $a; } public function constructB($a, $b) { echo '两个参数的构造函数重载,' . $a . ',' . $b, PHP_EOL; $this->a = $a; $this->b = $b; } } $r1 = new R(); // 默认构造函数 $r2 = new R('arg1'); // 默认构造函数 一个参数的构造函数重载,arg1 $r3 = new R('arg1', 'arg2'); // 默认构造函数 两个参数的构造函数重载,arg1,arg2
Relatively speaking, it is more troublesome than languages like Java, but it does achieve the same function.
Access restrictions on constructors and destructors
Constructors and destructors are public by default, the same as the default values of other methods in the class. Of course they can also be set to private and protected. If you make the constructor non-public, you will not be able to instantiate the class. This is widely used in the singleton mode. Let's look directly at the code of a singleton mode.
class Singleton { private static $instance; public static function getInstance() { return self::$instance == null ? self::$instance = new Singleton() : self::$instance; } private function __construct() { } } $s1 = Singleton::getInstance(); $s2 = Singleton::getInstance(); echo $s1 === $s2 ? 's1 === s2' : 's1 !== s2', PHP_EOL; // $s3 = new Singleton(); // Fatal error: Uncaught Error: Call to private Singleton::__construct() from invalid context
When $s3 wants to be instantiated, an error is reported directly. Regarding the question of why the singleton pattern makes it impossible to instantiate externally, we can look at the singleton pattern in the previous design pattern system article.
Summary
I didn’t expect that the constructor we use every day can play so many tricks. What needs to be paid attention to in daily development is subclass inheritance. The problem is the calling problem of the parent class constructor when the constructor is overridden and the destruction problem when the reference is made.
Recommended tutorial: "PHP Tutorial"
The above is the detailed content of Things to note about __construct() and __destory() in PHP. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



PHP 8.4 brings several new features, security improvements, and performance improvements with healthy amounts of feature deprecations and removals. This guide explains how to install PHP 8.4 or upgrade to PHP 8.4 on Ubuntu, Debian, or their derivati

Visual Studio Code, also known as VS Code, is a free source code editor — or integrated development environment (IDE) — available for all major operating systems. With a large collection of extensions for many programming languages, VS Code can be c

If you are an experienced PHP developer, you might have the feeling that you’ve been there and done that already.You have developed a significant number of applications, debugged millions of lines of code, and tweaked a bunch of scripts to achieve op

This tutorial demonstrates how to efficiently process XML documents using PHP. XML (eXtensible Markup Language) is a versatile text-based markup language designed for both human readability and machine parsing. It's commonly used for data storage an

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

A string is a sequence of characters, including letters, numbers, and symbols. This tutorial will learn how to calculate the number of vowels in a given string in PHP using different methods. The vowels in English are a, e, i, o, u, and they can be uppercase or lowercase. What is a vowel? Vowels are alphabetic characters that represent a specific pronunciation. There are five vowels in English, including uppercase and lowercase: a, e, i, o, u Example 1 Input: String = "Tutorialspoint" Output: 6 explain The vowels in the string "Tutorialspoint" are u, o, i, a, o, i. There are 6 yuan in total

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

What are the magic methods of PHP? PHP's magic methods include: 1.\_\_construct, used to initialize objects; 2.\_\_destruct, used to clean up resources; 3.\_\_call, handle non-existent method calls; 4.\_\_get, implement dynamic attribute access; 5.\_\_set, implement dynamic attribute settings. These methods are automatically called in certain situations, improving code flexibility and efficiency.
