2009-04-28 53 views
6

我正在構建一個包含多個輸入驗證的類,並且我決定將它們放在一個__set方法中(我不確定這是否合適,因爲我限制了它OOP經驗)。這似乎工作正常,從類外部傳遞無效值時拋出適當的錯誤。但是,如果一個變量在類中被修改,那麼_ _set方法似乎被全部忽略。PHP忽略類中的__set方法

任何瞭解將非常理解

//RESULT::::::::::::::::::::::::::::::: 
// PASS: Testing : hello 
// PASS: Testing exception handling 
// __SET: Setting b to 123 
// PASS: Testing with valid value: 123 
// FAIL: Testing exception handling World2 



<?php 
class Test { 
     public $a; 
     private $b; 

     function __set($key, $val) { 

       switch($key) { 
         case 'b': 
           if(!is_numeric($val)) throw new Exception("Variable $b must be numeric"); 
           break; 
       } 

       echo ("__SET: Setting {$key} to {$val}<br/>"); 
       $this->$key = $val; 
     } 
     function __get($key) { return $this->$key; } 
     function bMethod() { 
       $this->b = "World2"; 
     } 

} 

$t = new Test(); 

//testing a 
try { 
     $t->a = "hello"; 
     echo "PASS: Testing $a: {$t->a}<br/>"; 
} catch(Exception $e) { 
     echo "FAIL: Testing $a"; 
} 

//testing b 
try { 
     $t->b = "world";  
     echo "FAIL: Testing $b exception handling<br/>"; 
} catch(Exception $e){ 
     echo "PASS: Testing $b exception handling<br/>"; 
} 

//testing b with valid value 
try { 
     $t->b = 123; 
     echo "PASS: Testing $b with valid value: {$t->b}<br/>"; 
} catch(Exception $e) { 
     echo "FAIL: Testing $b"; 
} 

//bypassing exception handling with method 
try { 
     $t->bMethod("world"); 
     echo "FAIL: Testing $b exception handling {$t->b}<br/>"; 
} catch(Exception $e) { 
     echo "PASS: Testing $b exception handling<br/>"; 
} 
+0

這有我大感迷惑了至少一小時。 – Jonathan 2015-11-25 15:59:18

回答

10

閱讀__set的定義:「__set()中寫入數據時,以不可訪問的成員運行」。無法訪問是關鍵。在班級內,所有成員都可以訪問,並且__set被繞過。 Overloading

+0

不幸的是今天我在出票,但這是正確的。我遇到了這個問題,試圖模仿其他語言的getter/setter。它只是不起作用。 – zombat 2009-04-28 19:00:22

6

該文檔在php documentation說:

__get()被用於從不可訪問的成員讀取數據。

所以,你可以這樣做:

<?php 
class Test { 
    private $_params = array(); 

    function __set($key, $val) { 
     ... 
     $this->_params[$key] = $val; 
    } 

    function __get($key) { 
     if (isset($this->_params[$key])) return $this->$key; 
     throw Exception("Variable not set"); 
    } 

    ... 
} 
+0

這感覺就像是一種黑客攻擊,但它實際上正是我想要做的;類方法內的變量調用不能直接調用變量,因此它們使用__set和__get函數。 謝謝! – thatcanadian 2009-04-28 19:21:37