一起學(xué)習(xí)PHP中斷言函數(shù)的使用

原來(lái)一直以為斷言相關(guān)的函數(shù)是 PHPUnit 這些單元測(cè)試組件提供的呼畸,在閱讀手冊(cè)后才發(fā)現(xiàn)里初,這個(gè) assert() 斷言函數(shù)是 PHP 本身就自帶的一個(gè)函數(shù)锅睛。也就是說(shuō)疚膊,我們?cè)诖a中進(jìn)行簡(jiǎn)單的測(cè)試的時(shí)候是不需要完全引入整個(gè)單元測(cè)試組件的义辕。

assert() 斷言函數(shù)


assert(1==1);

assert(1==2);
// assert.exception = 0 時(shí),Warning: assert(): assert(1 == 2)
// assert.exception = 1 時(shí)寓盗,F(xiàn)atal error: Uncaught AssertionError: 驗(yàn)證不通過(guò)

很明顯灌砖,第二段代碼無(wú)法通過(guò)斷言驗(yàn)證。這時(shí)傀蚌,PHP 就會(huì)返回一個(gè)警告或者異常錯(cuò)誤基显。為什么有可能是兩種錯(cuò)誤形式呢?當(dāng)我們?cè)O(shè)置 php.ini 中的 assert.exception 為 off 或者 0 時(shí)善炫,也就是關(guān)閉這個(gè)參數(shù)的能力時(shí)撩幽,程序就會(huì)以 PHP5 的形式依然返回一個(gè)警告,就像上面代碼中的注釋一樣箩艺。同時(shí)窜醉,通過(guò) try...catch 也無(wú)法進(jìn)行異常的捕獲了。這個(gè)參數(shù)其實(shí)就是控制是否以正宗的異常對(duì)象進(jìn)行拋出艺谆。如果保持這個(gè)參數(shù)為默認(rèn)情況也就是設(shè)置為 on 或者 1 的話(huà)酱虎,就會(huì)直接拋出異常,程序中止擂涛。

從上述代碼可以看出读串,斷言的第一個(gè)參數(shù)是一個(gè)表達(dá)式,而且是需要一個(gè)返回 bool 類(lèi)型對(duì)象的表達(dá)式撒妈。如果我們傳遞的是一個(gè)字符串或者一個(gè)數(shù)字呢恢暖?

// 設(shè)置 assert.exception = 0 進(jìn)行多條測(cè)試

assert(" ");
// Deprecated: assert(): Calling assert() with a string argument is deprecated
// Warning: assert(): Assertion " " failed

assert("1");
// Deprecated: assert(): Calling assert() with a string argument is deprecated

assert(0);
// Warning: assert(): assert(0) failed

assert(1);

assert("1==2");
// Deprecated: assert(): Calling assert() with a string argument is deprecated
// Warning: assert(): Assertion "1==2" failed 

很明顯第一個(gè)參數(shù)的表達(dá)式會(huì)進(jìn)行類(lèi)型強(qiáng)制轉(zhuǎn)換,但是字符串類(lèi)型會(huì)多出一個(gè)過(guò)時(shí)提醒狰右,表明給 assert() 函數(shù)傳遞字符串類(lèi)型的表達(dá)式類(lèi)型已經(jīng)過(guò)時(shí)了杰捂。當(dāng)前的測(cè)試版本是 7.3 ,在將來(lái)可能就會(huì)直接報(bào)中止運(yùn)行的錯(cuò)誤或異常了棋蚌。主要問(wèn)題在于嫁佳,如果傳遞的字符串本身也是一個(gè)表達(dá)式的話(huà)挨队,會(huì)以這個(gè)表達(dá)式的內(nèi)容為基礎(chǔ)進(jìn)行判斷,這樣很容易產(chǎn)生歧義蒿往,就像最后一段代碼一樣盛垦。當(dāng)然,已經(jīng)過(guò)時(shí)的使用方式還是不推薦的瓤漏,這里僅是做一個(gè)了解即可腾夯。

接下來(lái)我們看一下 assert() 函數(shù)的其他參數(shù),它的第二個(gè)參數(shù)是兩種類(lèi)型蔬充,要么給一個(gè)字符串用來(lái)定義錯(cuò)誤的信息蝶俱,要么給一個(gè) 異常類(lèi) 用于拋出異常。

assert(1==1, "驗(yàn)證不通過(guò)");

assert(1==2, "驗(yàn)證不通過(guò)");
// Warning: assert(): 驗(yàn)證不通過(guò) failed 

如果直接給的一個(gè)字符串饥漫,那么在警告的提示信息中榨呆,顯示的就是我們定義的這個(gè)錯(cuò)誤信息的內(nèi)容。這個(gè)非常好理解庸队。

// 注意 assert.exception 設(shè)置不同的區(qū)別

assert(1==1,  new Exception("驗(yàn)證不通過(guò)"));

assert(1==2,  new Exception("驗(yàn)證不通過(guò)"));
// assert.exception = 1 時(shí)愕提,F(xiàn)atal error: Uncaught Exception: 驗(yàn)證不通過(guò)
// assert.exception = 0 時(shí),Warning: assert(): Exception: 驗(yàn)證不通過(guò)

當(dāng)然皿哨,我們也可以給一個(gè) 異常類(lèi) 讓斷言?huà)伋鲆粋€(gè)異常。在默認(rèn)情況下纽谒,這個(gè)異常的拋出將中止程序的運(yùn)行证膨。也就是一個(gè)正常的異常拋出流程,我們可以使用 try...catch 進(jìn)行異常的捕獲鼓黔。

try{
    assert(1==2,  new Exception("驗(yàn)證不通過(guò)"));
}catch(Exception $e){
    echo "驗(yàn)證失斞肜铡!:", $e->getMessage(), PHP_EOL;
}
// 驗(yàn)證失敯幕崔步!:驗(yàn)證不通過(guò)

另外還有一個(gè)參數(shù)會(huì)對(duì)斷言的整體運(yùn)行產(chǎn)生影響,那就是 php.ini 中的 zend.assertions 參數(shù)缎谷。它包含三個(gè)值:

  • 1井濒,生成并執(zhí)行代碼,一般在測(cè)試環(huán)境使用
  • 0列林,生成代碼但是在運(yùn)行時(shí)會(huì)路過(guò)
  • -1瑞你,不生成代碼,一般在正式環(huán)境使用

這個(gè)參數(shù)大家可以自行配置測(cè)試希痴,默認(rèn)的 php.ini 中它的默認(rèn)值是 1 者甲,也就是正常的執(zhí)行 assert() 函數(shù)。

assert_options() 及相對(duì)應(yīng)的 php.ini 中的參數(shù)配置

PHP 中的斷言功能還為我們提供了一個(gè) assert_options() 函數(shù)砌创,用于方便地設(shè)置和獲取一些和斷言能力有關(guān)的參數(shù)配置虏缸。它能夠設(shè)置的斷言標(biāo)志包括:

標(biāo)志 INI設(shè)置 默認(rèn)值 描述
ASSERT_ACTIVE assert.active 1 啟用 assert() 斷言
ASSERT_WARNING assert.warning 1 為每個(gè)失敗的斷言產(chǎn)生一個(gè) PHP 警告(warning)
ASSERT_BAIL assert.bail 0 在斷言失敗時(shí)中止執(zhí)行
ASSERT_QUIET_EVAL assert.quiet_eval 0 在斷言表達(dá)式求值時(shí)禁用 error_reporting
ASSERT_CALLBACK assert.callback (NULL) 斷言失敗時(shí)調(diào)用回調(diào)函數(shù)

