Destructor in PHP: Syntax, Examples
A destructor in PHP is a special method that is used to perform any cleanup activities when an object is destroyed. In PHP, it is defined using the __destruct() method. This special method gets executed automatically when:
- The object goes out of scope.
- The script execution is completed.
- unset() is called on the object.
- PHP garbage collection removes the object.
In object-oriented programming (OOP), a destructor plays a crucial role in cleaning up resources when an object is no longer needed. The __destructor() method is used to perform the cleanup tasks such as:
- Closing database connections
- Releasing file handles
- Freeing memory resources
- Logging messages
- Cleaning temporary data
- Logging object destruction
Basic Syntax of PHP Destructor
The general syntax for declaring a destructor in PHP is very simple and straightforward:
class ClassName {
public function __destruct() {
// Cleanup code here
}
}
In the above syntax,
- __destruct() is a method name that must be declared with two underscores.
- This method does not accept any parameters.
- You can only define one destructor in a class.
- PHP automatically calls the destructor at the end of program execution. However, it can also run earlier if the object goes out of scope or unset() is used.
- The destructor is almost always declared as public, but it may also be protected or private in special use cases.
How Destructor Works Internally in PHP?
Here’s how PHP handles destructors:
- When you create an object of the class, it stays alive in the memory until the program finishes executing or the memory is explicitly freed.
- When the object goes out of scope or is explicitly destroyed using unset() method, PHP automatically calls the __destruct() method.
- The destructor performs cleanup operations, such as closing database connection, releasing resources, or finalizing operations that need to occur before an object is destroyed.
- After the destructor finishes executing, PHP releases the memory allocated to that object.
- PHP uses a reference counting mechanism along with garbage collection, which means destructors may not execute immediately.
- However, under normal conditions, all pending destructors are triggered before the script finishes executing.
Basic Examples of Destructors in PHP
Let’s take some important examples based on the destructor in PHP that you must practice them.
Example 1: Basic
<?php
class Test {
public function __construct() {
echo "Constructor called \n";
}
public function __destruct() {
echo "Destructor called";
}
}
// Create an object of class Test.
$obj = new Test();
?>Output:
Constructor called Destructor called
Example 2:
<?php
class Test {
public function __destruct() {
echo "Object destroyed, \n";
}
}
$obj = new Test();
unset($obj); // Destroying object manually.
echo "End of script! \n";
?>Output:
Object destroyed. End of script!
In this example, we have created a class named Test, which contains a destructor method __destruct(). This method prints a message “Object destroyed.” when the object is destroyed.
Creating an object of the class Test does not trigger the destructor immediately. When PHP executes the unset() function, it immediately destroys the object $obj. As a result, PHP automatically calls the __destruct() method, so the message “Object destroyed.” is printed at that moment.
The destructor is triggered exactly when unset($obj) is called. After the object is destroyed, the script continues running and prints “End of script!”.
Example 3: Destructor in Loops
<?php
class LoopEx {
public function __construct() {
echo "Object created. \n";
}
public function __destruct() {
echo "Object destroyed. \n";
}
}
for ($i = 1; $i <= 2; $i++) {
$obj = new LoopEx();
}
?>
Output:
Object created. Object destroyed. Object created. Object destroyed.
In this example, each loop iteration destroys the previous object.
Advanced Examples Based on Destructor in PHP
Let’s take some advanced examples based on the destructor in PHP.
Example 1: Closing a Database Connection
Destructors are commonly used to close database connections. Look the at example below.
<?php
class Database {
private $conn;
public function __construct() {
$this->conn = new mysqli("localhost", "root", "", "test");
echo "Database connected. \n";
}
public function runQuery() {
echo "Executing query... \n";
}
public function __destruct() {
$this->conn->close();
echo "Database connection closed. \n";
}
}
$db = new Database();
$db->runQuery();
?>Output:
Database connected. Executing query... Database connection closed.
In this example, we have created a class named Database, which is responsible for handling database operations. The class contains a private variable $conn, which stores the MySQL connection object. Since it is a private variable, it can be accessed only inside this class itself.
The __construct() method declared inside the class automatically runs when an object of the class is created. Inside this method, a MySQL database connection is established using the following details:
- Host: localhost
- Username: root
- Password: “”
- Database: test
After the connection is successfully created, the constructor prints “Database connected.” The runQuery() method simulates executing a database query. It simply prints “Executing query…”
The __destruct() method runs automatically when the object is destroyed or when the script finishes execution. The destructor closes the database connection by calling $this->conn->close(), and then prints “Database connection closed.” Since the script ends after the query is executed, PHP destroys the $db object and triggers the destructor.
Example 2: Destructor in File Handling
<?php
class FileHandler {
private $file;
public function __construct($filename) {
$this->file = fopen($filename, "a");
echo "File opened. \n";
}
public function write($text) {
fwrite($this->file, $text . PHP_EOL);
}
public function __destruct() {
fclose($this->file);
echo "File closed. \n";
}
}
$obj = new FileHandler("log.txt");
$obj->write("Hello World!");
?>Output:
File opened. File closed.
Content written inside log.txt
Hello World!
In this example, we have created a class named FileHandler, which is responsible for handling file operations. This class contains a private variable $file that stores the file resource (file handle). Since this variable is declared as a private, it can be accessed only inside the class.
The constructor runs automatically when an object of the class is created. It accepts $filename as a parameter.
The function fopen($filename, “a”) opens the file in append mode:
- If the file does not exist, it will be created.
- If it already exists, new content will be added at the end.
After opening the file, it prints the message “File opened.”.
The write() function accepts a string and writes it to the opened file. The variable PHP_EOL adds a new line at the end (platform-specific). So, the line written into log.txt will be: Hello World!.
The __distruct() method runs automatically when the object is destroyed ( or end of script). It closes the open file using fclose() function. When the script finishes, PHP destroys the $obj object.
Example 3: Destruction Order
<?php
class OrderEx {
private $name;
public function __construct($name) {
$this->name = $name;
echo "Constructed: {$this->name}\n";
}
public function __destruct() {
echo "Destroyed: {$this->name}\n";
}
}
$obj1 = new OrderEx('Object 1');
$obj2 = new OrderEx('Object 2');
$obj3 = new OrderEx('Object 3');
?>
Output:
Constructed: Object 1 Constructed: Object 2 Constructed: Object 3 Destroyed: Object 3 Destroyed: Object 2 Destroyed: Object 1
In this example, we have created a class named OrderEx, which contains:
- private property $name
- constructor __construct()
- destructor __destruct()
The constructor method __construct() accepts a name and stores it in $this->name. This runs immediately when each object is created.
The destructor __destruct() method is automatically executed when the object is destroyed or the script execution ends.
As you can see in the example code, three objects are created. Therefore, each object creation triggers constructors one by one.
PHP destroys objects in reverse order of creation (LIFO – Last In, First Out), unless the unset() function changes the order. Since you did not call unset() function, destruction happens automatically at the end of the script. So, the destroy order:
- obj3
- obj2
- obj1
Common Mistakes to Avoid
Here are some common mistakes that you must avoid when working with destructors in PHP:
- Do not try to pass arguments to destructors because destructors cannot accept parameters.
- Do not create multiple destructors in a class because only one destructor is allowed per class.
- Should not use destructors for important program logic. Destructors should only handle cleanup, not critical application logic.
- Do not throw exceptions inside destructors because PHP does not allow exceptions to escape destructors. Doing so may cause a fatal error.
- Do not rely on destructor execution order across objects. Within the same scope, PHP destroys objects in reverse order of creation (LIFO). But PHP does not guarantee destruction order across different scopes, global objects, or static objects.
Best Practices for Using Destructor in PHP
Following are the best practices when working with destructor in PHP:
- Always close files or database connections in destructors.
- Use destructors for cleanup tasks.
- Call parent::__destruct() in inherited classes.
- Avoid executing important program logic in destructors.
Conclusion
A destructor in PHP is a special method that helps to release resources or perform final cleanup tasks before an object is destroyed. PHP automatically calls the destructor when an object goes out of scope or when the script execution ends.
While constructors run automatically when an object is created, destructors run automatically when an object is about to be removed from memory. We hope you now clearly understand how destructors work in PHP and have practiced the important examples discussed.
