Article
PHP5: Coming Soon to a Webserver Near You
Constructors and Destructors
PHP5 offers an alternative to PHP4 for the class constructor method. Rather than giving the constructor the same name as the class itself, you can use a method called __construct() as the constructor. The advantage of doing this is that should you rename the class, you won't need to rename the constructor (or any code in subclasses of the class you've renamed). Note that you can still use the old approach to constructors (backwards compatibility is preserved).
Here's an example:
<?php
class Foo {
var $variable;
/**
* Constructors now have the common __construct()
* function.
*/
function __construct() {
$this->variable = 'Something';
}
}
echo 'Constructing Foo with the new __construct()<br />';
$f = new Foo();
echo ( $f->variable );
?>
Script: constructor.php
PHP5 also introduces the destructor method, __destruct(), which you can use to make sure that an object is properly "cleaned up" (for example closing the connection to a database) once you've finished with it. PHP's garbage collection mechanism will call the destructor when it removes the object from memory; alternatively, you can call the destructor directly from your code.
For example:
<?php
class File
{
var $resource;
function __construct($name) {
$this->resource = fopen($name,'r');
}
function read() {
if ( !feof($this->resource) )
return fgets($this->resource);
else
return false;
}
function __destruct() {
fclose($this->resource);
}
}
$file = new File('example.html');
echo ('<pre>');
while ( $contents = $file->read() ) {
echo ( htmlspecialchars($contents) );
}
echo ('</pre>');
?>
Script: destructor.php
The __destruct() method above makes sure the opened file is closed when the object is trashed by PHP's garbage collector.
Note that calling __destruct() yourself doesn't actually remove the object from memory—it simply executes the code you defined with the __destruct() method. In the original Zend 2 Engine Overview [PDF] there was talk of a delete statement for removing objects from memory; my attempts to use it with the Beta resulted in syntax errors.
Abstract
PHP5 has formalized abstract classes and methods at an engine level. An abstract class (or method) is one which should not be used directly; instead, it should be used via a concrete subclass. The point in having abstract classes is to allow a group of subclasses to share the parent implementation, while warning other developers not to use the parent directly. You might have an abstract class called HTML_Widget, for example, which is extended by classes such as HTML_Table and HTML_Form; you want people to use only the subclasses rather than the parent itself.
A common PHP4 convention was to place die() statements inside classes and methods that were supposed to be abstract, but in PHP5 we now have a standard approach (which is another Good Thing).
Here's an example:
<?php
abstract class Senior {
protected $speech = 'Hello World!';
function speech() {
return $this->speech;
}
}
class Junior extends Senior {
protected $speech = 'Goodbye World!';
abstract function think() {
sleep(5);
}
}
# Attempt to instantiate abstract class: FATAL Error!
// $g = new Senior();
$g = new Junior();
# Attempt to instantiate abstract method: FATAL Error!
// $g->think();
echo ( $g->speech() );
?>
Script: abstract.php
You get fatal errors if you try to instantiate the abstract class Senior or the think() method of the Junior class.