3

I am attempting to write a "listener" on a variable in a class I cannot modify. I am extending the class in question, unsetting the properties I want to listen to, and then using __set to intercept writes to that variable. At that point I compare with the previous version and report if there are changes.

class A {
    var $variable;

    ...
}

class B extends A {
    var $new_variable

    function __construct() {
        parent::__construct();
        unset($this->variable);
    }

    function __set($thing, $data) {
        if ($thing == 'variable') {
            // Report change
            // Set $new_variable so we can use __get on it
        }
    }

    public function __get($var) {
        if (isset($this->$var)) {
            // Get as normal.
            return $this->$var;
        } elseif ($var == 'variable' && isset($this->new_variable)) {
            return $this->new_variable;
        }
    }

    ...
}

This works if I modify the class in question directly instead of via an extended class, removing the declaration of the variable and introducing the setter and getter methods. The problem is when I use the pattern shown above, the unset() call does not seem to actually remove the variables inherited from the parent class, thus rendering the __set method unable to intercept the variable's value.

So far this seems to me to be the only way I can watch the variables changes, but I do not want to hack the core of the framework, only inspect it's handy work (a parser). Is there a possibility of making this work, or another way to approach this problem?

PeeHaa
  • 71,436
  • 58
  • 190
  • 262
epocsquadron
  • 303
  • 5
  • 9
  • It turns out that part of the issue, but not all of it, was that I was using property_exists() in the __get method instead of isset() to check for the existence of a property. – epocsquadron Feb 07 '13 at 23:18

1 Answers1

2

Mmm, this is weird. The following code works fine:

class A 
{
    var $variable;
}

class B extends A 
{
    var $new_variable;

    function __construct() 
    {
        unset($this->variable);
    }

    function __set($thing, $data) 
    {
        if ($thing == 'variable') 
        {
        echo "\nThe variable value is '" . $data . "'\n";
        }
    }
}

$b = new B();
$b->variable = 'Intercepted'; //Output: The variable value is 'Intercepted'
$b->new_variable = 'Not intercepted'; // No output

Can you tell me if this piece of code does what you need and, if it doesn't, what would you need instead?

HTH

Andrés Fortier
  • 1,705
  • 11
  • 12
  • This example does indeed work for me, but when specifically applied to my codebase it does not. I have slowly added back logic to the point of nearly having the same code. The test example works, while the real code does not. I am still investigating what may be different.. – epocsquadron Feb 07 '13 at 23:12
  • I have tracked down the issue to my overloaded class being replaced with an instance of the parent class. Seems it worked all along. I am accepting your answer that there is nothing wrong with it. :) – epocsquadron Feb 08 '13 at 21:36
  • Ok, thanks. While I wasn't of much help, I'm glad you find the problem :) – Andrés Fortier Feb 12 '13 at 16:10