views:

29

answers:

3

Hello. Im' wondering if this is possible:

I've successfully used __set() magic method to set values to properties of a class:

class View
{
    private $data;

    public function __set( $key, $value )
    {
         $this->data[$key] = $value;
    }
}

So I'm able to:

$view = new View();
$view->whatever = 1234;

The problem comes when I want to concatenate a string for example. It seems like __set() is not being called (it's not being called in fact).

$view = new View();
$view->a_string = 'hello everybody';    //Value is set correctly

$view->a_string.= '<br>Bye bye!';       //Nothing happens...

echo $view->a_string;

This outputs "hello everybody". I'm not able to execute __set() in the second assignment. Reading php.net it says that:

__set() is run when writing data to inaccessible properties.

So as *a_string* already exists, __set is not called. My question finally is... how could I achieve that concatenation operation??

Note: Ok... Murphy came and gave me the answer as soon as I posted this...

The answer (As I understood), is that PHP is not able to decide if *a_string* is available as I didn't defined a __get() method.

Defining __get() allows php to find the current value of *a_string*, then uses __set() to concatenate the value.

+4  A: 

You should add a __get() method that allows you to access inaccessable properties just as you did with __set(). You could then do the following:

$view->myvar = $view->myvar.'Added text.';

The __get() method would be:

public function __get($var) {
  return (isset($this->data[$var])) ? $this->data[$var]: '';
}
Mitch C
Yeah, I saw this after editing my post.
clinisbut
I must have dropped this in right as you were editing it.
Mitch C
On a side note: returning NULL rather then an empty string seems more appropriate.
Wrikken
A: 

It's because __set() is a method and not a string. If you want it to "act" like a string you can change it to this.

class View
{
    private $data;

    public function __set( $key, $value )
    {
        if (empty($this->data[$key])) {
            $this->data[$key] = $value;
        } else {
            $this->data[$key] .= $value;
        }
    }
}
Viper_Sb
+1  A: 

FYI, for simple assignment, magic methods aren't even necessary.

class A {

}

$a = new A();

$a->str = '1';
$a->str .= '2';
echo $a->str;  // outputs 12

This will work just fine as PHP will create the new properties through assignment. __set/get usually is used when additional checks/code need to be run on the values.

webbiedave
I need magic method here because I is a MUST to store the data inside $data member.
clinisbut