Search code examples
phpyiimagic-methods

__get doesn't work twice for some name


I know it's a strange setup but I'm trying to avoid some magic Yii so much loves.

class myActiveRecord extends CActiveRecord
{
    public function __get($name) {
        $method = 'get' . ucfirst($name);
        if(method_exists($this, $method)) {
            $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
            foreach($backtrace  as $b) {
                if($b['function'] == $method) {
                    return parent::__get($name);
                }
            }

            return $this->$method();
        }

        return parent::__get($name);
    }
}

class test extends myActiveRecords
{

    public function getParty()
    {
        return $this->party;
    }
}

$test = new test();
echo $test->party;

I would like it that if Yii calls $test->party it doesn't just look for the attribute but first goes through my getFunction() even if my getFunction just returns the attribute. (in Yii the attributes are never defined as a property but always go through __get()

When I call $test->getParty() it works like a charm, however when Yii does this $test->party it does not, the following happens:

$this->party calls magic __get(), which calls the function getParty(). But then when the function getParty does again $this->party the magic function is not called a second time but I get an undefined property error. I have a way around but I prefer not to use it and that's this function:

function getParty()
{
    return self::__get('party');
}

The reason I start to work like this is because I like get and set methods, I get shivers when I see public properties used like that and also because I'm stuck with legacy code that was not written in english so often I do this, which does work like a charm, just not when the magic function for the same name is called twice:

public function getParty()
{
    return $this->feest;
}

Does anyone know the reason? or am I just wrong?


Solution

  • The reason is this could lead to infinite call to __get() method. Yes, you might put in some logic that would prevent it. But php chooses not to allow developers to shoot themselves in the foot. For this reason, once inside __get() method, it's not called again.