Kohana 3
Wraz z rozwojem frameworka autorzy doszli do wniosku, że nadszedł czas na większe zmiany. Z pojawieniem się gałęzi 3.x Kohany otrzymaliśmy framework, który w dużym stopniu różnił się od tego, który znaliśmy do tej pory. Zmiany te można interpretować dwojako. Z jednej strony otrzymaliśmy nową funkcjonalność, która ma nam ułatwić pracę, z drugiej postawiono nas przed dylematem, czy nadal korzystać ze „starej” gałęzi czy migrować na nową. Naturalnym wyborem powinna być migracja, ponieważ tylko ona zapewni nam możliwość korzystania ze stale aktualizowanego kodu, jednakże wymagała by ona dostosowania niemal każdego pliku, który stworzyliśmy. Poniżej zamieszczam listę zmian, które udało mi się dostrzec po kilku godzinach pracy z nową wersja Kohany.
Zmiana wzorca projektowego
W wersji 2.x Kohana opierała się o trójwarstwowy wzorzec MVC, który jest używany w zdecydowanej większości frameworków. W nowej wersji autorzy postanowili wyróżnić się na tle konkurencji i wdrożyli wzorzec – HMVC. Jak można sądzić po nazwie jest on rozszerzeniem MVC. Najprościej mówiąc różnica pomiędzy nimi polega na umożliwieniu w HMVC wewnętrznego wywoływania kontrolerów innych, niż ten wywołany przez użytkownika.
Chcąc wykonać wewnętrzne wywołanie kontrolera należy utworzyć obiekt Request przekazując do metody factory zapytanie, które chcemy wykonać.
$this -> request -> response .= Request :: factory( 'nazwa_kontrolera/nazwa_akcji' ) -> execute( );
Korzystając z wewnętrznych wywołań przydatne może się okazać rozróżnienie czy zapytanie zostały wykonane przez użytkownika czy programistę. Można tego dokonać sprawdzając czy obiekt aktualnego zapytania i zapytania „bazowego” są takie same.
if( $this -> request != Request::instance( ) ) die( 'Wykryto wewnętrzne wywołanie.' );
Mimo rozszerzenia wzorca programista nie jest zmuszony do korzystania z nowej funkcjonalności, tak więc możliwe jest korzystanie z MVC w taki sam sposób jak miało to miejsce w wersji 2.x Kohany.
Zmiana nazewnictwa klas
Na wzór Zend Framework w nowej wersji Kohany nazwy klas są ściśle powiązane z katalogiem, w którym się znajdują. Wszystkie klasy tworzone przez programistę powinny znajdować się w katalogu classes. Jest on bazowym katalogiem dla określania nazwy klasy. Nazwa klasy powinna odwzorowywać ścieżkę do pliku, w którym została zdefiniowana. Poniżej kilka przykładów nazw klas oraz miejsc, w których powinny się one znajdować.
Kontroler | Controller_Page | application/classes/controller/page.php |
Kontroler | Controller_Page_Category | application/classes/controller/page/category.php |
Model | Model_Page | application/classes/model/page.php |
Helper | Date | application/classes/date.php |
Jak można zauważyć w powyższej tabeli zmieniała się konwencja nazywania klas helperów. Aktualnie wszystkie nazwy klas powinny zaczynać się wielką literą.
Poza zmianą nazw klas uległ również sposób nazewnictwa akcji. Nazwa każdej akcji musi zostać poprzedzona prefiksem action_ (np. action_index( )).
Bootstrap
Bootstrap jest plikiem, od którego startuje ładowanie naszej aplikacji. Przejął on w dużej mierze rolę plików konfiguracyjnych. Poza samą konfiguracją odpowiada on za utworzenie obiektu Request, a co za tym idzie wywołanie odpowiedniego kontrolera.
Podczas dostosowywania pliku bootstrap warto zapoznać się z wersją wykorzystywaną przez jednego z twórców Kohany dostępnej na GitHubie, w której można znaleźć kilka przydatnych modyfikacji.
Routing
W gałęzi 2.x działanie rotingu było proste. Otrzymane zapytanie było rozbijane na podstawie znaku „/”. Pierwszy element interpretowany był jako nazwa kontrolera, drugi jako nazwa akcji, pozostałe były przekazywane jako parametry do akcji. Nic nie stało również na przeszkodzie, aby określić własne reguły routingu przy pomocy pliku konfiguracyjnego route.php.
W nowej wersji zasada routingu została zupełnie przebudowana. Aktualnie każdy schemat URL mający więcej niż 3 człony (kontroler, akcja, id) musi zostać osobno zdefiniowany – nie ma możliwości „niejawnego” przekazywania do akcji różnej ilości parametrów.
Domyśla zasada routingu wygląda następująco:
Route :: set( 'default', '(<controller>(/<action>(/<id>)))') -> defaults( array( 'controller' => 'welcome', 'action' => 'index' ) );
składa się na nią wywołanie dwóch metod. Pierwsza – set – umożliwia ustalenie nazwy reguły (default) oraz „symboliczne” określenie jej wyglądu ((<controller>(/<action>(/<id>)))) – nawiasy umożliwiają określenie opcjonalnych zmiennych. Druga – defaults – określenie wartości domyślnych dla poszczególnych zmiennych – przykładowo jeśli nie przekażemy zmiennej określającej nazwę kontrolera domyślnie zostanie użyty kontroler welcome.
Opcjonalnie przy pomocy wyrażeń regularnych możemy określić wzorzec, do którego musi pasować poszczególny segment URL, aby został zakwalifikowany do danej reguły routingu.
Route :: set( 'rest', '<nazwa>/<id>.<format>', array( 'nazwa' => '([A-z]+)', 'id' => '([0-9]+)', 'format' => '(html|xml|json)' ) ) -> defaults( array( 'controller' => 'welcome', 'action' => 'rest' ) );
Powyższa reguła definiuje URL, na który składają się trzy segmenty – nazwa, id, format. Dla każdego segmentu zostało zdefiniowane wyrażenie regularne określające jakie wartości może on przyjmować. Jako, że w adresie URL nie występuje nazwa kontrolera oraz akcji, która ma z zostać wywołana musimy określić je przy pomocy wartości domyślnych.
Nowy mechanizm routingu dostarcza również możliwości generowanie adresów URL na podstawie zdefiniowanych wzorców. W Kohanie 2.x chcąc umieścić na stronie odnośnik do akcji musieliśmy znać dokładny jej adres. W przypadku Kohany 3.x wystarczy, że znamy nazwę reguły routingu oraz listę parametrów, które przyjmuje.
echo Route :: get( 'rest' ) -> uri( array( 'nazwa' => 'produkty', 'id' => 12, 'format' => 'rss' ) ) );
Wywołując powyższy kod Kohana pobierze ze zdefiniowanych przez nas reguł tę o nazwie rest, a następnie w odpowiednie miejsca wstawia wartości przekazanych zmiennych. W rezultacie czego otrzymamy produkty/12.rss.
Komunikacja z bazą danych
Wraz z nową Kohaną ukazał się napisany od nowa moduł Database. Tak jak w przypadku poprzedniej wersji umożliwia on wykonywanie zapytań na dwa sposoby. Pierwszy sposób polega na przekazaniu do wykonania gotowego zapytania.
DB :: query( Database :: SELECT, 'SELECT * FROM users' ) -> execute( );
Jak widać powyższy kod różni się trochę od tego znanego z wersji 2.x. Podczas wykonywania zapytania musimy dodatkowo określić jego typ (Database :: SELECT) oraz wywołać metodę, która prześle zapytanie do bazy danych (execute).
Drugim sposobem jest wykorzystanie Query Buildera. Również i ta funkcjonalność była dostępna w poprzedniej wersji frameworka. Nowa wersja została na tyle rozbudowana, że umożliwia budowanie złożonych zapytań, co poprzednio było problematyczną sprawą.
DB :: select( 'username' ) -> and_where_open( ) -> or_where( 'firstname', 'LIKE', '%a%' ) -> or_where( 'lastname', 'LIKE', '%a%' ) -> and_where_close( ) -> and_where( 'logins', '>', 5 ) -> from( 'users' ) -> execute( );
Więcej informacji na temat nowego modułu można znaleźć w dołączonym do Kohany manualu.
Metody before( ) + after( )
Klasa kontrolera została wzbogacona o dwie powyższe metody, które wywoływane są odpowiednio przed oraz po wykonaniu akcji. Naturalnym ich zastosowaniem wydaje się być: w przypadku before sprawdzenie czy użytkownik ma prawo do wywołania pożądanej akcji, w przypadku after modyfikacja zwracanej odpowiedzi, czy po prostu przesłanie dodatkowych danych do szablonu.
Przykład wykorzystania metody before( ) do sprawdzania uprawnień użytkownika można znaleźć na nieoficjalnej wiki Kohany.
Pliki językowe
Funkcjonalność plików językowych została rozbita na dwa sposoby. Pierwszym z nich jest znana z Kohany 2.x funkcjonalność komunikatów polegająca na pobieraniu z pliku językowego tekstu na podstawie przekazanego klucza.
Kohana :: message( 'user', 'exists' ); // odpowiednik Kohana :: lang( 'user.exists ) z 2.x
Drugim elementem jest funkcjonalność wielojęzyczności. Jest ona realizowana poprzez helper i18n oraz jego metodę get( ), bądź też poprzez funkcję __( ), która stanowi alias do wspomnianej metody. Co ważne tłumaczenia mogą być używane niezależnie od komunikatów.
echo __( 'Witaj, :user', array( ':user' => $username ) );
Elementy zmienione / usunięte
Poniżej lista pozostałych elementów, które zostały zmienione lub usunięte z nowej gałęzi.
- Funkcjonalność helpera valid została przeniesiona do biblioteki Validation.
- Brak możliwości odwoływania się do kontrolera z widoku przez zmienną $this.
- Usunięcie mechanizmu flash z biblioteki Session – w paczce dostępnej do ściągnięcia ze strony Kohany w bibliotece Session brakuje również metody get_once, którą można znaleźć na GitHubie
- Przekierowanie użytkownika pod inny adres nie odbywa się już za pośrednictwem helpera url, tylko z wykorzystaniem obiektu Request.
$this -> request -> redirect( '/' );
- Usunięta została funkcjonalność zdarzeń.
- Usunięta została biblioteka Input, należy bezpośrednio odwoływać się do zmiennych superglobalnych. Chcąc odtworzyć funkcjonalność pobierania wartości ze zmiennych superglobalnych z możliwością określenia wartości domyślnej należy skorzystać z helpera Arr,
Arr :: get( $_GET, 'nazwa_zmiennej', 'domyślna_wartość' );
Dodatkowe informację o nowej wersji Kohany mogą być uzyskane poprzez aktywowanie w bootstrapie modułu userguide, a następnie wywołanie żądania userguide/docs, które wyświetli podstawowy manual. Moduł userguide jest o tyle przydatny, że dokumentacja oraz api (userguide/api) generowane są w locie zarówno dla plików Kohany, modułów oraz aplikacji.
Zobacz także
- Wprowadzenie do Kohany 3 od podstaw (eng)
- CheatSheet prezentujący dostępne metody wraz z ich krótkim opisem
- Zbiór wszystkich (?) modułów dostępnych do Kohany 3.x
Tagi: bootstrap, db, hmvc, ko2, ko3, Kohana, routing
Kategoria: Kohana
Literówka w routingu „Pierwsza – get – umożliwia ustalenie nazwy reguły” – zamiast „get” powinno być chyba „set” ;)
poprawione, dzięki :)
I oto powod dla ktorego wszystkie frameworki sa do dupy ;) Wezma cos zmienia i potem ucz sie od nowa a chyba nie taka jest idea. Moim zdaniem lepiej miec kilka wlasnych solidnie napisanych klas i z nich korzystac. Zaden framework nam tego nie da
pozwolę się nie zgodzić :) tak dramatyczne zmiany zdarzają się bardzo rzadko. poza tym KO2 działa w pełni sprawnie i nic nie stoi i na przeszkodzie, aby nadal z niej korzystać:-) w przypadku większości projektów, kilka własnych klas może być niewystarczające :)
mała uwaga: domyślny routing to: Route::set(‚default’, ‚((/(/)))’)
->defaults(array(
‚controller’ => ‚welcome’,
‚action’ => ‚index’,
));
dzięki :-) coś źle przekleiłem z edytora tekstu :-)