Guest User

PHP property overloading

a guest
Dec 19th, 2010
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 3.57 KB | None | 0 0
  1. <?php
  2. /*
  3.  
  4.   Author by Kay Sackey
  5.   Many thanks to http://latrine.dgx.cz/property-setters-and-getters-final-solution            
  6.   PHP Property overloading
  7.  
  8.  
  9. class ATest extends Magic {
  10.    // After the constructor fires this property is 'hidden', but you can access it directly through $_myAttribute
  11.    protected $myAttribute = property;
  12.  
  13.  
  14.    public function __construct(){
  15.       parent::__construct();  // Remember to call the Magic constructor first if your class defines a constructor
  16.    }
  17.  
  18. //      I use public functions for getters and setters because I only use this class to transition from class attributes towards getters/setters
  19. //      You can use it anyway you like.
  20.    
  21. //     If you don't define a getter or a setter then he object attribute will behave just as you expect it.
  22. //     e.g. $class->a = 5
  23.  
  24.    public function getMyAttribute(){
  25.        // Do some complex logic to get the attribute
  26.        return 0;
  27.    }
  28.  
  29.    public function setMyAttribute(){
  30.        // Do some complex logic to set the attribute
  31.    }
  32.  
  33.  
  34. */
  35.  
  36. //
  37. // This has only been updated to not throw a notice under E_STRICT, and to make it easier to integrate into existing classes
  38.  
  39. // define new "like-keyword"
  40. // value is short and unusual string
  41. define('property',   "\0\0");
  42.  
  43. class Magic{
  44.  
  45.     // magic
  46.     protected $_props;
  47.  
  48.     /**
  49.     * Universal setter.
  50.     *
  51.     * If property 'abc' is declared,
  52.     * there must be setAbc() setter,
  53.     * otherwise property is read-only
  54.     */
  55.     final private function __set($name, $value)
  56.     {
  57.         if (isset($this->_props[$name]))
  58.           if (method_exists($this, 'set'.$name))
  59.             $this->{'set'.$name}($value);
  60.           else
  61.             throw new Exception("Property '$name' is read-only.");
  62.         elseif($name[0] === '_')
  63.                 $this->$name = $value;
  64.         else
  65.             throw new Exception("Undefined property '$name'.");
  66.     }
  67.  
  68.     /**
  69.     * Universal getter.
  70.     *
  71.     * If property 'abc' is declared,
  72.     * there must be getAbc() getter,
  73.     * otherwise variable $_abc
  74.     */
  75.     final private function __get($name)
  76.     {
  77.      
  78.         if (isset($this->_props[$name]))
  79.           if (method_exists($this, 'get'.$name))
  80.             return $this->{'get'.$name}();
  81.           else
  82.             return $this->{'_'.$name};
  83.         else
  84.           throw new Exception("Undefined property '$name'.");
  85.     }
  86.  
  87.     final private function __isset($name)
  88.     {
  89.         return isset($this->_props[$name]);
  90.     }
  91.  
  92.     final private function __unset($name)
  93.     {
  94.         unset($this->_props[$name]);
  95.     }  
  96.  
  97.     final private function _property($obj)
  98.     {
  99.       // use cache (analyze object only once)
  100.       static $cache;
  101.       $item = & $cache[ get_class($obj) ];
  102.  
  103.       // look for properties
  104.       // 1) get_object_vars prevents ObjectIteration
  105.       // 2) outside of objects returns only public members (speed-up)
  106.          
  107.       if ($item === NULL) {          
  108.         $item = array();
  109.         foreach (get_object_vars($obj) as $name => $value){
  110.           if ($value === property) {
  111.             $item[$name] = true;
  112.             unset($obj->$name);
  113.             $obj->{'_'.$name} = null;          
  114.           }        
  115.         }  
  116.         return $item;
  117.       }
  118.  
  119.          
  120.       foreach ($item as $name => $foo){
  121.         unset($obj->$name);
  122.         $obj->{'_'.$name} = null;  
  123.       }
  124.        
  125.  
  126.       return $item;
  127.     }  
  128.    
  129.     function __construct()
  130.     {
  131.         // property initialization
  132.         $this->_props = self::_property($this);
  133.     }
  134.    
  135.    
  136. }
Advertisement
Add Comment
Please, Sign In to add comment