2015-11-07 30 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