The Call Magic Function in PHP 5

If you’re a PHP developer who wishes to learn how to implement and use the set of magic functions that come included with PHP 5, you’ve come to the right place. Welcome to the third part of a series that takes a close look at magic functions in PHP 5. Made up of seven tutorials, this series teaches you how to work with the most common PHP 5 magic functions, putting particular emphasis on their usage within the context of object-oriented applications.

And now that you know what to expect from this group of articles, it’s time to quickly review the topics that were discussed in the last one. In that installment of the series I explained by means of some examples how to work with the complementary "__isset()" and "__unset()" magic methods, which are called automatically by the PHP engine when using the "isset()" and "unset()" functions respectively.

Frankly speaking, those magic methods aren’t the most useful provided by PHP 5, but there are others that do allow you to perform powerful tasks with minor efforts. That’s exactly the case with the "__call()" function, which is invoked transparently by the PHP interpreter when a non-existent method of a class is called by a script.

As I said before, this function permits you to do all sorts of clever things, ranging from creating setters and getters on the fly to building mechanisms that catch calls to other defined class methods.

Therefore, as the title of this article suggests, in the new few lines I’m going to take a deeper look at the"__call()" function, so that you can quickly become familiar with it. 

Are you ready to learn how to take advantage of this handy magic function? Then begin reading right now!

{mospagebreak title=Review: the isset and unset magic functions}

It’s quite possible that you haven’t had the chance to read the preceding tutorial of this series, where I discussed briefly how to implement and use the "__isset()" and "__unset()" magic functions.

With this in mind, I’ve included the example created in that article, which shows how to utilize those functions within a basic class called "User."

Here’s the complete source code that corresponds to the aforementioned "User" class. Have a look at it, please:

class User

{

// constructor (not implemented)

public function _construct(){}

 

// set undeclared property in a restrictive way

public function __set($property, $value)

{

if (in_array($property, array(‘fname’, ‘lname’, ‘email’)) === TRUE)

{

$this->$property = $value;

}

}

 

// get declared property

public function __get($property)

{

return $this->$property;

}

 

// implement __isset() method

public function __isset($property)

{

echo ‘Checking if property ‘. $property . ‘ has been set…';

}

 

// implement __unset() method

public function __unset($property)

{

echo ‘Unsetting property ‘ . $property;

}

}

Now that I have listed the entire signature of the above "User" class, which shows a simple implementation of the "__isset()" and "__unset()" magic methods, please focus your attention on the following code snippet. It demonstrates how they behave when using the "isset()" and "unset()" PHP functions with an instance of the previous user-related class.

Here’s the corresponding code sample:

$user = new User();

$user->fname = ‘Alejandro';

$user->lname = ‘Gervasio';

isset($user->email);

/*

display the following

Checking if property email has been set…

*/

 

unset($user->email);

/*

displays the following

Unsetting property email

*/

As you can see, using the "__isset()" and "__unset()" functions isn’t too different from working with other magic methods, such as "__set()" and "__get()" that were discussed in the first tutorial. All that’s required here is to give an explicit implementation to the functions and then use "isset()" and "unset()" to make the PHP engine call them automatically. It’s that simple, really.

Well, at this point I’m sure that you’ve already grasped the underlying logic of the previous example. Thus, it’s time to continue exploring other PHP 5 magic functions, and that logically includes the "__call()" method mentioned in the introduction.

With that idea in mind, in the following section I’m going to explain how to work with this brand new method to implement what is widely called "method overloading" in object-oriented jargon.

Now, to learn more on this topic, click on the link that appears below and proceed to read the section to come. I’ll be there, waiting for you.

{mospagebreak title=Method overloading in PHP 5 with the call magic function} 

Quite probably, one of the most helpful methods that fall under the category of magic functions is the popular "__call()." If you still haven’t had the opportunity to use it with your programs, the "__call()" function is invoked behind the scenes by the PHP parser when it finds a reference to a method of a class that haven’t been explicitly defined.

So, on one hand there’s the pair composed by the "__set()" and "__get()" functions, which allow you to overload properties of a class, while on the other hand, "__call()" permits you to overload methods extremely easily.

Of course, this way of overloading properties and methods is only a proprietary feature of PHP 5 that differs significantly from other mature languages, such as Java and C++, but it can be really helpful when used in a creative manner.

Now that you have a more clear idea of when the "__call()" function is invoked by the PHP engine, let me show you two concrete examples, so you can spot the differences between them. In the first case, the "User" class that you saw before will be used without implementing the "__call()" method, while in the second example, the method will be implemented explicitly.

So, here’s the "User" class without using method overloading:

class User

{

// constructor (not implemented)

public function _construct(){}

 

// set undeclared property in a restrictive way

public function __set($property, $value)

{

if (in_array($property, array(‘fname’, ‘lname’, ‘email’)) === TRUE)

{

$this->$property = $value;

}

}

 

// get declared property

public function __get($property)

{

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

{

return $this->$property;

}

}

}

 

 

// example of usage of ‘User’ class with no method overloading

$user = new User();

$user->fname = ‘Alejandro';

$user->lname = ‘Gervasio';

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

// display user data

echo ‘First Name : ‘ . $user->fetch(‘fname’) . ‘ Last Name : ‘ . $user->fetch(‘lname’) . ‘Email : ‘ . $user->fetch(‘email’);

 

/*

triggers a fatal error:

Fatal error: Call to undefined method User::fetch() in path/to/file

*/

So far, nothing unexpected is happening here, since the above script attempts to retrieve the values assigned to the properties of a fictional user via a non-existent method called "fetch()." Naturally, this makes the PHP parser raise a fatal error.

However, this issue can be addressed quickly if the same class gives a concrete implementation to the "__call()" method. Want to see how this can be done? Well, take a look at the new definition of this class, which is as follows:

class User

{

// constructor (not implemented)

public function _construct(){}

 

// set undeclared property in a restrictive way

public function __set($property, $value)

{

if (in_array($property, array(‘fname’, ‘lname’, ‘email’)) === TRUE)

{

$this->$property = $value;

}

}

 

// get declared property

public function __get($property)

{

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

{

return $this->$property;

}

}

 

// single point to fetch user data

public function __call($method, $args)

{

if ($method === ‘fetch’ AND empty($args) === FALSE)

{

return $this->$args[0];

}

}

}

Definitely, things are getting much more interesting now. As you can see, the enhanced version of the "User" class includes the "__call()" method, which checks to see if the non-existent method being called is named "fetch()" or not. If this happens to be true, it’ll return the first argument that was passed in to it.

Implementing the "__call()" function in that way will allow us to use the non-declared "fetch()" method to retrieve the values assigned to the properties of the "User" class in a really simple fashion.

But guess what? The full details of this process will be discussed in the last section of this tutorial. Therefore, to get there, click on the link below and keep reading.

{mospagebreak title=The call magic method in action} 

In the prior segment, I explained how to implement the "__call()" functions to intercept all of the calls made to non-existent methods of the sample "User" class. In this particular case, the function will accept only requests for a "fetch()" method, which will be used for retrieving the values assigned to the class’s properties. For you to understand how to accomplish this retrieval process, you’ll find a short example below that shows how to use the undeclared "fetch()" method without triggering a fatal error.

Here it is:

// example on utilizing ‘User’ class with method overloading

$user = new User();

$user->fname = ‘Alejandro';

$user->lname = ‘Gervasio';

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

 

// display user data

echo ‘First Name : ‘ . $user->fetch(‘fname’) . ‘ Last Name : ‘ . $user->fetch(‘lname’) . ‘ Email : ‘ . $user->fetch(‘email’);

 

/*

display the following

First Name : Alejandro Last Name : Gervasio Email : alejandro@mydomain.com

*/

There you have it. Now, via the handy "__call()" magic function it’s possible to overload the "fetch()" method and use it for retrieving the values given to the properties of the "User" class. Of course, you can implement the "__call()" function in the way that best suits your needs; that process will logically depend on the context in which this function will be used.

Finally, feel free to edit all of the code samples shown in this tutorial, so you can acquire a more solid foundation in working with the set of magic functions included with PHP 5.

Final thoughts

It’s hard to believe, but we’ve come to the end of this third part of the series. Nevertheless, the whole experience has been instructive, since you learned how to use the "__call()" magic function to implement method overloading in PHP 5.

Definitely, I don’t mean to dismiss the importance of other magic functions, but possibly the trio composed by the "__set()", "__get()" and "__call()" methods is one of the most powerful ones when it comes to simplifying the tasks performed by a particular class. Naturally, this simplification comes at a cost, very frequently in terms of poorer readability and code maintenance, so make sure not to abuse them when developing your own web applications.

Moving forward, in the next installment of the series I’m going to continue exploring more magic functions bundled with PHP 5. That particular tutorial will be focused on discussing the "__sleep()" and "__wakeup()" functions, which are invoked automatically by the PHP engine when serializing/unserializing objects.

Don’t miss the upcoming part!

[gp-comments width="770" linklove="off" ]

chat sex hikayeleri Ensest hikaye