本文和大家分享的主要是php中用 Enum 限定參數(shù)類型相關(guān)內(nèi)容,一起來看看吧,希望對(duì)大家學(xué)習(xí)php 有所幫助。
PHP 是一門若類型語言,這是大家都知道的,弱類型讓我們?cè)诰帉懘a時(shí)很舒服,但是維護(hù)它卻變得不那么舒服,一個(gè)小型的 PHP 項(xiàng)目只有有限的幾個(gè)程序員去維護(hù)的話,其實(shí)這個(gè)問題并不明顯,也不會(huì)成為困難,但是當(dāng)項(xiàng)目變大,協(xié)作的人數(shù)變多的時(shí)候這就是一個(gè)需要去正式的問題。
PHP 7 和 PHP < 7
在PHP 7 之前我們對(duì)參數(shù)沒有太多的限定。
function test(array $arr, App\Model\User $user)
{
}
PHP 7 之前我們只能對(duì)形參做這樣的限制,無法限定基礎(chǔ)類型。而 PHP7 之后我們可以對(duì)參數(shù)進(jìn)行基礎(chǔ)類型限制了。
function test(array $arr, App\Model\User $user, string $string, int $int, bool $bool, float $float) : int
{
}
可以對(duì)形參進(jìn)行基礎(chǔ)類型進(jìn)行限制,并且方法和函數(shù)的返回值也可以提前告知。
這樣的好處就是多少協(xié)作時(shí),不需要他人調(diào)用一個(gè)他不熟悉或者從來沒有用過的方法或者函數(shù)的時(shí)候去找到定義的人進(jìn)行溝通,代碼已經(jīng)告訴他需要傳遞什么樣的參數(shù)給函數(shù),減少了多余的協(xié)作溝通成本。
當(dāng)然無論是 PHP 7 還是 php 5.* 其實(shí)都有一個(gè)庫(kù)可以做到這些功能,那就是SPL Type ,但是這個(gè)庫(kù)雖然以 SPL 命名但并不和 SPL 一樣默認(rèn)集成 PHP 里,它不是 PHP 的內(nèi)核組件一部份,因此需要獨(dú)立去安裝。
當(dāng)你使用 PHP 5.* 而不是 PHP 7 的時(shí)候,想要達(dá)到參數(shù)限定可以去安裝它。若你使用 PHP 7 這個(gè)庫(kù)的功能其實(shí)已經(jīng)沒什么用了,唯一還用的就是 SplEnum 這個(gè)類。
SplEnum 這個(gè)類實(shí)現(xiàn)了其他編程語言的枚舉功能,那么枚舉有什么用呢,我們可以假設(shè)這樣一個(gè)場(chǎng)景,我們有一個(gè)很大的項(xiàng)目,有百人的開發(fā)團(tuán)隊(duì)或者更多,作為最初項(xiàng)目的文章模塊的設(shè)計(jì)開發(fā)者你定義了一個(gè)創(chuàng)建文章的方法,這個(gè)方法需要兩個(gè)參數(shù)。一個(gè)參數(shù)是外部表單提交或者其他途徑獲得的數(shù)據(jù),一個(gè)是將要?jiǎng)?chuàng)建的文章的類型。
你可以通過文檔、數(shù)據(jù)庫(kù)注釋、方法注釋等一系列方法告訴調(diào)用者該如何傳參,但是如果有的人這些都沒讀或者懶得去看那么你該如何限定他們用不正確的方法調(diào)用這個(gè)方法呢?
似乎好像沒有辦法了。
但是這個(gè)類就可以幫助我們,這里我使用了一個(gè)和擴(kuò)展同樣功能的PHP代碼實(shí)現(xiàn)的包
<?php
---- # 1.定義 Enum 部分namespace Type;
require './vendor/autoload.php';
class ArticleTypeEnum extends \MyCLabs\Enum\Enum{
const GENERAL = 1;
const JOB = 2;
const DISCUSS = 3;
const SHARE = 4;
const COURSE = 5;
const LIFE = 6;
const SPECIAL_COLUMN = 7;
}
---- # 2.定義方法部分
function createArticle(array $data, ArticleTypeEnum $articleTypeEnum){
// 創(chuàng)建對(duì)應(yīng)的類型的文章
}
---- # 3.調(diào)用部分
try{
testTypeEnum($data, new ArticleTypeEnum(ArticleTypeEnum::COURSE));
}catch (\Exception $exception){
echo $exception->getMessage();
}
我在第一部分定義了枚舉類,集成枚舉基類 \MyCLabs\Enum\Enum ,在類中定義了幾個(gè)文字類型常量。
第二部分是一個(gè)偽代碼的一個(gè)創(chuàng)建文章的方法。
第三部分是調(diào)用部分,可以看見因?yàn)榈诙€(gè)參數(shù)已經(jīng)被限定為枚舉類,所以我必須傳遞一個(gè)枚舉類型實(shí)例給創(chuàng)建方法,如果傳遞的不是枚舉類的實(shí)例,那么程序就會(huì)拋出異常。
很簡(jiǎn)單的我就可以將外部調(diào)用時(shí)要?jiǎng)?chuàng)建的文章類型限定在規(guī)定范圍內(nèi)而不會(huì)出現(xiàn)未知的參數(shù),或者一些臟數(shù)據(jù)進(jìn)入到數(shù)據(jù)庫(kù)中去,同時(shí)代碼層面就告訴調(diào)用者應(yīng)該如何去傳遞參數(shù)。
在傳遞第二個(gè)參數(shù)的時(shí)候你可能覺得麻煩,其實(shí)這個(gè)庫(kù)作者已經(jīng)想到了。
<?php
---- # 3.調(diào)用部分
try{
testTypeEnum($data, ArticleTypeEnum::GENERAL());
}catch (\Exception $exception){
echo $exception->getMessage();
}
這樣就可以了,這是利用 PHP 的魔術(shù)方法 __callStatic() 實(shí)現(xiàn)的調(diào)用相應(yīng)常量。
這樣我們就可以在代碼層面控制參數(shù)類型以提高我們的程序可維護(hù)性了。
來源:稀土掘金