Search code examples
phpoopinheritancemagic-methods

PHP properties with get/set functions


One of the handy features of other languages is the ability to create get and set methods for properties. In trying to find a good way to duplicate this functionality in PHP, I stumbled across this: http://www.php.net/manual/en/language.oop5.magic.php#98442

Here is my breakdown of that class:

<?php

class ObjectWithGetSetProperties {

    public function __get($varName) {
        if (method_exists($this,$MethodName='get_'.$varName)) {
            return $this->$MethodName();
        } else {
            trigger_error($varName.' is not avaliable .',E_USER_ERROR);
        }
    }

    public function __set($varName,$value) {
        if (method_exists($this,$MethodName='set_'.$varName)) {
            return $this->$MethodName($value);
        } else {
            trigger_error($varName.' is not avaliable .',E_USER_ERROR);
        }
    }

}

?>

My plan was to extend this class and define the appropriate get_someproperty() and set_someproperty() in this extended class.

<?php
class SomeNewClass extends ObjectWithGetSetProperties {
    protected $_someproperty;
    public function get_someproperty() {
        return $this->_someproperty;
    }
}
?>

The trouble is, the base class of ObjectWithGetSetProperties is unable to see my method get_someproperty() in SomeNewClass. I always get the error, "key is not available".

Is there any way to resolve this, allowing the base class of ObjectWithGetSetProperties to work, or will I have to create those __get() and __set() magic methods in each class?


Solution

  • Try is_callable instead. Example code-fragment:

    <?php
    date_default_timezone_set("America/Edmonton");
    class A {
        protected $_two="goodbye";
        protected $_three="bye";
        protected $_four="adios";
        public function __get($name) {
            if (is_callable(array($this,$m="get_$name"))) {
                return $this->$m();
            }
            trigger_error("Doh $name not found.");
        }
        public function get_two() {
            return $this->_two;
        }
    }
    class B extends A {
        protected $_one="hello";
        protected $_two="hi";
        protected $_three="hola";
        public function get_one() {
            return $this->_one;
        }
        public function get_two() {
            return $this->_two;
        }
        public function get_three() {
            return $this->_three;
        }
        public function get_four() {
            return $this->_four;
        }
    }
    
    $a=new a();
    echo $a->one."<br />";//Doh one not found.
    echo $a->two."<br />";//goodbye
    echo $a->three."<br />";//Doh three not found.
    echo $a->four."<br />";//Doh four not found.
    $b=new b();
    echo $b->one."<br />";//hello
    echo $b->two."<br />";//hi
    echo $b->three."<br />";//hola
    echo $b->four."<br />";//adios
    ?>
    

    (Updated to show where B overrides A)