2012-05-05 47 views
3

如何使用__get()在多級別對象屬性中返回null,以訪問如下所示的情況?如何使用__get()在多級別對象屬性訪問中返回null?

舉例來說,這是我的課,

class property 
{ 

    public function __get($name) 
    { 
     return (isset($this->$name)) ? $this->$name : null; 
    } 
} 


class objectify 
{ 

    public function array_to_object($array = array(), $property_overloading = false) 
    { 
     # if $array is not an array, let's make it array with one value of former $array. 
     if (!is_array($array)) $array = array($array); 

     # Use property overloading to handle inaccessible properties, if overloading is set to be true. 
     # Else use std object. 
     if($property_overloading === true) $object = new property(); 
      else $object = new stdClass(); 

     foreach($array as $key => $value) 
     { 
      $key = (string) $key ; 
      $object->$key = is_array($value) ? self::array_to_object($value, $property_overloading) : $value; 
     } 


     return $object; 

    } 
} 

我如何使用它,

$object = new objectify(); 

$type = array(
    "category" => "admin", 
    "person" => "unique", 
    "a"   => array(
     "aa" => "xx", 
     "bb"=> "yy" 
    ), 
    "passcode" => false 
); 


$type = $object->array_to_object($type,true); 
var_dump($type->a->cc); 

結果,

null 

,但我得到一個錯誤信息與空當輸入數組是null,

$type = null; 
$type = $object->array_to_object($type,true); 
var_dump($type->a->cc); 

結果,

Notice: Trying to get property of non-object in C:\wamp\www\test...p on line 68 
NULL 

是否有可能在這種情況下的返回NULL?

+1

PHP語言不知道多級對象,對象始終是一個單一的節點,它在上下文中訪問時對升序或降序節點一無所知。 – hakre

回答

0

您可以可以返回,而不是空的新屬性

public function __get($name) 
    { 
     return (isset($this->$name)) ? $this->$name : new property(); 
    } 
+0

感謝Vic給出答案。 – laukok

1

是的,但解釋如何並不那麼微不足道。首先明白,爲什麼你遇到這個問題:

$value = $a->b->c; 

這將首先用於$a->b返回NULL。所以,其實你寫道:

$value = NULL->c; 

所以不是NULL你需要返回一個NULL -object的設置的項目(讓我們namne它NULLObect),其工作原理類似於您的基類,並表示NULL。你可以想象,在PHP中你不能真正模擬NULL,而PHP的語言特性太有限,無法做到這一點。

但是,你可以嘗試接近我所描述的NULLObect

class property 
{ 

    public function __get($name) 
    { 
     isset($this->$name) || $this->$name = new NULLObject(); 
     return $this->$name; 
    } 
} 


class NULLObject extends Property {}; 

請注意,這可能不是你正在尋找的。如果它不符合您的需求,它可能是PHP是用於編程的錯誤語言,它可能是highjly。使用一些比PHP具有更好的成員重寫功能的語言。

相關問題:

+0

感謝您的解釋。我可以問我如何在上面的腳本中創建一個'NULLObect'?謝謝。 – laukok

+0

我不確定它是否對你有意義,但我用一個簡單的代碼示例擴展了答案。 – hakre

+0

感謝您的編輯。 – laukok

0

是的,我知道它已經4年前,但我有一個本週類似的問題,而當我試圖解決它,我發現這個線程。所以,這裏是我的解決方案:

class NoneWrapper 
{ 
    private $data; 

    public function __construct($object) 
    { 
     $this->data = $object; 
    } 

    public function __get(string $name) 
    { 
     return property_exists($this->data, $name) 
      ? new NoneWrapper($this->data->$name) 
      : new None; 
    } 

    public function __call($name, $arguments) 
    { 
     if (is_object($this->data)) { 
      return (property_exists($this->data, $name)) 
      ? $this->data->$name 
      : null; 
     } else { 
      return null; 
     } 
    } 

    public function __invoke() 
    { 
     return $this->data; 
    } 
} 

class None 
{ 
    public function __get(string $name) { 
     return new None; 
    } 

    public function __call($name, $arguments) 
    { 
     return null; 
    } 

    public function __invoke() 
    { 
     return null;  
    } 
} 

$object = new NoneWrapper(
    json_decode(
     json_encode([ 
      'foo' => [ 
       'bar' => [ 
        'first' => 1, 
        'second' => 2, 
        'third' => 3, 
        'fourth' => 4, 
       ], 
      ] 
     ]) 
    ) 
); 

var_dump($object->foo->bar->baz()); // null 
var_dump($object->foo->bar->third()); // 3