Skip to content

Instantly share code, notes, and snippets.

@texdc
Last active August 29, 2015 14:13
Show Gist options
  • Save texdc/5fea2f84a3e408824e91 to your computer and use it in GitHub Desktop.
Save texdc/5fea2f84a3e408824e91 to your computer and use it in GitHub Desktop.
<?php
/**
* Allows value objects to expose their properties while maintaining immutability.
*
* Inject your properties in your constructor.
* Define your properties in the docblock for your class with {@code @property}.
* Mutability is just a bug waiting to happen.
*/
abstract class Value
{
/**#@+
* Error messages
*
* @var string
*/
private static $PRIVATE_PROPERTY = "Cannot access private property";
private static $UNDEFINED_PROPERTY = "Undefined property:";
/**#@- */
/**
* Magic getter
*
* @param string $aProperty
*/
final public function __get($aProperty)
{
if (property_exists($this, $aProperty)) {
return $this->{$aProperty};
}
$this->triggerError(static::$UNDEFINED_PROPERTY, $aProperty);
}
/**
* Magic setter
*
* @param string $aProperty
* @param mixed $aValue
*/
final public function __set($aProperty, $aValue)
{
if (property_exists($this, $aProperty)) {
$this->triggerError(static::$PRIVATE_PROPERTY, $aProperty);
}
$this->triggerError(static::$UNDEFINED_PROPERTY, $aProperty);
}
/**
* Trigger an {@code ErrorException}
*
* @param string $aMessage
* @param string $aProperty
* @throws ErrorException
*/
private function triggerError($aMessage, $aProperty)
{
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
$aMessage = sprintf($aMessage . " %s::$%s", __CLASS__, $aProperty);
throw new ErrorException($aMessage, 0, E_USER_NOTICE, $backtrace[1]['file'], $backtrace[1]['line']);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment