Magic Functions in PHP 5

It’s not breaking news that the release of PHP 5 drastically changed the way that many developers build their web-based programs. The incorporation of a much more robust object model, along with the introduction of native exceptions, type hinting and so forth (add your own improvement to the list) has given the language the maturity that we see in it today. This seven-part article series will explain an important new feature: magic functions.

Among the new features introduced in PHP 5, magic functions are an important part of the whole enhancement process. They’ve also been rather overlooked by some programmers, either because of laziness or ignorance.

Despite their funny name, magic functions permit users to perform difficult tasks effortlessly. They can be powerful time-savers for loading resources automatically, or for overloading methods and properties of classes, to cite just two illustrative examples.

Naturally, for experienced developers, magic functions are an old creature they’ve long since tamed, but for beginners, learning how to use them in a true productive manner can be challenging experience — especially when they’re utilized during the development of object-oriented applications.

So, if you’re a PHP programmer who wishes to learn how to master the basic concepts that surround the implementation and use of magic functions, then in this series of articles you’ll find a comprehensive guide that will show you how to work with them, using a strong hands-on approach.

In the successive tutorials of the series, I’m going to cover the most relevant magic functions provided by PHP 5, starting with the "__set()" and __"get()" methods. Future parts will explore the "__call()", "__sleep() and "__wakeup() functions, and even later I will discuss the use of "__isset()", "__unset()", "__clone()", "__destruct()" and "__autoload()" respectively.

By the end of this series, you should be armed with a solid background in the theory of using magic functions. You’ll also have practiced with a good number of concrete examples.

Now, it’s time to leave the preliminaries start discovering the real power behind utilizing magic functions. Let’s get started right away!

{mospagebreak title=Get and set functions: a quick overview}

As I expressed in the introduction, the first two magic functions that I plan to cover are the popular "__set()" and "__get()" methods. They can be really useful for overloading properties of a class.

But, at this point, you may be wondering how to use these functions. Well, as with any other magic methods, the "__set()" and "__get()" functions have no concrete implementation and must be given a explicit definition.

In the case of the "__set()" function, it’ll be called automatically by the PHP engine each time a script attempts to assign a value to a property of a class that hasn’t been explicitly declared. On the other hand, the "__get()" function will be invoked transparently when a script tries to retrieve the value of an undeclared class property as well.

This setting and retrieval process of values of properties within a class that have no a explicit declaration comprises what’s known as "property overloading." It must be very carefully implemented to prevent its misuse and abuse. 

Does this sound a bit confusing to you? Fear not; in a moment, I’m going to back up all of these concepts with a couple of examples that will illustrate how to use the team of "__set()" and "__get()" functions.

Say that there’s a basic class called "User," which represents, through software, a real-world user. The definition of this sample class would be something like this:

class User {

private $fname = ‘Alejandro’;

private $lname = ‘Gervasio’;

private $email = ‘alejandro@mydomain.com’;

 

// constructor (not implemented)

public function __construct(){}

 

// set user’s first name

public function setFirstName($fname)

{

$this->fname = $fname;

}

 

// get user’s first name

public function getFirstName()

{

return $this->fname;

}

// set user’s last name

public function setLastName($lname)

{

$this->lname = $lname;

}

 

// get user’s last name

public function getLastName()

{

return $this->lname;

}

// set user’s email address

public function setEmail($email)

{

$this->email = $email;

}

 

// get user’s email address

public function getEmail()

{

return $this->email;

}

}

As you can see, the structure of the above "User" class is pretty easy to follow. It’s only composed of a few setters and getters, used for setting and retrieving the values assigned to its three declared properties, that is $fname, $lname and $email respectively.

So far, nothing strange is happening here, right? What follows is a simple demonstration of how to use this class:

$user = new User();

$user->setFirstName(‘John’);

$user->setLastName(‘Doe’);

$user->setEmail(‘john@domain.com’);

 

// display user data

echo ‘First Name: ‘ . $user->getFirstName() . ‘ Last Name: ‘ . $user->getLastName() . ‘ Email: ‘ . $user->getEmail();

 

/*

displays the following

First Name: John Last Name: Doe Email: john@domain.com

*/

Well, that was extremely boring, wasn’t it? All that the previous script does is create an instance of the "User" class, assign some values to the properties of the class via the pertinent setters, and finally display the values in question using the pertinent getters.

However, this tame and well-known scenario is about to become more exciting. It’s possible to redefine the "User" class by using the "__set()" and "__get()" magic functions to make the class’s signature much shorter. At the same time, they’ll allow us to assign undeclared properties dynamically.

The full details of this process will be discussed in the section to come. Click on the link below and keep reading to learn more.

{mospagebreak title=Property overloading in action}

In the previous segment, I created a basic "User" class, whose API allowed us to easily assign and retrieve the values of its declared properties. However, as I expressed earlier, it’s possible to shorten its  definition and make it more "dynamic" simply by concretely implementing the "__set()" and "__get()" methods.

To demonstrate this concept a bit more, I’m going to redefine this sample class to allow us not only to create new class properties at run time, but retrieve their respective values with extreme ease.

Now that you know what I’m going to do in the next few lines, please examine the modified version of the "User" class. It now looks like this:

class User

{

// constructor (not implemented)

public function _construct(){}

 

// set undeclared property

function __set($property, $value)

{

$this->$property = $value;

}

 

// get defined property

function __get($property)

{

if (isset($this->$property))

{

return $this->$property;

}

}

}

Now, suddenly things are much more interesting than in the example shown in the previous section. As you can see above, the "User" class is only comprised of two methods – the corresponding "__set()" and "__get()" functions. And in this specific situation, they have been given a concrete implementation.

In the first case, the "__set()" function will create an undeclared property and assign a value to it, while in the last case, its counterpart "__get()" will retrieve this value if the property has been previously set.

The implementation of these two methods permits us to overload properties in a truly simple way. It also makes the class’s source code much shorter and more compact. But, as with everything in life, this process has some disadvantages that must be taken into account. First, and most importantly, the lack of an explicit declaration for each property of the class makes the code harder to read and follow. Second, it’s practically impossible for an IDE to keep track of those properties for either commenting or documenting them.

Logically, this is something that must be evaluated consciously when overloading the properties of a class. Its implementation depends strongly on the context where it will be used.

Now, returning to the previous example class, given that it’s already been modified, it’s time to give it a try, right? So, with that idea in mind, in the next section I’m going to create an example that will show how to assign undeclared properties to it, and how to retrieve their values.

Don’t waste more time; read the following segment. It’s only one click away

{mospagebreak title=The set and get methods in action}

In the previous segment, you learned how to give a concrete implementation to the "__set()" and "__get()" magic functions within a simple class to assign to it undeclared properties at run time. You also learned how to fetch values in a straightforward manner.

Now, it’s time to demonstrate how to take advantage of these functions by means of a concrete example. Below I wrote a short script, which shows how to dynamically assign four properties to the "User" class that naturally have no explicit declaration.

Here’s how this script looks:

// example of usage of ‘User’ class with property overloading

$user = new User();

$user->fname = ‘Alejandro’;

$user->lname = ‘Gervasio’;

$user->email = ‘alejandro@mydomain.com’;

$user->address = ‘My address 1234′;

 

// display user data

echo ‘First Name: ‘ . $user->fname . ‘ Last Name: ‘ . $user->lname . ‘ Email: ‘ . $user->email . ‘ Address: ‘ . $user->address;

/*

displays the following

First Name: Alejandro Last Name: Gervasio Email: alejandro@mydomain.com Address: My address 1234

*/

Regardless of the simplicity of the above example, it demonstrates how useful the "__set()" and "__get()" magic functions can be when it comes to overloading properties of a class.

As you may have noticed, on one hand the script creates four new properties for the class and assigns to them some trivial values, while on the other hand those values are retrieved "behind the scenes" via the pertinent "__get()" method. Simple to code, even when it’s not so simple to read, right?

The previous phrase is an adequate epilogue for this first installment of the series. As I explained before, the implementation of the "__set()" and "__get()" magic functions is a powerful approach that must be used very carefully.

Undeniably, it’s possible to perform all sorts of clever tasks via these functions, but this versatility comes at a cost. In general, it may be harder to read and understand how a class is handling its properties. Anyway, PHP 5 gives you the chance to use property overloading in an easy way, so go ahead and give it a try!

Final thoughts

That’s all for the moment. In this introductory part of the series, I explained how to implement and use the "__set()" and "__get()" magic functions included with PHP 5, which allow you to overload the properties of a class very easily.

It’s not new to say that property overloading is a powerful approach that can be used to perform all sorts of clever tasks, but as I explained, it must be used carefully, and certainly not abused.

In the next part of the series I’m going to explain how to use the "__isset()" and "__unset()" magic functions, so don’t miss the upcoming tutorial!

[gp-comments width="770" linklove="off" ]
antalya escort bayan antalya escort bayan