2015-11-07 63 views
2

我目前正在制作一个基于对象的API。我有一个叫做Part的抽象类,每个孩子都可以扩展。 Part有一个__set函数,该函数将值存储在名为$attributes的受保护数组中。但是,当我做$part->user = new User(etc...);它不运行__set函数。这里是我的代码:PHP __神奇的方法不被调用

部分:

<?php 

namespace Discord; 

abstract class Part 
{ 
    protected $attributes = []; 

    public function __construct(array $attributes) 
    { 
     $this->attributes = $attributes; 

     if (is_callable([$this, 'afterConstruct'])) { 
      call_user_func([$this, 'afterConstruct']); 
     } 
    } 

    /** 
    * Handles dynamic get calls onto the object. 
    * 
    * @param string $name 
    * @return mixed 
    */ 
    public function __get($name) 
    { 
     $str = ''; 

     foreach (explode('_', $name) as $part) { 
      $str .= ucfirst($name); 
     } 

     $funcName = "get{$str}Attribute"; 

     if (is_callable([$this, $funcName])) { 
      return call_user_func([$this, $funcName]); 
     } 

     if (!isset($this->attributes[$name]) && is_callable([$this, 'extraGet'])) { 
      return $this->extraGet($name); 
     } 

     return $this->attributes[$name]; 
    } 

    /** 
    * Handles dynamic set calls onto the object. 
    * 
    * @param string $name 
    * @param mixed $value 
    */ 
    public function __set($name, $value) 
    { 
     echo "name: {$name}, value: {$value}"; 
     $this->attributes[$name] = $value; 
    } 
} 

客户:

<?php 

namespace Discord\Parts; 

use Discord\Part; 
use Discord\Parts\User; 

class Client extends Part 
{ 
    /** 
    * Handles extra construction. 
    * 
    * @return void 
    */ 
    public function afterConstruct() 
    { 
     $request = json_decode($this->guzzle->get("users/{$this->id}")->getBody()); 

     $this->user = new User([ 
      'id'  => $request->id, 
      'username' => $request->username, 
      'avatar' => $request->avatar, 
      'guzzle' => $this->guzzle 
     ]); 
    } 

    /** 
    * Handles dynamic calls to the class. 
    * 
    * @return mixed 
    */ 
    public function __call($name, $args) 
    { 
     return call_user_func_array([$this->user, $name], $args); 
    } 

    public function extraGet($name) 
    { 
     return $this->user->{$name};  
    } 
} 

当我创建的Client一个新实例,它会自动创建一个User实例,并设置它。但是,我在__set中测试了代码,并且它不运行。

任何帮助表示赞赏。

谢谢

回答

3

The __set magic method is called only when a property is inaccessible from the context in which it is set。因为Client延伸PartPart的属性都可以在Client访问,所以魔术方法是不需要的。

+0

谢谢,但仍然有点困惑。我怎么能解决这个问题? – cheese5505

+1

@ cheese5505这取决于你需要做什么。你可以使用(1)一个特定于属性的setter,(2)一个通用的setter,它接受一个属性名和一个值,或者(3)一个容器或者某种类型的包装器,在'Part'上运行,如果你真的需要神奇的方法来工作。 –

+0

我需要能够运行'$ client-> user'来检索'$ client-> attributes ['user']'以及'$ client-> user = etc'来设置'$ client-> attributes [ '用户']'。这将是我最好的选择?你能不能指出我做这件事的方向?谢谢! – cheese5505