Вашему внимаю предлагается жвачка для ума для любителей true-кодинга на PHP.
Этот вопрос хорошо подходит для того, чтобы задавать на собеседовании и замучить кандидата до смерти, тк сразу и без подготовки на него ответят далеко не все, а только те соискатели, кто очень хорошо знает предметную область и глубоко погружен в некоторые тонкости языка.
Итак, задача казалось бы вполне тривиальная и очень типичная:
Получить в переменную $id значение параметра id из GET, при условии, что это цифра и больше 0, в остальных случаях - FALSE.
И это бы было тривиально, если бы не следующие ограничения:
Запись должна быть в одну строку
$id = ...;
(точку с запятой можно поставить только один раз в конце строки), а операторы 'if' и '?', а также фигурные скобки использовать нельзя. Обращаться к массивам $_* нельзя.
Тест-кейс который должен выполняться:
index.php?id=100500 => 100500
index.php?id=-10 => FALSE
index.php?id=0 => FALSE
index.php?id= => FALSE
index.php?id=wtf => FALSE
index.php? => FALSE
Ну что ж, давайте рассуждать как это сделать.
Если бы не ограничения на if и ?, то все было бы предельно просто и очень прозрачно. Требование написать в одну строку явно намекает на то, что надо использовать какую-то хитрую функцию... или хитро использовать какую-то функцию.
Для этого нам больше всего подходит функция filter_input
, и если внимательно изучить мануал от нее, то можно найти все что нужно для решения задачи: нам нужно использовать фильтр FILTER_VALIDATE_INT
, благодаря которому мы поймем, что нам передали число, а также установить опции, в которых min_range
будет 1. Это отсечет все цифры меньше 1 и все, что является не цифрой.
Задача почти решена, за одним небольшим исключением - если в GET нет нужного нам параметра, то filter_input считает это шибкой фильтрации и отдает NULL в качестве результата. И тут на помощь приходит магия: в конец добавляем or
после которого присваиваем FALSE нашей переменной, и благодаря or
этот код сработает только тогда, когда результат от предыдущей операции интерпретируется как ложь. Таким образом, все что не прошло через filter_input станет FALSE, задача решена.
И если вы были достаточно внимательны, то уже увидели правильный ответ в виде кода на изображении в самом начале :)
А еще есть более элегантное решение, просто добавить в опции 'default' => FALSE
, и тогда все что не пройдет валидацию превратится в FALSE, что позволит избавится от or
и магии :)