Одним из аспектов, отсутствующих в некоторых других ответах, здесь является способ использования перечислений с подсказками типов.
Если вы определяете свое перечисление как набор констант в абстрактном классе, например,
abstract class ShirtSize {
public const SMALL = 1;
public const MEDIUM = 2;
public const LARGE = 3;
}
тогда вы не можете напечатать подсказку в параметре функции - для одного, потому что это не экземпляр, но также потому, что тип ShirtSize::SMALL
- int
, а не ShirtSize
.
Вот почему родные перечисления в PHP были бы намного лучше, чем все, что мы можем придумать. Однако мы можем приблизить перечисление, сохранив частное свойство, которое представляет значение перечисления, а затем ограничив инициализацию этого свойства нашими предопределенными константами. Чтобы предотвратить создание произвольного экземпляра перечисления (без дополнительных затрат на проверку типов в белом списке), мы делаем конструктор закрытым.
class ShirtSize {
private $size;
private function __construct ($size) {
$this->size = $size;
}
public function equals (ShirtSize $s) {
return $this->size === $s->size;
}
public static function SMALL () { return new self(1); }
public static function MEDIUM () { return new self(2); }
public static function LARGE () { return new self(3); }
}
Тогда мы можем использовать ShirtSize
так:
function sizeIsAvailable ($productId, ShirtSize $size) {
// business magic
}
if(sizeIsAvailable($_GET["id"], ShirtSize::LARGE())) {
echo "Available";
} else {
echo "Out of stock.";
}
$s2 = ShirtSize::SMALL();
$s3 = ShirtSize::MEDIUM();
echo $s2->equals($s3) ? "SMALL == MEDIUM" : "SMALL != MEDIUM";
Таким образом, самое большое отличие с точки зрения пользователя заключается в том, что вам нужно добавить ()
к имени константы.
Единственным недостатком является то, что ===
(который сравнивает равенство объектов) вернет false, когда ==
вернет true. По этой причине лучше всего предоставить метод equals
, чтобы пользователям не приходилось не забывать использовать ==
, а не ===
для сравнения двух значений перечисления.
РЕДАКТИРОВАТЬ: пара существующих ответов очень похожи, в частности: https://stackoverflow.com/a/25526473/2407870.