Magic __get getter for static properties in PHP
No, it is not possible.
Quoting the manual page of __get :
Member overloading only works in object context. These magic methods will not be triggered in static context. Therefore these methods can not be declared static.
In PHP 5.3, __callStatic
has been added ; but there is no __getStatic
nor __setStatic
yet ; even if the idea of having/coding them often comes back on the php internals@ mailling-list.
There is even a Request for Comments: Static classes for PHP
But, still, not implemented (yet ? )
Maybe someone still need this:
static public function __callStatic($method, $args) {
if (preg_match('/^([gs]et)([A-Z])(.*)$/', $method, $match)) {
$reflector = new \ReflectionClass(__CLASS__);
$property = strtolower($match[2]). $match[3];
if ($reflector->hasProperty($property)) {
$property = $reflector->getProperty($property);
switch($match[1]) {
case 'get': return $property->getValue();
case 'set': return $property->setValue($args[0]);
}
} else throw new InvalidArgumentException("Property {$property} doesn't exist");
}
}
Very nice mbrzuchalski. But it seems to only work on public variables. Just change your switch to this to allow it to access private/protected ones:
switch($match[1]) {
case 'get': return self::${$property->name};
case 'set': return self::${$property->name} = $args[0];
}
And you'd probably want to change the if
statement to limit the variables that are accessible, or else it would defeat the purpose of having them be private or protected.
if ($reflector->hasProperty($property) && in_array($property, array("allowedBVariable1", "allowedVariable2"))) {...)
So for example, I have a class designed to pull various data for me out of a remote server using an ssh pear module, and I want it to make certain assumptions about the target directory based on what server it's being asked to look at. A tweaked version of mbrzuchalski's method is perfect for that.
static public function __callStatic($method, $args) {
if (preg_match('/^([gs]et)([A-Z])(.*)$/', $method, $match)) {
$reflector = new \ReflectionClass(__CLASS__);
$property = strtolower($match[2]). $match[3];
if ($reflector->hasProperty($property)) {
if ($property == "server") {
$property = $reflector->getProperty($property);
switch($match[1]) {
case 'set':
self::${$property->name} = $args[0];
if ($args[0] == "server1") self::$targetDir = "/mnt/source/";
elseif($args[0] == "server2") self::$targetDir = "/source/";
else self::$targetDir = "/";
case 'get': return self::${$property->name};
}
} else throw new InvalidArgumentException("Property {$property} is not publicly accessible.");
} else throw new InvalidArgumentException("Property {$property} doesn't exist.");
}
}