2016-12-24 62 views
1

我有一個類的下列鏈:設置屬性遞歸

class A extends Model { 
    public $first; 
    public $b; 
    public function __construct() { 
    $this -> b = new B(); 
    } 
} 

class B extends Model { 
    public $c; 
    public function __construct() { 
    $this -> c = new C(); 
    } 
} 

class C extends Model { 
    public $foo; 
} 

我想編寫一個函數,將設置基於一些參數的屬性值,例如,如果我將它稱爲對對象A和通過array('b_c_foo' => 'something')到它,我想$a -> b -> c -> foo = 'something'被設置。

例如:

$a = new A(); 
$params = array(
    'first' => 'first', 
    'b_c_foo' => 'something' 
); 
$a -> fillAttributes($params); 
var_dump($a); // here A object should have first == 'fist', and b -> c -> foo == 'something' 

我已經寫了這樣的功能僅用於A類,這很容易,因爲我能夠找到數組索引,並將其設置爲A類像$this -> {$index} = $value;,但它不是那麼容易,如果通話次數是動態的。

我該怎麼做?

回答

1

喜歡的東西

public function fillAttributes(array $params) 
{ 
    foreach ($params as $attributeName => $attributeValue) { 
     $rootObject = $this; 

     foreach(explode('_', $attributeName) as $proprietyName) { 
       if (property_exists($rootObject, $proprietyName)) { 
        if (is_object($rootObject->$proprietyName)) { 
         $rootObject = $rootObject->$proprietyName; 
        } 
       } 
     } 

     $rootObject->$proprietyName = $attributeValue; 
    } 
} 

基本上你explode字符串,並檢查是否存在使用該名稱的適當性,並且它不是一個對象。只有這樣你才能設定值。