如果您熟悉任何主要編程語言(.NET、Java、Python 等),您可能熟悉“枚舉”或“枚舉”的概念。這些用于通過將可讀名稱分配給靜態(tài)值集合來幫助提高可讀性。閱讀“Color.Red”比查看“#FF0000”或“1”要容易得多。為了擴(kuò)展這個(gè)想法,想象寫一個(gè) if 語句,你將一個(gè)十六進(jìn)制值與紅色進(jìn)行比較?if ("#FF0000" == Color.Red) { // Do stuff }
?似乎更有意義并且直截了當(dāng)?;蛘?,您可能正在將一個(gè)值與 switch 語句中的多個(gè)情況進(jìn)行比較。比較 "#FF0000" 與 Color.Red、Color.Blue 和 Color.Green 比 "#FF0000"、"#00FF00" 更容易
如果您熟悉枚舉和 PHP,您可能會說“在PHP中沒有枚舉!”那么如果這么,那你是對的。但這并不意味著我們不能使用類輕松創(chuàng)建它們。在本文中,我將快速向您展示如何使用類和常量創(chuàng)建枚舉。此外,我將展示使用反射查找給定值的枚舉鍵(這通常與使用枚舉的原因相反,但仍然可以保證)。
PHP 中的枚舉
首先,我們將創(chuàng)建一個(gè)簡單的顏色枚舉,它將列出三種顏色:紅色、藍(lán)色和綠色。與其他語言一樣,您可能知道我們會在我們的代碼中引用這些顏色值,如 Color.Red、Color.Blue 和 Color.Green。我們不必創(chuàng)建某種類實(shí)例或任何東西。通常,語言將自己的枚舉定義為語言語法的一部分和/或讓您添加自己的枚舉。另一方面,PHP 沒有這個(gè)概念。所以我們必須做的是使用一個(gè)類,準(zhǔn)確地說是一個(gè)抽象類,來做我們想做的事。對于我們的各種值,我們將定義一些常量。這是它的樣子......
abstract class Color {
const RED = 1;
const BLUE = 2;
const GREEN = 3;
}
使用抽象類,我們不需要?jiǎng)?chuàng)建類的實(shí)例來訪問它包含的變量。有了這個(gè)定義,我們可以開始使用我們的枚舉類來比較值 1、2 和 3,分別是紅色、藍(lán)色和綠色。除了可讀性之外,我們?yōu)槭裁匆褂妹杜e?好吧,也許我們只能將顏色作為整數(shù)存儲在數(shù)據(jù)庫中。我們可以在數(shù)據(jù)庫中存儲 1,然后比較數(shù)據(jù)庫中的值,看看它是否等于 Color.RED。如果沒有這個(gè)枚舉,我們可能不知道 1 是數(shù)據(jù)庫中“紅色”的表示。不只是在數(shù)據(jù)庫中使用字符串聽起來很愚蠢,但是您會驚訝為什么事情從來沒有那么簡單……尤其是在擁有數(shù)十名開發(fā)人員的大型組織中工作時(shí)。
如何使用
大多數(shù)熟悉枚舉的人通常都知道使用句點(diǎn)來訪問值。例如 Color.Blue 或 Color.Green。由于這是一個(gè)抽象類,并且 PHP 用于訪問類成員的解析運(yùn)算符是?::
?那么您將不得不使用?Color::BLUE
?和?Color::GREEN
?。還不錯(cuò)吧?
將枚舉值轉(zhuǎn)換為其鍵
正如一開始提到的,大多數(shù)時(shí)候你會使用一個(gè)枚舉來比較你從其他地方得到的一些值和枚舉的值。從數(shù)據(jù)庫中獲取值,將其與 Color.BLUE 進(jìn)行比較,然后將頁面顏色更改為藍(lán)色作為響應(yīng)。但是,如果我們有一個(gè)像 3 這樣的值并且我們想知道枚舉中的顏色呢?當(dāng)然,我們可以針對我們定義的三個(gè)常量中的每一個(gè)嘗試該值并得到我們的答案。但是如果我們不知道所有的常數(shù)值是多少呢?如果有 20 個(gè)常量呢?做 20 個(gè) if/else 語句或設(shè)置一個(gè)包含 20 個(gè) case 的 switch 會有點(diǎn)多。下面的代碼采用了不同的方法。我們使用反射來獲取常量,遍歷它們并將每個(gè)常量的值與我們提供的值進(jìn)行比較。如果沒有找到,我們返回 null。
function getConstantName($enum, $constantValue) {
try {
$reflection = new ReflectionClass($enum);
} catch (ReflectionException $ex) {
return null;
}
$constants = $reflection->getConstants();
foreach ($constants as $key => $val) {
if ($val === $constantValue) {
return $key;
}
}
return null;
}
使用此代碼,我們可以輸入 Color 枚舉名稱和我們正在尋找的值,它將返回鍵。確保你給它一個(gè)枚舉名稱或我們類的實(shí)例,函數(shù)可以看到定義!例如,如果我們調(diào)用?getConstantName('Color', 3);
?將返回“綠色”。您可能會也可能不會決定使用此功能,但是如果您想知道 3 是否甚至等于我們的枚舉“Color”中定義的顏色,那么您肯定可以使用它。如果你使用?getConstantName('Color',
? 6); 你得到一個(gè)空值,并且知道它甚至不是受支持的顏色,并且可以將頁面的顏色默認(rèn)為?Color::Red
?。
未來的考慮
現(xiàn)在當(dāng)然我知道你可能想用枚舉做很多其他的事情。而且你甚至可以做一些事情,比如混合?Color::BLUE
?和?Color::YELLOW
?如果你希望它返回?Color::GREEN
?。由于我們創(chuàng)建了一個(gè)抽象類,因此將您的函數(shù)移動(dòng)到類中并使其成為靜態(tài)方法沒有問題。如果您在網(wǎng)絡(luò)上進(jìn)行一些搜索,您會發(fā)現(xiàn)其他人提到了與此類似的想法,并將其轉(zhuǎn)向其他方向,包括定義基類并從中繼承。