2011-10-23 50 views
4

我有一個使用方法鏈接的驗證類。我希望能夠做一個檢查,以TRUE/FALSE這樣的:鏈接方法時如何返回false

if ($obj->checkSomething()) {} 

而且鏈的方法是這樣的:

if ($obj->checkSomething()->checkSomethingElse()) {} 

然而,問題是,如果一個方法返回FALSE,也不會發送回一個對象,從而打破與此錯誤結束的方法鏈接:

Fatal error: Call to a member function checkSomething() on a non-object in ... 

我一定要挑無論是單方法返回CA lls或方法鏈接還是有解決方法嗎?

+2

這是一個很好的跡象,爲什麼你不應該使用方法鏈接:) – NikiC

回答

8

一個想法是設置一個內部標誌來指示成功或失敗,並通過另一種方法訪問它,同時在每個方法中檢查該標誌,並且如果它被設置則不做任何事情。例如: -

class A { 
    private $valid = true; 

    public function check1() { 
     if (!$this->valid) { 
      return $this; 
     } 
     if (!/* do actual checking here */) { 
      $this->valid = false; 
     } 
     return $this; 
    } 
    public function check2() { 
     if (!$this->valid) { 
      return $this; 
     } 
     if (!/* do actual checking here */) { 
      $this->valid = false; 
     } 
     return $this; 
    } 
    public function isValid() { 
     return $this->valid; 
    } 
} 

// usage: 

$a = new A(); 

if (!$a->check1()->check2()->isValid()) { 
    echo "error"; 
} 

爲了最小化樣板中的每個功能檢查,你也可以使用魔術方法__call()。例如: -

class A { 
    private $valid; 
    public function __call($name, $args) { 
     if ($this->valid) { 
      $this->valid = call_user_func_array("do" . $name, $args); 
     } 
     return $this; 
    } 
    private function docheck1() { 
     return /* do actual checking here, return true or false */; 
    } 
    private function docheck2() { 
     return /* do actual checking here, return true or false */; 
    } 
    public isValid() { 
     return $this->valid; 
    }  
} 

的用法是與上面相同:

$a = new A(); 

if (!$a->check1()->check2()->isValid()) { 
    echo "error"; 
} 
+0

+1打我。 –

+0

自己想過這件事,但希望能夠解決這個問題。將看看如果一些PHP大師提出了一個更簡單的解決方案,否則你的答案將被接受。謝謝! – Seralize

1

我相信你正在尋找有一個實例計算爲真/假基於驗證的結果。

雖然有些語言允許您覆蓋實例的布爾值,但php不會(除了轉換爲字符串,即PHP的Magic Methods)。

此外,PHP手冊中的the booleans page有一個評估爲false的事物列表,但它沒有給出任何重寫行爲的方法。這就是說,我會建議按照JRL的想法,構建一個驗證規則鏈,然後用一個函數返回你的if語句中所需的布爾值來執行它。

0

你可能會把它們包裝在一個子類中。

例如如果你有

class Validate { 
    public function checkSomething($data) { 
     if ($data === $valid) { 
      return true; 
     } 
     return false; 
    } 
    public function checkSomethingElse($data) { 
     if ($data === $valid) { 
      return true; 
     } 
     return false; 
    } 
} 

你可以這樣做:

class ValidateChain extends Validate { 
    protected $valid = true; 

    public function checkSomething($data) { 
     if (false === parent::checkSomething($data)) { 
      $this->valid = false; 
     } 
     return $this; 
    } 
    public function checkSomethingElse($data) { 
     if (false === parent::checkSomethingElse($data)) { 
      $this->valid = false; 
     } 
     return $this; 
    } 
    public function getIsValid() { 
     return $this->valid; 
    } 
} 

$v = new ValidationChain(); 
$valid = $v->checkSomething()->checkSomethingElse()->getIsValid(); 

快速和骯髒,E & OE。你可能需要添加一個方法來找出哪些位是無效的,等等。