Присвоить значение или бросить исключение: какая конструкция?

PHP 7. Есть объект TitleMap с ArrayAccess, который по индексу возвращает объект Data. Надо написать конструкцию, которая в случае наличия индекса присвоит значение, а в случае отсутствия - бросит исключение, мол неправильное значение индекса (исключение надо бросать в клиентском коде, не залазя в сам TitleMap ).

Если в лоб, то вот:
if (!isset($this->title_map[$page_type]) {
    throw new EngineError('There is no Data for this type.');                    
};
$data = $this->title_map[$page_type];


Но хочется что-то такое, без дублирования:
$data = $this->title_map[$page_type] ?? throw new EngineError('There is no Data for this type.');


К сожалению, такая штука не проходит парсинг. Есть еще короткие варианты? Соль в том, что проверку на нуль нельзя делать (иначе присвоил бы, а потом проверил бы на null), только isset - имплементация OffsetGet должна возвращать только Data (использованы return type hints).
  • Вопрос задан
  • 175 просмотров
Пригласить эксперта
Ответы на вопрос 2
27cm
@27cm
TODO: Написать статус
Причина, почему так, как вы хотите, не работает - throw не возвращает никакого значения. Не будет работать даже вот такая простая конструкция:
$return = throw new Exception();

Если очень хочется, есть такой вариант - объявить вспомогательную функцию, в которую и обернуть throw (функция по умолчанию будет возвращать null):
function throwme($e) { throw $e; }

$data = $this->title_map[$page_type] ?? throwme(new EngineError('...'));


Подробнее можно почитать тут:
stackoverflow.com/a/1211497

P.S.: Идея с конструкцией вроде $var = $test ?? throw new Exception() мне нравится.
Ответ написан
Preemiere
@Preemiere
Symfony developer
Тут нет никакого дублирования, не занимайтесь ерундой. Первый вариант понятен и отлично читается.
if (!array_key_exists($page_type, $this->title_map) {
    throw new EngineError('There is no Data for this type.');
};

$data = $this->title_map[$page_type];
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы