Вы наверняка знаете проект thecodingmachine/safe.
A set of core PHP functions rewritten to throw exceptions instead of returning false when an error is encountered.
// вместо
$contents = @file_get_contents($file);
if ($contents === false) {
throw new RuntimeException("File {$file} is not readable");
}
// пишем
$contents = Safe\file_get_contents($file);
Такой подход мне всегда казался максимально бредовым: скодогенерировать обёртки над всеми стандартными PHP-функциями и написать плагины под каждый статанализатор вместо того, чтобы воспользоваться композицией функций.
Поэтому ночью 3 августа 2019 года я написал библиотечку
vudaltsov/exceptionally, которая решала проблему куда более элегантно:
$contents = exceptionallyCall('file_get_contents', $file);
Тогда ещё не было стрелочных функций и first class callable синтаксиса, поэтому краткая запись могла выглядеть только так.
Забавно, что утром в тот же день в паре кварталов от моей квартиры загорелся склад, подробнее в личном канале.
Через 2 дня я предложил RFC в Symfony, а ещё через неделю Yonel Ceruto добавил статический метод ErrorHandler::call(), он там есть и по сей день.
Но настали времена, когда я больше не пишу на Symfony, а функция всё ещё актуальна. Поэтому я решил перенести
vudaltsov/exceptionally в thesis/exceptionally, упростить и приправить дженериками:
/**
* @template T
* @param callable(): (T|false) $function
* @return T
* @throws \ErrorException
*/
function exceptionally(
callable $function,
int $errorLevels = E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED,
): mixed {}
// PHP < 8.6
$contents = exceptionally(static fn () => file_get_contents($file));
// PHP >= 8.6 с partial function application
$contents = exceptionally(file_get_contents($file, ...));
Исключение ErrorException, кстати, существует в ядре ровно для этой задачи, поэтому помимо стандартных параметров оно принимает файл и номер строки.
Пользуйтесь Thesis Exceptionally на здоровье!
composer require thesis/exceptionally
⸻
Этот пост я разместил неделю назад в 🐘 PHPeople. Кстати, общая группа там теперь бесплатная — подписывайся на @phpeople_community!