Object-Oriented PHP: Implementation of C# getters and setters in PHP
========================================================================
PHP 5 and C# .NET have a getter and setter method feature, making it look like we’re accessing the data member directly. As you probably know, in C# you can define getters and setters for the properties of an object like this:
-------------------------------------------------
public class Person
{
//default constructor
public Person()
{
}
private string _Name;
public string Name
{
//set the person name
set { this._Name = value; }
//get the person name
get { return this._Name; }
}
}
-------------------------------------------------
You can simulate this functionality in PHP 5.x using the magic __get () and __set () functions, but that solution has one big drawback. Magic variables are not visible in the PHP code (in a class declaration), and in IDE applications (until the variable is declared “virtually” from the phpDoc comments).
Because of that I present you another little-known functionality of the PHP language, which solves the above problems. In my solution you can easily convert class properties into magic variables which will be visible everywhere in the code/IDE applications.
The official PHP documentation suggests that there is no way to trigger magic methods in case of operations performed on declared class properties (the __get (), __isset (), __unset () and __set () methods operate only on variables that were not declared in the given class).
But the reality is different. Looking at the source code of PHP interpreter one can quickly notice that the PHP documentation is somewhat incomplete. There is one, the only way to force the PHP interpreter to use magic methods on the declared class properties. You can trigger this functionality during the construction of an object.
Below is a sample script which enumerates through all of the properties and switches them to read-only mode if their name starts with an underscore:
-------------------------------------------------
class Test
{
public $_magic = "readonly";
protected $realMagic = array();
public function __construct() {
foreach($this as $name => $value) {
if($name[0] === '_') {
$this->realMagic[$name] = $value;
unset($this->$name);
}
}
}
public function __get($name) {
if(isset($this->realMagic[$name])) {
return $this->realMagic[$name];
}
}
public function __set($name, $value) {
if(isset($this->realMagic[$name])) {
throw new Exception('This property is read only');
}
}
}
-------------------------------------------------
Let’s make a test with a code below:
-------------------------------------------------
$x = new Test();
echo "<br>READING _magic PROPERTY... ";
echo $x->_magic;
echo "<br>SETTING _magic PROPERTY...<br>";
$x->_magic = "test";
…and see the results:
READING _magic PROPERTY... readonly
SETTING _magic PROPERTY...
Fatal error: Uncaught exception 'Exception' with message 'This property is read only' in C:\Documents and Settings\agraniszewski\Desktop\www\example2.php:26 Stack trace: #0 C:\Documents and Settings\agraniszewski\Desktop\www\example2.php(39): Test->__set('_magic', 'test') #1 {main} thrown in C:\Documents and Settings\agraniszewski\Desktop\www\example2.php on line 26
-------------------------------------------------
SUMMARY
The greatest advantage of this solution is that we can thus simulate static/magic properties in PHP without sacrificing the intellisense functionality of any popular IDE application. |