Почему route в Codeigniter 4, присваивает неверное значение параметру контроллера?

Рейтинг: 0Ответов: 2Опубликовано: 27.03.2023

Возникла непонятная ситуация. При передаче значения false в обычную функцию, где по-умолчанию значение = null присвоение или вывод значения происходит правильно:

function some(?bool $a = null)
{
    var_dump($a);
}

some();
some(true);
some(false);

Результат:

NULL
bool(true)
bool(false)

Однако, когда я попытался передать тоже самое в параметр контроллера через route, то для значения false вывелось true, что, соответственно, дало неверные результаты. Из-за чего такое могло произойти? Может codeigniter как-то по-другому false в параметре обрабатывает? Route-ы:

$routes->get('default', 'Results::index');
$routes->get('successful', 'Results::index/true');
$routes->get('errors', 'Results::index/false');

Controller:

public function index(?bool $decline = null)
{
    var_dump($decline);
    exit;
}

Результат:

NULL
bool(true)
bool(true)

Ответы

▲ 2Принят

Да, возможно, в CodeIgniter есть какая-то специфика обработки параметров маршрута, которая приводит к такому поведению. Возможно, это связано с тем, что параметры маршрута обрабатываются как строки, и при их преобразовании в булевое значение используется нестрогое сравнение.

Чтобы решить эту проблему, можно попробовать явно указать тип параметра в маршруте, используя синтаксис в фигурных скобках. Например:

$routes->get('errors/(:any)', 'Results::index/$1', ['decline' => '(false|0)']);

Здесь мы явно указываем, что параметр должен иметь значение "false" или "0". Если это не поможет, то можно попробовать преобразовать параметр в булевое значение внутри контроллера, используя функцию filter_var:

public function index(?string $decline = null)
{
$decline = filter_var($decline, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
var_dump($decline);
exit;
}

Здесь мы используем функцию filter_var для преобразования строки в булевое значение, с указанием параметров FILTER_VALIDATE_BOOLEAN и FILTER_NULL_ON_FAILURE. Это позволит нам получить правильное булевое значение, даже если значение параметра не является строго равным "true" или "false".

▲ 2

true и false в данном случае строки, а не булевы значения. Поскольку функция принимает bool аргумент, непустые строки переводятся в true. Вам придется сделать что-то типа этого

   public function index($a = '')
    {
        switch($a) {
            case '':
                $a = null;
                break;
            case 'true':
                $a = true;
                break;
            case 'false':
                $a = false;
                break;
            default:
                throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
        }
        var_dump($a);
        exit;
    }