2010-05-12 73 views
0

我使用了__get()__set()魔術方法來攔截對某些私有屬性的外部調用,而無需爲每個屬性編寫setter和getter。到目前爲止好:在私有屬性上調用empty()

<? 

class Foo{ 
    private $id; 
    private $info = array(); 
    private $other; 

    public function __set($name, $value){ 
     switch($name){ 
      case 'id': 
      case 'info': 
       return $this->$name = $value; 
       break; 
      default: 
       throw new Exception('Attribute "' . $name . '" cannot be changed from outside the class'); 
     } 
    } 

    public function __get($name){ 
     switch($name){ 
      case 'id': 
      case 'info': 
       return $this->$name; 
       break; 
      default: 
       throw new Exception('Attribute "' . $name . '" cannot be read from outside the class'); 
     } 
    } 
} 

$MyFoo = new Foo; 

$MyFoo->id = 33; 
$MyFoo->info = array (
    'item_id' => '20', 
    'issue' => '53', 
); 
try{ 
    $MyFoo->other = 44; 
}catch(Exception $e){ 
    echo 'Exception raised as expected: ' . $e->getMessage(); 
} 

?> 

現在我需要測試某些屬性(數組)是否仍然空。我意識到,empty($MyFoo->info)總是false所以我在手冊中擡起頭來,我發現__isset()

__isset()被調用isset()函數或空()在人跡罕至 屬性觸發。

但是,我不清楚我應該如何在我的代碼中實現__isset()。我想它應該返回true或false,但是......我可以區分是通過empty()還是通過isset()來呼叫?

回答

2

你需要做的是這樣:

public function __isset($name) { 
    return isset($this->$name); 
} 

在這種情況下isset($MyFoo->info)empty($MyFoo->info)會達到預期效果:

// isset($MyFoo->info) --> true 
// empty($MyFoo->info) --> false 
$MyFoo->info = array(1, 2, 3); 

// isset($MyFoo->info) --> true 
// empty($MyFoo->info) --> true 
$MyFoo->info = array(); 

// isset($MyFoo->info) --> false 
// empty($MyFoo->info) --> true 
$MyFoo->info = null; 
+0

你是對的。看起來empty()觸發__isset(),但它不直接使用它的返回值。 – 2010-05-12 09:08:04

+0

empty()首先調用__isset(),如果它返回true,則__get()檢查現有屬性的值是否爲空。 – 2010-05-12 09:24:11