Created
May 20, 2013 16:54
-
-
Save sagebind/5613551 to your computer and use it in GitHub Desktop.
PHP trait that gives classes property accessor functionality.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use LogicException; | |
use BadMethodCallException; | |
trait Accessors | |
{ | |
/** | |
* Gets the value of a property. | |
* | |
* @param string $name | |
* The name of the property. | |
* | |
* @return mixed | |
* The value of the property. | |
* | |
* @throws LogicException | |
* Thrown if the property is write-only or does not exist. | |
*/ | |
final public function __get($name) | |
{ | |
// check if the property has a getter | |
if (method_exists($this, "get_$name")) | |
{ | |
// call the getter | |
return call_user_func(array($this, "get_$name")); | |
} | |
// check if the property has a setter | |
else if (method_exists($this, "set_$name")) | |
{ | |
throw new LogicException("Member variable '$name' is write only."); | |
} | |
// non-existent property | |
else | |
{ | |
throw new LogicException("Member variable '$name' does not exist."); | |
} | |
} | |
/** | |
* Sets the value of a property. | |
* | |
* @param string $name | |
* The name of the property. | |
* | |
* @param mixed $value | |
* The value to set the property to. | |
* | |
* @return void | |
* | |
* @throws LogicException | |
* Thrown if the property is read only or does not exist. | |
*/ | |
final public function __set($name, $value) | |
{ | |
// check if the property has a setter | |
if (method_exists($this, "set_$name")) | |
{ | |
// set value | |
call_user_func(array($this, "set_$name"), $value); | |
} | |
// property is read only | |
else if (method_exists($this, "get_$name")) | |
{ | |
throw new LogicException("Member variable '$name' is read only."); | |
} | |
// non-existent property | |
else | |
{ | |
throw new LogicException("Member variable '$name' does not exist."); | |
} | |
} | |
/** | |
* Checks if a property is set. | |
* | |
* @param string $name | |
* The name of the property. | |
* | |
* @return bool | |
* True if the property is set, otherwise false. | |
*/ | |
final public function __isset($name) | |
{ | |
// check if the property has a getter | |
if (method_exists($this, "get_$name")) | |
{ | |
return $this->__get($name) !== null; | |
} | |
return false; | |
} | |
/** | |
* Unsets a property by setting its value to null. | |
* | |
* @param string $name | |
* The name of the property. | |
* | |
* @return void | |
*/ | |
final public function __unset($name) | |
{ | |
$this->__set($name, null); | |
} | |
/** | |
* Handles method calls that do not point to a function. | |
* | |
* Also fixes PHP bug where invoking a callable property causes an exception. | |
* | |
* @param string $name | |
* The name of the invalid method. | |
* | |
* @param mixed[] $args | |
* Arguments passed to the method. | |
* | |
* @return mixed | |
* The return value of the method called. | |
* | |
* @throws BadMethodCallException | |
* Thrown if a property isn't callable or the method doesn't exist. | |
*/ | |
final public function __call($name, $args) | |
{ | |
// trying to invoke a property | |
if (property_exists($this, $name) || method_exists($this, "get_$name")) | |
{ | |
$value = $this->$name; | |
// fix for invoking callable objects as properties | |
if (is_object($value) && method_exists($value, '__invoke')) | |
{ | |
return call_user_func_array(array($value, '__invoke'), $args); | |
} | |
// a callable name or function | |
else if (is_callable($value)) | |
{ | |
return call_user_func_array($value, $args); | |
} | |
// the property isn't callable | |
else | |
{ | |
throw new BadMethodCallException("The property '$name' is not callable."); | |
} | |
} | |
// method doesn't exist | |
throw new BadMethodCallException("Method '$name' does not exist."); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment