Enum, spl и причем тут php
#php, #spl, #enum
Enum - перечисление, важный тип данных, позволяющий создавать ограниченные последовательности из идентификаторов. Иными словами, это набор всегда строго определенных значений. В слаботипизированных языках, к которым изначально принадлежит и php, этот тип обычно не реализован. И хотя разработчики уже не первый год просят создать enum в php, создатели этого языка пока не спешат обрадовать сообщество этой возможностью.

Enum, spl и php
Так было не всегда. До 7 версии в php была, встроенная в spl (стандартная библиотека PHP), возможность эмулировать enum. Это можно было сделать создав свой класс, наследующий от SplEnum. Но, по мере развития языка и движению к строгой типизации, эту возможность было решено исключить. В релиз php 7.0.0 от 3 декабря 2015 г. этот тип данных включен не был.
Однако, сообщество разработчиков всё равно хотело использовать enum тип и создало свои инструменты для этого. И мы рассмотрим их чуть позже в этой статье, а сейчас хочу рассказать, чем же удобен этот тип и какие проблемы он решает.
Для чего нужен enum
Представьте, что вы разрабатываете приложение для обработки заявок на кредитование. У вас есть разные типы продуктов, например: "сельская ипотека", "автокредит" и "кредит наличными". По техническому заданию, приложение не должно обрабатывать другие типы. То есть, если придет заявка на "бизнес-ипотеку", то её необходимо будет отклонить. Также необходимо создать три формы для каждого типа продуктов, чтобы пользователи могли присылать новые заявки.
Первая идея, которая приходит в голову, поместить все продукты в массив:
<?php $types = [ 'сельская ипотека', 'автокредит', 'кредит наличными', ];
Теперь можно создавать страницы с формами, где будет указан тип программы. Рассмотрим пример с "сельская ипотека":
<form> <input type="text" name="name" placeholder="Имя"> <input type="text" name="tel" placeholder="Телефон"> <input type="text" name="sum" placeholder="Необходимая сумма"> <input type="hidden" name="type" value="cельская ипотека"> <button type="submit">Отправить заявку</button> </form>
Php-скрипт по значению инпута с именем type будет определять разрешенный тип. То есть проводить проверку наличия данной строки в массиве:
<?php if (in_array($_POST['type'], $types)) { // обработка заявки } else { // неверный тип заявки }
И вот тут нас поджидает самая распространенная ошибка с буквой "с". Догадались какая? Да, в созданной форме строка "cельская ипотека" начинается с английской буквы. Это очень неочевидная и частая ошибка, которую сложно отловить. Пока вы догадаетесь в чем причина, ваш заказчик потеряет много клиентов. Вот тут бы нам и пригодился тип enum.
Эмуляция enum в современном php
Сообщество php-разработчиков не сидело без дела все эти годы и разработало прекрасную библиотеку myclabs/php-enum, которая позволяет создавать классы эмулирующие перечисления. На момент написания статьи, у неё набралось почти 2 тысячи звезд на github и 16,5 миллионов скачиваний.
Как и любую другую современную библиотеку, её можно установить с помощью пакетного менеджера composer. Для этого в консоли нужно выполнить:
composer require myclabs/php-enum
Теперь мы сможем создать перечисление наших продуктов, используя enum тип. Для удобства приведу весь код в одном месте:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?php // подключение автолодера include "vendor/autoload.php"; // подключение пространства имен use MyCLabs\Enum\Enum; // наш класс, реализующий enum class MortgageTypes extends Enum { private const RURAL = 'сельская ипотека'; private const AUTO = 'автокредит'; private const CASH = 'кредит наличными'; } ?> <form> <input type="text" name="name" placeholder="Имя"> <input type="text" name="tel" placeholder="Телефон"> <input type="text" name="sum" placeholder="Необходимая сумма"> <input type="hidden" name="type" value="<?= new MortgageTypes(MortgageTypes::RURAL())?>"> <button type="submit">Отправить заявку</button> </form> |
Обратите внимание на строку 19, значение аттрибута value будет "сельская ипотека", на этот раз, с правильной буквой "с". А проверить это значение можно с помощью простого кода:
<?php if (MortgageTypes::isValid($_POST['type'])) { // обработка заявки } else { // неверный тип заявки }
Такой код значительно лучше читается и огранизован с помощью классов, что добавляет + в карму и упрощает тестирование. Эмуляция типа enum также позволяет нам оградить своё приложение от возможных багов, а заказчика от непредвиденных потерь. Для этого была использована сторонняя библиотека, хотя в идеальном мире этот тип данных мог бы быть и встроен в php. Надеюсь, разработчики этого языка в ближайшее время услышат сообщество. Ну а мы с вами знаем что с этим делать.