views:

150

answers:

4

How can i perform a function once a variable's value has been set?

say like

$obj = new object(); // dont perform $obj->my_function() just yet
$obj->my_var = 67    // $obj->my_function() now gets run

I want the object to do this function and now having to be called by the script.

Thanks

EDIT my_var is predefined in the class, __set is not working for me.

+10  A: 

I'd recommend to create a setter function for $obj and include the relevant function call there. So basically your code would look somehow like this:

$obj = new ClassOfYours();
$obj->setThatValue("apple");

Of course you would have to take care that all assignments to ThatValue need to be done through that setter in order make it work properly. Assuming that you're on php5 I'd set that property to private, so all direct assignments will cause an runtime error.

A good overview about OOP in php can be found in this article on devarticles.com.

HTH

KB22
I agree, this is a cleaner way to do it.
gnud
+1 no funky magic, please
stereofrog
+3  A: 

To acheive exactly what you describe, you'd have to use a magic setter.

class ObjectWithSetter {

    var $data = array();

    public function my_function() {
        echo "FOO";
    }


    public function __set($name, $value) {
        $this->data[$name] = $value;
        if($name == 'my_var') {
            $this->my_function();
        }
    }

    public function __get($name) {
        if (array_key_exists($name, $this->data)) {
            return $this->data[$name];
        }
        $trace = debug_backtrace();
        trigger_error(
            'Undefined property via __get(): ' . $name .
            ' in ' . $trace[0]['file'] .
            ' on line ' . $trace[0]['line'],
            E_USER_NOTICE);
        return null;
    }

    /**  As of PHP 5.1.0  */
    public function __isset($name) {
        return isset($this->data[$name]);
    }

    public function __unset($name) {
        unset($this->data[$name]);
    }

}
gnud
This method is not very transparent.I suggest that you use a normal, non-magic setter function instead (like several others suggested).
gnud
A: 

Assuming you want to call my_function() once you set a value, that case you can encapsulate both the operations into one. Something like you create a new function set_my_var(value)

function set_my_var(varvalue)
{
$this->my_var = varvalue;
$this->my_function();
}
Anirudh Goel
+12  A: 

Use a private property so __set() is invoked:

class Myclass {
  private $my_var;
  private $my_var_set = false;

  public function __set($var, $value) {
    if ($var == 'my_var' && !$this->my_var_set) {
      // call some function
      $this->my_var_set = true;
    }
    $this->$var = $value;
  }

  public function __get($var, $value) {
    return $this->$name;
  }
}

See Overloading. __set() is called because $my_var is inaccessible and there is your hook.

cletus
+1. see http://php.net/__set for details on the magic __set() method.
ax
Thanks. setters seem to be the best method. Could this be expanded so the function gets run once 3 variables are set? var_a, var_b and var_c? Once all of those are set run a function?
dotty
Sure, you could put any logic in there you like.
cletus
thanks. Can you take a look at the edit in the original question. It seems that __set() does not work because the variable is already predefined.
dotty
It won't work if my_var is accessible either because it is public or you are accessing it within the class (and thus have private access). My guess is it's public. You'll note I deliberately set it private in my example.
cletus