At first, PHP wasn't an
object-oriented (OO) language. As it evolved, more and more object-oriented
features appeared. First, you could define classes, but there were no
constructors. Then, constructors appeared, but there were no destructors. Slowly
but surely, as more people began to push the limits of PHP's syntax, additional
features were added to satisfy the demand.
However, if you're the type of person who wishes PHP to be a
true OO language, you'll probably be disappointed. At its heart, PHP is a
procedural language. It isn't Java. But, if you're the type of person who wants
to use some OO features in your code, PHP is probably right for you.
A class is a package containing two things:
data and methods to access and modify that data. The data portion consists of
variables; they're known as properties. The other part of a class is a
set of functions that can alter a class' properties; they're called
methods.
When we define a class, we don't define an object that can be
accessed and manipulated. Instead, we define a template for an object. From this
blueprint, we create malleable objects through a process known as
instantiation . A program can
have multiple objects of the same class, just as a person can have more than one
book or many pieces of fruit.
Classes also live in a defined hierarchy. At the top of the chain, there is a generic class.
In PHP, this class is named stdClass, for
"standard class." Each class down the line is more specialized than its parent.
For example, a parent class could be a building. Buildings can be further
divided into residential and commercial. Residential buildings can be further
subdivided into houses and apartment buildings, and so forth.
Both houses and apartment buildings have the same set of
properties as all residential buildings, just as residential and commercial
buildings share some things in common. When classes are used to express these
parent-child relationships, the child class inherits the properties and methods
defined in the parent class. This allows you to reuse the code from the parent
class and requires you to write code only to adapt the new child to its
specialized circumstances. This is called inheritance and is one of the major advantages of
classes over functions. The process of defining a child class from a parent is
known as subclassing or
extending.
Objects play
another role in PHP outside their traditional OO position. Since PHP can't use
more than one namespace, the ability for a class to package multiple properties
into a single object is extremely helpful. It allows clearly demarcated separate
areas for variables.
class guest_book {
var $comments;
var $last_visitor;
function update($comment, $visitor) {
...
}
}
The class keyword defines an class, just as function defines a function. Properties are
declared using the var keyword. Method declaration is
identical to how functions are defined.
$gb = new guest_book;
Object instantiation is covered in more detail in Section 7.2.
Inside a class, you can optionally declare properties using
var. There's no requirement to do so, but it is a useful way to reveal
all the class' variables. Since PHP doesn't force you to predeclare all your
variables, it's possible to create one inside a class without PHP throwing an
error or otherwise letting you know. This can cause the list of variables at the
top of a class definition to be misleading, because it's not the same as the
list of variables actually in the class.
Besides declaring a property, you can also assign it a
value:
var $last_visitor = 'Donnan';
var $last_visitor = 'Donnan'; // okay
var $last_visitor = 9; // okay
var $last_visitor = array('Jesse'); // okay
var $last_visitor = pick_visitor( ); // bad
var $last_visitor = 'Chris' . '9'; // bad
If you try to assign something else, PHP dies with a parse
error.
var $last_visitor;
function update($comment, $visitor) {
if (!empty($comment)) {
array_unshift($this->comments, $comment);
$this->last_visitor = $visitor;
}
}
If the visitor left a comment, you add it to the top of the
array of comments and set that person as the latest visitor to the guest book.
The variable $this is a special variable that refers to the current
object. So, to access the $size property of an object from inside that
object, refer to $this->size.
To assign nonconstant values to variables upon instantiation,
assign them in the class constructor. The class constructor is a method
automatically called when a new object is created, and it has the same name as
your class:
class guest_book {
var $comments;
var $last_visitor;
function guest_book($user) {
$dbh = mysql_connect('localhost', 'username', 'password');
$db = mysql_select_db('sites');
$user = mysql_real_escape_string($user);
$sql = "SELECT comments, last_visitor FROM guest_books WHERE user='$user'";
$r = mysql_query($sql);
if ($obj = mysql_fetch_object($r)) {
$this->comments = $obj->comments;
$this->last_visitor = $obj->last_visitor;
}
}
}
$gb = new guest_book('stewart');
Constructors are covered in Section 7.3.
Note that mysql_real_escape_string() is new as of PHP 4.3; for earlier
versions, use mysql_escape_string().
Be careful not to
mistakenly type $this->$size. This is legal, but it's not the same
as $this->size. Instead, it accesses the property of the object
whose name is the value stored in the $size variable. More often then
not, $size is undefined, so $this->$size appears empty. For
more on variable property names, see Section 6.6.
Besides using -> to access a method or member variable, you can also use
::. This syntax can access static methods in a class. These methods are
identical for every instance of an class, because they can't rely on
instance-specific data. For example:
class convert {
// convert from Celsius to Fahrenheit
function c2f($degrees) {
return (1.8 * $degrees) + 32;
}
}
$f = convert::c2f(100); // 212
class xhtml extends xml {
}
Child classes inherit parent methods and
can optionally choose to implement their own specific versions:
class DB {
var $result;
function getResult() {
return $this->result;
}
function query($sql) {
error_log("query() must be overridden by a database-specific child");
return false;
}
}
class MySQL extends DB {
function query($sql) {
$this->result = mysql_query($sql);
}
}
The MySQL class above inherits
the getResult( ) method
unchanged from the parent DB class, but has its own MySQL-specific query(
) method.
function escape($sql) {
$safe_sql = mysql_real_escape_string($sql); // escape special characters
$safe_sql = parent::escape($safe_sql); // parent method adds '' around $sql
return $safe_sql;
}
Section 7.8
covers accessing overridden methods.
The underlying engine powering PHP is named Zend. PHP 4 uses
Zend Engine 1; PHP 5 will use an updated version — Zend Engine 2 (ZE2). ZE2 has
an entirely new object model that allows PHP to support many new object-oriented
features: constructors and destructors, private methods, exception handling,
cloning, and nested classes. In this chapter, we mention when there's a
difference in syntax or features between PHP 4 and what's supported by ZE2, so
you can plan for the future.