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