Obsługa __call w kontrolerach Kohana 3

Podziel się z innymi!

    Obsługa magicznej metody __call w kontrolerach Kohana 3 została zarzucona. W zamian za to Twórcy frameworka zaimplementowali obsługę tzw „catch all-a”. Definicje ścieżek routingu definiuje się w pliku application/bootstrap.php

    U mnie „catch all” wygląda mniej więcej tak.

    Route::set('catch_all', '<path>', array('path' => '.+'))
        ->defaults(array(
            'controller' => 'error',
            'action' => '404',
    ));

    Czyli jak łatwo się domyślić w przypadku nie istnienia danego kontrolera i akcji zwracana jest strona 404.

    Jednak zamiast kontrolera error można by w tym miejscu wskazać dowolny inny kontroler a w miejsce 404 dowolną inną metodę.

    Route::set('catch_all', '<path>', array('path' => '.+'))
        ->defaults(array(
            'controller' => 'page',
            'action' => 'index',
    ));

    Dzięki takiemu podejściu z url-a można wyeliminować zarówno nazwę kontrolera jak i metody i ograniczyć się jedynie do unikalnego identyfikatora zasobu.

    Wadą tego rozwiązania jest to, że wariant ten jest rozpatrywany dopiero na samym końcu, a poza tym wywołanie adresu na kształt http://domena.com/page/nie_istniejaca_akcja spowoduje rzucenie wyjątku


    exception 'ReflectionException' with message 'Method action_nie_istniejaca_akcja does not exist'...

    Wyjątek ten można oczywiście obsłużyć w bootstrapie tym bardziej, że parametr ‚status’ instancji klasy Request jest ustawiany na 404.

    $request = Request::instance();
    try {
        $request->execute();
        echo $request
            ->send_headers()
            ->response;
    } catch (Exception $e) {
        if ($request->status == '404') {
            Request::factory('error/404')->execute();
        }
    }

    Co jednak kiedy chcemy mieć możliwość ograniczenia mechanizmu „catch all” do konkretnego kontrolera albo użyć go w więcej niż jednym kontrolerze? Jedynym rozwiązaniem wydaje mi się modyfikacja klasy Request. Nie namawiam oczywiście do grzebania w katalogu „system”. Kaskadowy układ plików Kohany pozwala na utworzenie pliku request.php w katalogu application/classes i zdefiniowanie klasy „Request” dziedziczącej po „Kohana_Request”. Modyfikacji wymaga w zasadzie jedna linia w metodzie „execute”.

    Zamiast

    $class->getMethod('action_'.$action)->invokeArgs($controller, $this->_params);

    należy najpierw sprawdzić czy dana metoda istnieje, a podjąć próbę wywołania magicznej metody __call.

    if($class->hasMethod('action_'.$action) === true)
    {
        $class->getMethod('action_'.$action)->invokeArgs($controller, $this->_params);
    }
    else
    {
        $class->getMethod('__call')->invokeArgs($controller, array('action_'.$action, $this->_params));
    }
    Podziel się z innymi!

      Posted in PHP by Zbigniew Heintze · Tag: