Created
February 8, 2012 14:12
-
-
Save firegate666/1769855 to your computer and use it in GitHub Desktop.
magic property getter example with internal xml storage
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 | |
/** | |
* Example class that holds an xml and adds magic getter and property accessors for xml nodes | |
* The class property annotations define type casts | |
* | |
* @property integer username | |
* @property string password | |
* @property array collection | |
* @property array car | |
* | |
* @author behnke | |
* | |
*/ | |
class Proptest | |
{ | |
protected $false = false; | |
public function getFalse() | |
{ | |
return $this->false; | |
} | |
/** | |
* | |
* @var SimpleXMLElement | |
*/ | |
protected $xml = null; | |
protected static $propMapping = null; | |
public function __construct() | |
{ | |
$this->xml = simplexml_load_string('<?xml version="1.0"?><user><username protected="true">123456</username><password>jhdfH</password><car><drivers><driver>Stan</driver><driver>Mike</driver></drivers><type>Ford Focus</type><wheels>4</wheels></car><collection><name>tes2t</name><name>test</name><value>foobar</value></collection></user>'); | |
} | |
/** | |
* get property type | |
* | |
* @param String $name | |
* @return String | |
*/ | |
protected static function __get_xmlPropertyType($name) | |
{ | |
if (is_null(static::$propMapping)) | |
{ | |
static::$propMapping = array(); | |
$refclass = new ReflectionClass(get_called_class()); | |
$props = $refclass->getDocComment(); | |
preg_match_all('/@property (\w+) (\w+)/', $props, $matches, PREG_SET_ORDER); | |
foreach($matches as $match) | |
{ | |
static::$propMapping[$match[2]] = $match[1]; | |
} | |
} | |
if (isset(static::$propMapping[$name])) | |
{ | |
return static::$propMapping[$name]; | |
} | |
else | |
{ | |
return null; | |
} | |
} | |
/** | |
* magic getter for xml properties | |
* | |
* @param String $function | |
* @param array $args | |
*/ | |
public function __call($function, $args) | |
{ | |
if (substr($function, 0, 3) == 'get') | |
{ | |
$property = lcfirst(substr($function, 3)); | |
return $this->__get_xmlProperty($property, true); // delegate | |
} | |
} | |
/** | |
* tests if xml property exists | |
* | |
* @param String $name | |
* @retun boolean | |
*/ | |
protected function __has_xmlProperty($name) | |
{ | |
return isset($this->xml->$name); | |
} | |
/** | |
* magic xml property access with typecast | |
* | |
* @param String $name | |
* @param boolean $protectedAllowed override protected | |
* @throws Exception if property is protected | |
* @return mixed | |
*/ | |
protected function __get_xmlProperty($name, $protectedAllowed = false) | |
{ | |
$type = static::__get_xmlPropertyType($name); | |
$value = $this->xml->$name; | |
if (!$protectedAllowed && isset($value['protected']) && $value['protected'] == 'true') | |
{ | |
throw new Exception(sprintf('Undefined or protected property %s of class %s', $name, get_called_class())); | |
} | |
settype($value, $type); | |
return $value; | |
} | |
/** | |
* magic xml property access | |
* | |
* @uses Proptest::__get_xmlProperty(String, boolean) | |
* @param String $name | |
* @throws Exception if property is protected or does not exist | |
* @return mixed | |
*/ | |
public function __get($name) | |
{ | |
if ($this->__has_xmlProperty($name)) | |
{ | |
return $this->__get_xmlProperty($name); | |
} | |
else | |
{ | |
throw new Exception(sprintf('Undefined or protected property %s of class %s', $name, get_called_class())); | |
} | |
} | |
} | |
function printOut($name, $value) | |
{ | |
printf("%s: %s\n", $name, var_export($value, true)); | |
} | |
$test = new Proptest(); | |
printOut('getCar', $test->getCar()); | |
printOut('collection', $test->collection); | |
try { | |
printOut('username', $test->username); // this one fails, xml protected property | |
} catch(Exception $e) { printOut('exception', $e->getMessage());} | |
printOut('getUsername', $test->getUsername()); | |
printOut('password', $test->password); | |
printOut('getFalse', $test->getFalse()); | |
try { | |
printOut('false', $test->false); // this one fails, object protected property | |
} catch(Exception $e) { | |
printOut('exception', $e->getMessage()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment