Searching...
Thursday 25 July 2013

Defining Class Properties in PHP :: continued


Property Overloading

Property overloading continues to protect properties by forcing access and manipulation through public methods, yet allowing the data to be accessed as if it were a public property. These methods, known as accessors and mutators, or more informally as getters and setters, are automatically triggered whenever the property is accessed or manipulated, respectively.

Unfortunately, PHP does not offer property overloading features that you might be used to if you’re familiar with other OOP languages such as C++ and Java. Therefore, you’ll need to make do with using public methods to imitate such functionality. For example, you might create getter and setter methods for the property name by declaring two functions, getName() and setName(), respectively, and embedding the appropriate syntax within each.

PHP version 5 and newer does offer some semblance of support for property overloading, done by overloading the __set and __get methods. These methods are invoked if you attempt to reference a member variable that does not exist within the class definition. Properties can be used for a variety of purposes, such as to invoke an error message, or even to extend the class by actually creating new variables () on the fly. Both __get and __set are introduced in this article.

Setting Properties with the __set() Method

The mutator, or setter method, is responsible for both hiding property assignment implementation and validating class data before assigning it to a class property. Its prototype follows:

boolean __set([string property_name],[mixed value_to_assign])

It takes as input a property name and a corresponding value, returning TRUE if the method is successfully executed and FALSE otherwise. An example follows:

class Employee
{
var $name;
function __set($propName, $propValue)
{
echo "Nonexistent variable: \$$propName!";
}
}
$employee = new Employee ();
$employee->name = "Mario";
$employee->title = "Executive Chef";

This results in the following output:

Nonexistent variable: $title!

You could use this method to actually extend the class with new properties, like this:

class Employee
{
public $name;
function __set($propName, $propValue)
{
$this->$propName = $propValue;
}
}
$employee = new Employee();
$employee->name = "Mario";
$employee->title = "Executive Chef";
echo "Name: ".$employee->name;
echo "<br />";
echo "Title: ".$employee->title;

This produces the following:

Name: Mario
Title: Executive Chef

 

Getting Properties with the __get() Method

The accessor, or mutator method, is responsible for encapsulating the code required for retrieving a class variable. Its prototype follows:

boolean __get([string property_name])

It takes as input one parameter, the name of the property whose value you’d like to retrieve. It should return the value TRUE on successful execution and FALSE otherwise. An example follows:

class Employee
{
public $name;
public $city;
protected $wage;
function __get($propName)
{
echo "__get called!<br />";
$vars = array("name","city");
if (in_array($propName, $vars))
{
return $this->$propName;
} else {
return "No such variable!";
}
}
}
$employee = new Employee();
$employee->name = "Mario";
echo $employee->name."<br />";
echo $employee->age;

This returns the following:

Mario
__get called!
No such variable!

Creating Custom Getters and Setters

Frankly, although there are some benefits to the __set() and __get() methods, they really aren’t sufficient for managing properties in a complex object-oriented application. Because PHP doesn’t offer support for the creation of properties in the fashion that Java or C# does, you need to implement your own solution. Consider creating two methods for each private property, like so:

<?php
class Employee
{
private $name;
// Getter
public function getName() {
return $this->name;
}
// Setter
public function setName($name) {
$this->name = $name;
}
}
?>

Although such a strategy doesn’t offer the same convenience as using properties, it does encapsulate management and retrieval tasks using a standardized naming convention. Of course, you should add additional validation functionality to the setter; however, this simple example should suffice to drive the point home.


0 comments:

Post a Comment

 
Back to top!