這些參數(shù)的含義都非常好理解鲫懒,大家可以自己測(cè)試一下。我們就來(lái)看一下最后一個(gè) ASSERT_CALLBACK 的作用刽辙。其實(shí)它的說(shuō)明也非常清楚窥岩,就是斷言失敗的情況下就進(jìn)入到這個(gè)選項(xiàng)定義的回調(diào)函數(shù)中。

assert_options(ASSERT_ACTIVE, 1);
assert_options(ASSERT_WARNING, 1);
assert_options(ASSERT_BAIL, 1);

assert_options(ASSERT_CALLBACK, function($params){
    echo "====faild====", PHP_EOL;
    var_dump($params);
    echo "====faild====", PHP_EOL;
});

assert(1!=1);
// ====faild====
// string(105) ".../source/一起學(xué)習(xí)PHP中斷言函數(shù)的使用.php"
// ====faild====

當(dāng)斷言失敗的時(shí)候扫倡,我們就進(jìn)入了回調(diào)函數(shù)中谦秧,在回調(diào)函數(shù)直接簡(jiǎn)單的打印了傳給回調(diào)函數(shù)的參數(shù)內(nèi)容∧炖#可以看出疚鲤,這個(gè)回調(diào)函數(shù)里面?zhèn)鬟f過(guò)來(lái)的是無(wú)法通過(guò)斷言的文件信息。

總結(jié)

學(xué)習(xí)掌握一下斷言函數(shù)的使用及配置缘挑,可以為我們將來(lái)學(xué)習(xí) PHPUnit 單元測(cè)試打下基礎(chǔ)集歇,當(dāng)然,本身這個(gè)能力的東西就不是很多语淘,大家記住就好啦诲宇!

測(cè)試代碼:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202005/source/%E4%B8%80%E8%B5%B7%E5%AD%A6%E4%B9%A0PHP%E4%B8%AD%E6%96%AD%E8%A8%80%E5%87%BD%E6%95%B0%E7%9A%84%E4%BD%BF%E7%94%A8.php

參考文檔:

https://www.php.net/manual/zh/function.assert-options.php

https://www.php.net/manual/zh/function.assert.php

===========

各自媒體平臺(tái)均可搜索【硬核項(xiàng)目經(jīng)理】

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市惶翻,隨后出現(xiàn)的幾起案子姑蓝,更是在濱河造成了極大的恐慌,老刑警劉巖吕粗,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纺荧,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡颅筋,警方通過(guò)查閱死者的電腦和手機(jī)宙暇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)议泵,“玉大人占贫,你說(shuō)我怎么就攤上這事∠瓤冢” “怎么了型奥?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)碉京。 經(jīng)常有香客問(wèn)我桩引,道長(zhǎng),這世上最難降的妖魔是什么收夸? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任坑匠,我火速辦了婚禮,結(jié)果婚禮上卧惜,老公的妹妹穿的比我還像新娘厘灼。我一直安慰自己夹纫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布设凹。 她就那樣靜靜地躺著舰讹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪闪朱。 梳的紋絲不亂的頭發(fā)上月匣,一...
    開(kāi)封第一講書(shū)人閱讀 52,457評(píng)論 1 311
  • 那天,我揣著相機(jī)與錄音奋姿,去河邊找鬼锄开。 笑死,一個(gè)胖子當(dāng)著我的面吹牛称诗,可吹牛的內(nèi)容都是我干的萍悴。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼寓免,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼癣诱!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起袜香,我...
    開(kāi)封第一講書(shū)人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤撕予,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后蜈首,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體实抡,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年疾就,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片艺蝴。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡猬腰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出猜敢,到底是詐尸還是另有隱情姑荷,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布缩擂,位于F島的核電站鼠冕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏胯盯。R本人自食惡果不足惜懈费,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望博脑。 院中可真熱鬧憎乙,春花似錦票罐、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至阵谚,卻和暖如春蚕礼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背梢什。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工奠蹬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人绳矩。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓罩润,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親翼馆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子割以,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容