亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

PHP 中鏈接檢查的優雅方式

PHP 中鏈接檢查的優雅方式

PHP
慕森王 2023-07-15 17:23:06
假設您有一個通用驗證函數,并且必須對輸入進行多次子檢查。每個子檢查也返回布爾值。請看這個虛構的:private function hasValidContent(string $content) : bool{    $isValid = false;    $isValid = $this->hasMoreThanOneChar($content);    $isValid = $this->hasValidCharacters($content);    $isValid = $this->hasCapitalLetters($content);    ...        return $isValid;}當然,上面的代碼不會工作,因為接下來的每一次檢查都會覆蓋前一次的評估。但是,當第一次檢查導致 時,如何才能停止進一步的檢查呢false?例如,如果其內容不超過一個字符,那么它應該在函數之后停止hasMoreThanOneChar并立即將方法返回hasValidContent為 false。是的,當然,您可以在每次方法調用后檢查表達式是否變為 false,但這很尷尬,而且開銷很大且重復。||如果有數千個或&&類似的東西在一個單一的中做這件事感覺真的很難看return $this->checkA($content)    && $this->checkB($content)   && $this->checkC($content)  ...;表達式多了之后,可讀性就會受到影響。另一種經常提到的方法可能是使用異常private function hasValidContent(string $content) : bool{    try {        $this->hasMoreThanOneChar($content);        $this->hasValidCharacters($content);        $this->hasCapitalLetters($content);        ...    }    catch {        return false;    }    return true;}private function hasMoreThanOneChar(string $string) : void {    if(count($string) < 2 ) {      throw new HasNotMoreThanOneCharException(...)    }}但我也認為這不是一個優雅的解決方案,因為驗證內容并不例外。所以我的問題是:有什么優雅的模式嗎?有什么關鍵詞可以搜索嗎?
查看完整描述

3 回答

?
蝴蝶不菲

TA貢獻1810條經驗 獲得超4個贊

創建一個包含您要執行的所有驗證的數組。數組的每個元素都必須是可調用的。迭代并盡早退出。如果所有驗證器都通過了,那就好了。


private function hasValidContent(string $content) : bool

{

? ? $validators = [

? ? ? ? // instance method

? ? ? ? [$this, 'hasMoreThanOneChar'],

? ? ? ? // callable class

? ? ? ? new class {

? ? ? ? ? ? public function __invoke(string $content)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? return ...;

? ? ? ? ? ? }

? ? ? ? },

? ? ? ? // anonymous function

? ? ? ? function (string $content): bool {

? ? ? ? ? ? return ...;

? ? ? ? }

? ? ];


? ? foreach ($validators as $validate) {

? ? ? ? if (!$validate($content)) {

? ? ? ? ? ? return false;

? ? ? ? }

? ? }


? ? return true;

}


查看完整回答
反對 回復 2023-07-15
?
幕布斯6054654

TA貢獻1876條經驗 獲得超7個贊

我推斷您正在尋找責任鏈模式。


例如,假設您有三個類:鎖、警報和燈,用于檢查房屋的狀態。


abstract class HomeChecker {

    protected $successor;


    public abstract function check(Home $home);


    public function succeedWith($successor) {

        $this->successor = $successor;

    } 


    public function next(Home $home) {

        $this->successor->check($home);

    }

}


class HomeStatus {

     public $locked = true;

     public $alarmOn = true;

     public $lightsOff = true;

}


class Locks extends HomeChecker {

   public function check(Home $home) {

       if(!$home->locked) {

           throw new Exception('The doors are not locked'); // or basically whatever you want to do

       }

       $this->next($home);

   }

}


class Alarm extends HomeChecker {

   public function check(Home $home) {

       if(!$home->alarmOn) {

           throw new Exception('The Alarms are not on'); // or basically whatever you want to do

       }

       $this->next($home);

   }

}


class Lights extends HomeChecker {

   public function check(Home $home) {

       if(!$home->lightsOff) {

           throw new Exception('The lights are still on!'); // or basically whatever you want to do

       }

       $this->next($home);

   }

}


$locks = new Locks();

$alarm = new Alarm();

$lights = new Lights();

$locks->succeedWith(new Alarm); // set the order in which you want the chain to work

$alarms->succeedWith(new Lights);


$locks->check(new HomeStatus);

所有三個類:Locks、Lights 和 Alarm 都擴展了一個名為HomeChecker的類,該類基本上具有一個抽象檢查方法以確保子類確實實現該方法以及兩個名為successWith和next 的方法。successWith 方法用于設置一個后繼者,如果當前執行的方法返回 true(意味著沒有錯誤),則將調用該后繼者。下一個方法本質上調用了鏈接起來的下一個方法。


通過這一行,我們開始了這個鏈,如果locks類的check 方法$locks->check(new HomeStatus);中的檢查失敗,則會拋出一個錯誤,并且執行將停止,否則它將調用HomeChecker 類的下一個方法,該方法最終將調用 check 方法我們安排的下一堂課


$locks->succeedWith(new Alarm); // set the order in which you want the chain to work

$alarms->succeedWith(new Lights);

在這些行中。


所以通過這種方式我們可以非常優雅地進行鏈式檢查。我希望這能幫到您。


查看完整回答
反對 回復 2023-07-15
?
動漫人物

TA貢獻1815條經驗 獲得超10個贊

一個建議是讓驗證方法拋出 anException而不是返回trueand false(成功時不返回任何內容)。


例如:


Class Validator {

    public static function assertString($string) {

        if (!is_string($string)) {

            throw new Exception('Type mismatch.');

        }

    }

    

    public static function assertStringLength($string, $min, $max) {

        if (strlen($string) < $min || strlen($string) > $max) {

            throw new Exception('String outside of length boundaries.');

        }

    }

}

你的代碼看起來像這樣:


try {

    Validator::assertString($string);

    Validator::assertStringLength($string, 4, 50);

} catch (Exception $e) {

    // handle invalid input

}

請注意,我的函數是靜態的,在這種情況下有意義,但不一定總是如此。


查看完整回答
反對 回復 2023-07-15
  • 3 回答
  • 0 關注
  • 169 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號