Purpose of PHP constructors
Solution 1:
A constructor is a function that is executed after the object has been initialized (its memory allocated, instance properties copied etc.). Its purpose is to put the object in a valid state.
Frequently, an object, to be in an usable state, requires some data. The purpose of the constructor is to force this data to be given to the object at instantiation time and disallow any instances without such data.
Consider a simple class that encapsulates a string and has a method that returns the length of this string. One possible implementation would be:
class StringWrapper {
private $str;
public function setInnerString($str) {
$this->str = (string) $str;
}
public function getLength() {
if ($this->str === null)
throw new RuntimeException("Invalid state.");
return strlen($this->str);
}
}
In order to be in a valid state, this function requires setInnerString
to be called before getLength
. By using a constructor, you can force all the instances to be in a good state when getLength
is called:
class StringWrapper {
private $str;
public function __construct($str) {
$this->str = (string) $str;
}
public function getLength() {
return strlen($this->str);
}
}
You could also keep the setInnerString
to allow the string to be changed after instantiation.
A destructor is called when an object is about to be freed from memory. Typically, it contains cleanup code (e.g. closing of file descriptors the object is holding). They are rare in PHP because PHP cleans all the resources held by the script when the script execution ends.
Solution 2:
Learn by example:
class Person {
public $name;
public $surname;
public function __construct($name,$surname){
$this->name=$name;
$this->surname=$surname;
}
}
Why is this helpful? Because instead of:
$person = new Person();
$person->name='Christian';
$person->surname='Sciberras';
you can use:
$person = new Person('Christian','Sciberras');
Which is less code and looks cleaner!
Note: As the replies below correctly state, constructors/destructors are used for a wide variety of things, including: de/initialization of variables (especially when the the value is variable), memory de/allocation, invariants (could be surpassed) and cleaner code. I'd also like to note that "cleaner code" is not just "sugar" but enhances readability, maintainability etc.
Solution 3:
The constructor is run at the time you instantiate an instance of your class. So if you have a class Person
:
class Person {
public $name = 'Bob'; // this is initialization
public $age;
public function __construct($name = '') {
if (!empty($name)) {
$this->name = $name;
}
}
public function introduce() {
echo "I'm {$this->name} and I'm {$this->age} years old\n";
}
public function __destruct() {
echo "Bye for now\n";
}
}
To demonstrate:
$person = new Person;
$person->age = 20;
$person->introduce();
// I'm Bob and I'm 20 years old
// Bye for now
We can override the default value set with initialization via the constructor argument:
$person = new Person('Fred');
$person->age = 20;
$person->introduce();
// if there are no other references to $person and
// unset($person) is called, the script ends
// or exit() is called __destruct() runs
unset($person);
// I'm Fred and I'm 20 years old
// Bye for now
Hopefully that helps demonstrate where the constructor and destructor are called, what are they useful for?
-
__construct()
can default class members with resources or more complex data structures. -
__destruct()
can free resources like file and database handles. - The constructor is often used for class composition or constructor injection of required dependencies.
Solution 4:
The constructor of a class defines what happens when you instantiate an object from this class. The destructor of a class defines what happens when you destroy the object instance.
See the PHP Manual on Constructors and Destructors:
PHP 5 allows developers to declare constructor methods for classes. Classes which have a constructor method call this method on each newly-created object, so it is suitable for any initialization that the object may need before it is used.
and
PHP 5 introduces a destructor concept similar to that of other object-oriented languages, such as C++. The destructor method will be called as soon as all references to a particular object are removed or when the object is explicitly destroyed or in any order in shutdown sequence.
In practise, you use the Constructor to put the object into a minimum valid state. That means you assign arguments passed to the constructor to the object properties. If your object uses some sort of data types that cannot be assigned directly as property, you create them here, e.g.
class Example
{
private $database;
private $storage;
public function __construct($database)
{
$this->database = $database;
$this->storage = new SplObjectStorage;
}
}
Note that in order to keep your objects testable, a constructor should not do any real work:
Work in the constructor such as: creating/initializing collaborators, communicating with other services, and logic to set up its own state removes seams needed for testing, forcing subclasses/mocks to inherit unwanted behavior. Too much work in the constructor prevents instantiation or altering collaborators in the test.
In the above Example
, the $database
is a collaborator. It has a lifecycle and purpose of it's own and may be a shared instance. You would not create this inside the constructor. On the other hand, the SplObjectStorage
is an integral part of Example
. It has the very same lifecycle and is not shared with other objects. Thus, it is okay to new
it in the ctor.
Likewise, you use the destructor to clean up after your object. In most cases, this is unneeded because it is handled automatically by PHP. This is why you will see much more ctors than dtors in the wild.