2010-09-13 254 views
0

林”想知道如果这是可能的:__set和字符串连接

我已经成功地使用__set()魔术方法将值设置为一个类的属性:

class View 
{ 
    private $data; 

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

所以我能到:

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

问题来了,当我想连接一个字符串为例。看起来__set()没有被调用(事实上它没有被调用)。

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

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

echo $view->a_string; 

这输出“大家好”。我无法在第二个任务中执行__set()。 阅读php.net它说:

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

因此,作为对a_string已经存在,__set没有被调用。 我的问题最后是...我怎么能实现这个连接操作?

注: 好吧......墨菲走过来,只要我这贴给我的答案...

答案(我的理解),是PHP是不能够决定是否a_string可用,因为我没有定义__get()方法。

定义__get()允许php找到当前值a_string,然后使用__set()连接该值。

回答

4

您应该添加一个__get()方法,该方法允许您像访问__set()一样访问不可访问的属性。然后,您可以执行以下操作:

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

的__get()方法是:

public function __get($var) { 
    return (isset($this->data[$var])) ? $this->data[$var]: ''; 
} 
+0

是的,编辑我的帖子后我看到了这个。 – 2010-09-13 21:24:57

+0

我必须在编辑它时正确放弃这一点。 – 2010-09-13 21:29:25

+1

在旁注:返回NULL而不是空字符串似乎更合适。 – Wrikken 2010-09-14 00:26:34

0

这是因为__set()是一种方法,而不是一个字符串。如果你想让它像一个字符串一样“行动”,你可以改变它。

class View 
{ 
    private $data; 

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

仅供参考,对于简单的任务,魔术方法甚至没有必要的。

class A { 

} 

$a = new A(); 

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

这将工作得很好,因为PHP将通过分配创建新属性。当需要在值上运行额外的检查/代码时,通常会使用__set/get。

+0

我需要神奇的方法,因为我必须将数据存储在$ data成员中。 – 2010-09-14 05:52:13