English 中文(简体)
如何在链条方法中退回错误
原标题:How to return false when chaining methods

我有一个使用方法链条的验证类别。 我愿通过<>t>TRUE/FALSE进行单项检查。

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

But also chain methods like this:

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

然而,问题是,如果一种方法回归,则不会退回物体,从而打破以这一错误结束的方法链条:

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

Do I have to pick either single method return calls or method chaining or is there a workaround?

最佳回答

一种想法是建立内部国旗,以表明成功或失败,并通过另一种方法加以利用,同时在每种方法中核对这一旗帜,如果它有的话,则不做任何事情。 例如:

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

为了尽量减少每项功能的碎块检查,你还可以使用灵丹妙药(<>条码/代码>。 例如:

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";
}
问题回答

也许,你可以把他们归入一个子类。

e.g. 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;
    }
}

你可以这样做:

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

Quick and dirty, E&OE。 或许需要增加一种方法,以找出哪一种轨道有效等。





相关问题
Separating Business Layer Errors from API errors

The title is horrible, i know; I m terrible at titles on SO here. I m wondering what would be the best way to present unified error responses in a webapi when errors could be raised deep inside the ...

AsyncTask and error handling on Android

I m converting my code from using Handler to AsyncTask. The latter is great at what it does - asynchronous updates and handling of results in the main UI thread. What s unclear to me is how to handle ...

How to tell why a file deletion fails in Java?

File file = new File(path); if (!file.delete()) { throw new IOException( "Failed to delete the file because: " + getReasonForFileDeletionFailureInPlainEnglish(file)); } Is there a ...

Exceptions: redirect or render?

I m trying to standardize the way I handle exceptions in my web application (homemade framework) but I m not certain of the "correct" way to handle various situations. I m wondering if there is a ...

热门标签