Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


The Object-Oriented Evolution of PHP  : Page 2

One of the key ingredients in the upcoming version 5 of PHP will be the Zend Engine 2.0, with support for a brand new object-oriented programming model. This article describes the evolution of the object-oriented programming support in PHP, covering the new features and changes that are scheduled for PHP 5.

Objects in the Old Days
So, what could one do with objects back in the days of PHP 3.0 or, for that matter, with the current PHP 4.0 version? Not much, really. Objects were essentially containers for properties, like associative arrays. The biggest difference was that objects had to belong to a class. Classes, as in other languages, contained a collection of both properties and methods (functions). You could instantiate instances (objects) from the classes using the new operator. The object model supported single inheritance, which let users extend (specialize) an existing class without having to write it from scratch or copy it. Finally, PHP 4.0 also added the ability to call methods of a specific class, from both within and outside of object contexts.

One of the biggest twists in PHP's history was that despite the very limited functionality, and despite a host of problems and limitations, object oriented programming in PHP thrived and became the most popular paradigm for the growing numbers of off-the-shelf PHP applications. This trend, which was mostly unexpected, caught PHP in a sub-optimal situation. It became apparent that objects were not behaving like objects in other OO languages, and were instead behaving like associating arrays.

The Limitations of the Old Object Model
The most problematic aspect of the PHP 3 / PHP 4 object model was that objects were passed around by value, and not by reference. What does that mean? Here's an example.

Let's say you have a simple, somewhat useless function, called myFunction():

function myFunction($arg) { $arg = 5; }

And you call this function as follows:

$myArgument = 7; myFunction($myArgument); print $myArgument;

As you probably know, the call to myFunction() will leave $myArgument unchanged; Sent to myFunction() is a copy of $myargument's value, and not $myargument itself. This type of argument passing is called passing arguments by value. Passing arguments by reference is done by most structured languages and is extremely useful, as it allows you to write your functions or call other people's functions without worrying about side effects they may have on variables outside their scope.

However, consider the following example:

function wed($bride, $groom) { if ($bride->setHusband($groom) && $groom->setWife($bride)) { return true; } else { return false; } } wed($joanne, $joe); print areMarried($joanne, $joe);

Author Note: Implementing Woman::setHusband(), Man::setWife() and areMarried() is left as an exercise for the reader.

What is the return value of areMarried()? One would hope that the two newlyweds would manage to stay married at least until the following line of code, but as you may have guessed—they wouldn't. areMarried() will confirm that they got divorced just as soon as they got married. Why?

The reason is simple. Objects in PHP 3.0 and 4.0 are not 'special'. They behave like any other kind of variable; in other words, when you pass $joanne and $joe to wed(), you don't really pass them. Instead, you pass clones or replicas of them. So, while their clones end up being married inside wed(), the real $joe and $joanne remained safely distant from the sacrament of holy matrimony, in their protected outer-scope.

Of course, PHP 3 and 4 did give you an option to force your variables to be passed by reference, so you could let functions change the arguments that were passed to them in the outer scope. To do that, you could define the prototype for wed() using the ampersand (&) symbol to tell PHP that its arguments should be passed by-reference, instead of by-value. For example:

function wed(&$bride, &$groom)

With this new implementation of wed(), Joanne and Joe would have better luck (or not, depending on your point of view).

However, it gets more complicated than that. For instance, what if you want to return an object from a function, by reference? What if you want to make modifications to $this inside the constructor, without worrying about what may happen when it gets copied back from new's result into the container variable (if you don't know what I'm talking about here, say "Hallelujah.")?

While PHP 3 and 4 did address these problems to a certain extent by providing syntactic hacks to pass around objects by reference, they never addressed the core of the problem, which is that objects and other types of values are not created equal. Therefore, objects should be passed around by reference unless stated otherwise.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.