[Из песочницы] Не используйте Illuminate Support
tl; dr: Если Вы пишете framework agnostic пакет, не используйте illuminate/support.
Перевод статьи Метта Аллана (Matt Allan) «Don’t Use Illuminate Support».
Множество framework agnostic Composer пакетов (PHP) зависят от illuminate/support, который включает в себя хелперы и код общего назначения, используемый в Laravel framework. А всё потому, что данный пакет содержит в себе множество замечательных функций типа array_get
, а также великолепные коллекции.
Хелперы — отличная штука, но я не думаю, что разработчики понимают все последствия включения данного пакета в свой проект. Все боятся критики за изобретение велосипеда, поэтому тянут 6000+ строк кода чтобы самим не писать такой код
isset($arr[$k]) ? $arr[$k] : null
Ад зависимостей
Используя illuminate/support (5.2) Вы подтягиваете в свой проект illuminate/contracts, doctrine/inflector, полифилл для random_bytes, и mb_string. К счастью дерево зависимостей на этом заканчивается.
mb_string не стандартный php модуль, поэтому он не может быть установлен на машине пользователя. Если Вы не работаете со строками, не стоит заставлять пользователей перекомпилировать PHP только для того, чтобы использовать свой пакет. Можете использовать stringy как хорошую альтернативу, он использует полифилл.
Конфликт версий
Более 6000 пакетов зависят от illuminate/support. Если кто-нибудь установит Ваш пакет и другой, включающий в себя illuminate/support, он должен быть зависим от той же версии, иначе получится конфликт. Беглый взгляд показывает, что множество проектов всё ещё используют версию 4.1.x.
Положение ухудшается, если Ваш пакет используется вместе с Laravel или Lumen. Пользователь не сможет обновиться раньше Вас (и все пакеты, использующие illuminate/support). Теперь Вы мешаете пользователю обновить свой фреймворк. Единственная альтернатива, использовать неограниченные диапазоны вроде >5.2
, но это довольно плохая идея.
Глобальная область видимости
illuminate/support подтягивает 52 функции в глобальную область видимости. Хорошо если используемый фреймворк не использует пространство имён. Зависимости не должны загрязнять глобальную область.
Но ведь хелперы прекрасны, почему бы не использовать их? Некоторые трансформеры работают не так, как ожидается, а dd
бесполезен в терминале. Но все хотят, чтобы эти 52 функции вели себя так как хочется, поэтому суют их в глобальную область.
Фасады
Это конечно небольшая проблема, но сильно раздражает когда пишешь код по 40+ часов в неделю. illuminate/support имеет множество часто используемых классов типа Collection, Request, Response, и App. Каждый раз, когда я начинаю набирать пространство имён, IDE пытается импортировать неправильную коллекцию или бесполезный фасад вместо фактического класса, который мне нужен. illuminate/support включает в себя целый каталог классов которые даже не работают за пределами Laravel! Я гарантирую, что Вы не используете фасады в рамках framework agnostic, поэтому, пожалуйста, прекратите тянуть их в мой проект.
Критические ошибки
Сейчас ваш пакет зависит от 3-х различных пакетов, не нарушающих SemVer. Стоит ли рисковать получить такие же проблемы как с left-pad вместо написания нескольких строк кода?
Нацеливание на меньшее количество зависимостей
Попробуйте использовать как можно меньше зависимостей. Если посмотреть на проекты от phpleague, то можно заметить, что все они имеют малое количество зависимостей или вообще их не имеют. Хорошая практика — написать несколько небольших вспомогательных классов для 2-х или 3-х функций. Если не хочется писать самостоятельно, скопируйте функции которые Вам нужны в соответствии с лицензией.
Если тестировать все возможные версии, много времени уйдёт на настройку конфигурации CI сервера, чем на написание своего собственного кода и тестов для нескольких вспомогательных функций.
Альтернативы
Если Вам нужна тонна функционала, следует использовать пакеты вместо того, чтобы всё писать самому. Поскольку illuminate/support охватывает огромное количество функционала, ниже список тех, что можно использовать для каждого конкретного случая.
doctrine/inflector
Приведение слов к единственному и множественному числу. Это на самом деле зависимость illuminate/support.
danielstjules/Stringy
Охватывает все функции преобразования строк. Использовался в illuminate/support до версии 5.2.
dusank/knapsack
Работа с коллекциями. Единственные пакет, обнаруженный мной сравнимый с Laravel collections.
anahkiasen/underscore-php
Замена функциям для работы с массивами, использует точечную нотацию. Я не знаю, хорошей альтернативы, поддерживающей точечную без использования зависимостей. Я просто пишу ванильный php для этого. В php7+ можно использовать null coalesce operator вместо array_get
.
Комментарии (20)
21 августа 2016 в 09:35
+11↑
↓
Как раз сегодня видел шутку в тему
JavaScript 4K demo competition! Build an amazing app with fewer than 4096 dependencies
— Joe Groff (@jckarter) 8 августа 2016 г.21 августа 2016 в 10:26
+11↑
↓
> mb_string не стандартный php модуль
> Не стоит заставлять пользователей перекомпилировать PHPЯ даже не знаю, что в ответ на это написать. Передайте пожалуйста автору статьи, чтобы он завязывал с тяжелыми наркотиками.
21 августа 2016 в 11:10
+2↑
↓
Тут дело не только в авторе статьи, но и в переводчике. Ляпов хватает и у того, и у другого, а всё вместе — получилась так себе статья…
21 августа 2016 в 15:28
0↑
↓
Вы имеете в виду, что mb_string по умолчанию не включен?
21 августа 2016 в 11:38
+4↑
↓
Автор и переводчик, видимо, не знают, что illuminate/support это не только 4 килограмма диетического мяса хэлперов, но ещё и базовые классы фреймворка типа сервис-провайдера и менеджер, и что из упомянутых 6000+ пакетов большая часть является именно пакетами для ларавел.dd бесполезен в терминале
Феерично, просто феерично…21 августа 2016 в 13:25
–5↑
↓
То есть на самом деле повторное использование кода — зло? :)Тогда не используйте вообще фреймворки.
21 августа 2016 в 18:14
0↑
↓
О! Он снова здесь))))
21 августа 2016 в 15:28
+1↑
↓
>, а dd бесполезен в терминале
Ахаха, делает http запрос к сайту и удивляется, что ему в консоль падает html от dd… К слову, в cli — dd не генерирует html.21 августа 2016 в 18:13
–3↑
↓
isset ($arr[$k])? $arr[$k]: null
Я немного отстал от жизни, но зачем писать так?Ведь «isset (expr)» по сути означает »expr!== null» (точнее, isset ещё не показывает ошибки в случае несуществования переменной/индекса, поэтому на самом деле »@expr!== null»). Т.е. приведенный выше кусок кода по сути означает »@$arr[$k] !== null ? $arr[$k] : null», только больше запутан. Почему не написать просто »@$arr[$k]»?
Я понимаю, если бы было «array_key_exists ($k, $arr) ? $arr[$k] : null» — это, хоть и длинно, но передаёт логический смысл.
21 августа 2016 в 18:17
0↑
↓
Я собственно тоже не понимаю зачем так пишут, но многие пишут просто «потому что так короче».21 августа 2016 в 18:19
+1↑
↓
Чем что? Чем »@$arr[$k]»?21 августа 2016 в 18:23
0↑
↓
А, собственно, я понял. Вы, наверное, имели в виду не »@$arr[$k] !== null ? $arr[$k] : null», а »@$arr[$k] !== null ? $arr[$k] : $default»?21 августа 2016 в 18:24
0↑
↓
Чем array_key_exists ($k, $arr)? $arr[$k]: null21 августа 2016 в 18:36
0↑
↓
А символ @ я вообще не использую.
21 августа 2016 в 19:36
0↑
↓
Часто пишу вот так:$arr = ['key' => 'value']; $a = @$arr['key'] ?: NULL; $b = @$arr['nonexistent'] ?: NULL; var_dump($a); // string(5) "value" var_dump($b); // NULL
И коротко, и логический смысл вполне понятен, как мне кажется.21 августа 2016 в 19:47
0↑
↓
А 0, '' и array () у Вас никогда не бывают значениями массива?21 августа 2016 в 20:40
0↑
↓
Чаще всего в таких случаях это используется в качестве значения по умолчанию.
Ничего же не мешает написать:$a = @$arr['key'] ?: [];
21 августа 2016 в 21:02
0↑
↓
Ну, это уже более осмысленно (ИМХО).
Но всё же в случае со строками (как в исходном Вашем примере) Вы потеряете значение '0'.
Т.е.»@$arr['key'] ?: ''» вернёт '' и для значения '', и для значения '0'.
21 августа 2016 в 22:31
+1↑
↓
Все, кто пользуется в таком контексте @, будут гореть в аду.22 августа 2016 в 00:02
+1↑
↓
Часто пишу вот так:
обновляйтесь на php7 и прекращайте
$a = $arr['key'] ?? null; $b = $arr['nonexistent'] ?? null;
Оператор подавления ошибок — лучше бы его в PHP вообще небыло.