How to return false with chaining methods

I have a validation class that uses a chain of methods. I would like to be able to do single checks using TRUE/FALSE as follows:

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

But also chain methods like this:

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

However, the problem is that if one method returns FALSE , it will not send the object back and thus break the chain of methods that ends with this error:

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

Do I need to select calls with a single method return or a chain of methods, or is there a workaround?

+4
source share
3 answers

One idea would be to set an internal flag to indicate success or failure and access it using another method, checking this flag in each method and not doing anything if it is set. For instance:.

 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"; } 

To minimize template validation in each function, you can also use the __call() magic method. For instance:.

 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; } } 

Usage will be the same as above:

 $a = new A(); if (!$a->check1()->check2()->isValid()) { echo "error"; } 
+8
source

I believe that you want the instance to be evaluated as true / false based on the results of the check.

While some languages ​​allow you to override the logical value of an instance, php does not (except casting to a string, that is. See PHP Magic Methods ).

In addition, the booleans page in the PHP manual contains a list of things that evaluate to false but provide no way to override behavior.

Having said that, I suggest going over to the JRL idea and building a chain of validation rules, and then "execute" it using a function that returns the boolean value needed in your if statement.

+1
source

Perhaps you could wrap them in a subclass.

eg. if you have

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

You can do it:

 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(); 

Fast and dirty, E & OE. And you probably will need to add a way to find out which bits are invalid, etc.

0
source

All Articles