Skip to content

Instantly share code, notes, and snippets.

@sagebind
Created May 20, 2013 16:54
Show Gist options
  • Save sagebind/5613551 to your computer and use it in GitHub Desktop.
Save sagebind/5613551 to your computer and use it in GitHub Desktop.
PHP trait that gives classes property accessor functionality.
<?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