PHP: Accessors (Getters/Setters)
In languages like C# and VB.net one can define access (read/write) to class properties using
accessors (get/set).
private string _name;
public string name
{
get
{
return _name;
}
set
{
_name = value;
}
}
If we were to exclude the set accessor completely, the property becomes read-only, excluding
the get accessor (obviously leaving the set accessor intact) makes the property write-only.
But more about that later, in this post we're going to talk about adding this functionality to
PHP 5.
A quick way to achieve this is to simply create/use methods to get/set access to a property:
private $name;
public get_name()
{
return $this->name;
}
public set_name($value)
{
$this->name = $value;
}
This personally doesn't feel like a very "natural" way to access fields - since this involves calling methods
and not assigning properties, we can however make it more natural by using "magic methods".
In the following snippet we do exactly that (magic methods __get & __set) by defining a base class containing the functionality to make this work.
abstract class GetterSetter
{
// Check for property accessibility
protected function Accessible($name)
{
// Check for available accessors
if ((method_exists($this, "set_$name")) ||
(method_exists($this, "get_$name")))
return true;
// Inform dev why access to a field was denied
throw new Exception((property_exists($this, $name) == false)
? "Property $name does not exist"
: "Property $name not accessible");
}
public function __get($name)
{
if ($this->Accessible($name))
{
// call get accessor
if (method_exists($this, "get_$name"))
return $this->{"get_$name"}();
else
throw new Exception("Writeonly Property $name");
}
}
public function __set($name, $value)
{
if ($this->Accessible($name))
{
// call set accessor (if available)
if (method_exists($this, "set_$name"))
$this->{"set_$name"}($value);
else
throw new Exception("Readonly Property $name");
}
}
}
The preceding snippet automatically calls the appropriate methods (accessors), when we read/write to
the property/field. To use functionality, simply extend a class.
class person extends GetterSetter
{
private $Age;
private $Name;
public $Note; // Not processed by magic get/set methods - since its public.
public function __construct($Name)
{
$this->Name = $Name;
}
protected function get_Age()
{
return $this->Age;
}
protected function set_Age($value)
{
if ($value < 18)
throw new Exception('Invalid age specified');
$this->Age = $value;
}
protected function get_Name()
{
return $this->Name;
}
}
Usage:
$a = new person('Jack');
//$a->Age = 10; // Throws Exception
//$a->Age = 19; // Sets the field
//$a->Name = "Ben"; // Throws ReadOnly exception
//$a->test = 10; // Throws Exception since the field is undefined.
This ultimately provides a mechanism by which we can set constraints on class properties,
e.g. field must be of certain type (int/string/bool etc), field must be in certain format (e.g. email)
Posted by - Christoff Truter
Date - 2010-05-11 23:28:30
Comments
Post comment