Kohana è un framework PHP 5 che utilizza il modello architettonico Model View Controller (MVC). Ci sono diversi motivi per cui dovresti scegliere Kohana, ma i principali sono sicurezza, assenza di peso e semplicità. In questo tutorial, presenterò le sue caratteristiche principali e, con una semplice dimostrazione, ti mostrerò quanto tempo Kohana può potenzialmente salvarti.
Kohana è un framework PHP5 che utilizza il modello architettonico Model View Controller. MVC mantiene la logica dell'applicazione
separato dalla presentazione. Questo ci consente di creare codice più pulito e di risparmiare tempo per la ricerca dei bug.
In non familiarità con questo modello:
Kohana era originariamente un fork di CodeIgniter (CI), che è un prodotto open-source di EllisLab. Ci sono molte somiglianze tra CI e Kohana, ma tutto il codice è nuovo o completamente riscritto. Come puoi leggere sul sito ufficiale di Kohana, le caratteristiche principali sono:
Iniziamo. Visita il sito Web ufficiale di Kohana http://kohanaphp.com e fai clic sulla casella verde nell'angolo a destra per scaricare l'ultima versione. Tutte le librerie, gli helper e le visualizzazioni di Kohana sono inclusi nel pacchetto di download predefinito, ma è possibile selezionare moduli aggiuntivi, strumenti del fornitore e lingue, se lo si desidera. Ai fini di questo tutorial, il pacchetto predefinito può essere sufficiente. Clicca su "Scarica Kohana!" per iniziare il download.
Al termine del download:
$ config ['site_domain'] = 'localhost / kohana';
Kohana funzionerà in quasi tutti gli ambienti con una configurazione minima. Ci sono alcuni requisiti minimi del server:
Ci sono anche alcune estensioni richieste.
Se l'installazione viene completata correttamente, verrai reindirizzato a questa pagina di test:
Se uno dei test fallisce, è necessario correggerli prima di andare avanti.
Se tutti i test sono passati, vai alla directory Kohana e rimuovi o rinomina lo script install.php. Aggiorna, e vedrai una pagina di benvenuto come questa:
Kohana è pronto ad andare. Non è necessaria altra configurazione Questo quadro è fantastico. Non è vero? Rivediamo un po 'di codice. Seguimi.
Le esercitazioni di programmazione Canonical iniziano con l'esempio "Hello world". Penso, invece, che una semplice applicazione possa darti un'idea chiara di come funziona il framework. Quindi, costruiremo un gestore di raccolte di CD, solo per una divertente dimostrazione. Prima di iniziare la codifica, è necessaria una breve introduzione al file system Kohana.
La nostra applicazione verrà inserita nel applicazione cartella. In questa cartella ci sono diverse sottocartelle ma abbiamo bisogno di quanto segue per il nostro progetto:
Le sottocartelle rimanenti non sono richieste per questo tutorial, quindi ti invito a saperne di più sul sito web Kohana.
Il sistema la cartella ospita il core Kohana e gli strumenti Kohana come librerie, helper e file di configurazione predefiniti. In questo progetto useremo alcune librerie e alcuni helper: buoni strumenti per velocizzare il tuo lavoro.
Il risorse la cartella non è una cartella Kohana predefinita. L'ho creato per file multimediali come CSS, JS e immagini. Ti mostrerò come includere questi file nel progetto.
Il moduli cartella è il posto dove mettere raccolte riutilizzabili di file correlati che insieme aggiungono una particolare funzionalità a un'applicazione. Il modulo di autenticazione, fornito dal team Kohana, è un esempio di modulo.
Questa è una breve introduzione al file system Kohana, ma è sufficiente per gli scopi di questo tutorial. Non voglio annoiarvi di più con la teoria.
Ho scelto MySQL come mio DBMS, ma ricordo che Kohana supporta anche MsSQL, MySQLi, PostgreSQL, PDOSqlite. Crea un database chiamato "cd_collection" o scegli il nome che preferisci ed esegui il seguente SQL attraverso phpMyAdmin o qualsiasi strumento per gestire l'amministrazione di MySQL.
CREATE TABLE 'albums' ('id' int (11) NOT NULL auto_increment, 'name' varchar (50) collazion utf8_bin NOT NULL, 'author' varchar (50) collazion utf8_bin NOT NULL, 'genre_id' int (11) NOT NULL , PRIMARY KEY ('id'), KEY 'genre_id' ('genre_id')) ENGINE = InnoDB DEFAULT CHARSET = utf8 COLLATE = utf8_bin AUTO_INCREMENT = 19; INSERIRE 'album' ('id', 'name', 'author', 'genre_id') VALUES (2, 'Lines, Vines And Trying Times', 'Jonas Brothers', 16), (3, 'The END' , "The Black Eyed Peas", 16), (4, "Relapse", "Eminem", 18), (5, "Monuments And Melodies", "Incubus", 1), (6, "Thriller", "Michael Jackson ', 16), (7,' Back in Black ',' AC / DC ', 4), (8,' The Dark Side of the Moon ',' Pink Floyd ', 4), (9,' Bat out of Hell ',' Meat Loaf ', 4), (10,' Backstreet Boys ',' Millennium ', 16), (11,' Rumours ',' Fleetwood Mac ', 4), (12,' Come on Over ' , 'Shania Twain', 16), (13, 'Led Zeppelin IV', 'Led Zeppelin', 4), (14, 'Jagged Little Pill', 'Alanis Morissette', 4), (15, 'Sgt. Pepper "s Lonely Hearts Club Band", "The Beatles", 16), (16, "Falling into You", "C√ © line Dion", 16), (17, "Music Box", "Mariah Carey", 16 (18, 'Born in the USA', 'Bruce Springsteen', 4); CREATE TABLE 'generi' ('id' int (11) NOT NULL auto_increment, 'name' varchar (50) collazion utf8_bin NOT NULL, PRIMARY KEY ('id'), UNIQUE KEY 'name' ('name')) ENGINE = I nnoDB DEFAULT CHARSET = utf8 COLLATE = utf8_bin AUTO_INCREMENT = 22; INSERIRE 'generi' ('id', 'name') VALUES (1, 'Alternative Rock'), (2, 'Blues'), (3, 'Classical'), (4, 'Rock'), (5 , 'Paese'), (6, 'Dance'), (7, 'Folk'), (8, 'Metal'), (9, 'Hawaiian'), (10, 'Importazioni'), (11, ' Indie Music '), (12,' Jazz '), (13,' Latin '), (14,' New Age '), (15,' Opera '), (16,' Pop '), (17,' Soul '), (18,' Rap '), (20,' Soundtracks '), (21,' World Music '); ALTER TABLE 'album' ADD CONSTRAINT 'genre_inter_relational_constraint' FOREIGN KEY ('genre_id') REFERENCES 'generi' ('id') ON DELETE CASCADE ON UPDATE CASCADE;
Come puoi vedere, l'SQL crea due tabelle, album e generi e li popola con alcuni dati. L'ultima istruzione SQL aggiunge un vincolo per la chiave esterna "genre_id".
La struttura del database è molto semplice e non richiede molte spiegazioni.
Ora devi dire a Kohana dove si trova il tuo database e come accedervi. Modifica il file di configurazione globale Sistema / config / database.php come segue
$ config ['default'] = array ('benchmark' => TRUE, 'persistent' => FALSE, 'connection' => array ('type' => 'mysql', 'user' => 'root', ' pass '=>' root ',' host '=>' localhost ',' port '=> FALSE,' socket '=> FALSE,' database '=>' cd_collection '),' character_set '=>' utf8 ', 'table_prefix' => ", 'object' => TRUE, 'cache' => FALSE, 'escape' => TRUE);
Questo codice dice a Kohana di connettersi a un database MySQL chiamato "cd_collection" su localhost con il nome utente "root" e la password "root". È necessario modificare queste impostazioni in base alla configurazione del server del database.
Creiamo ora il nostro primo controller. Ricorda queste convenzioni.
Inoltre, ricorda come Kohana struttura i suoi URL e come puoi chiamare un metodo controller; ad esempio http: //hostname/kohana_directory/index.php/controller/function.
Diamo un'occhiata a questo semplice controller.
PHP5 OOP è un prerequisito. Quindi se non sei esperto, puoi saperne di più qui.
La funzione di costruzione, chiamata __construct, inizializza la classe e chiama il costruttore genitore.
La funzione indice è la funzione predefinita, quindi verrà chiamata se chiamiamo il controller senza
specificando qualsiasi funzione (ad esempio http: //localhost/index.php/kohana/album.) Dopo il controller del nome
non c'è alcuna funzione, verrà chiamata la funzione indice predefinita).Date queste regole di base, concentriamoci sulla nostra applicazione. Il controller dell'album implementa tutte le azioni per
la gestione della collezione di album. Questo controller ci consente di creare un nuovo album, per mostrare gli album memorizzati nel nostro database,
per aggiornare un album e per eliminare un album.Quindi, cambiamo la classe come segue.
Crea un file chiamato album.php nel application / controller / e incollare quanto segue.
album_model = new Album_Model; $ this-> genre_model = new Genre_Model; $ this-> list_view = new View ('lista'); $ this-> update_view = new View ('update'); $ this-> create_view = new View ('create'); public function index () $ this-> show_albums_list (); funzione privata show_albums_list () $ albums_list = $ this-> album_model-> get_list (); $ This-> list_view-> set ( 'albums_list', $ albums_list); $ This-> list_view-> render (TRUE); public function show_create_editor () $ this-> create_view-> set ('genres_list', $ this-> get_genres_list ()); $ This-> create_view-> render (TRUE); public function show_update_editor ($ id) $ album_data = $ this-> album_model-> read ($ id); $ This-> update_view-> set ( 'album_id', $ album_data [0] -> id); $ This-> update_view-> set ( 'name', $ album_data [0] -> nome); $ This-> update_view-> set ( 'autore', $ album_data [0] -> autore); $ This-> update_view-> set ( 'genre_id', $ album_data [0] -> genre_id); $ This-> update_view-> set ( 'genres_list', $ this-> get_genres_list ()); $ This-> update_view-> render (TRUE); public function create () $ album_data = array ('name' => $ this-> input-> post ('name'), 'author' => $ this-> input-> post ('author'), 'genre_id' => $ this-> input-> post ('genre_id')); $ This-> album_model-> creare ($ album_data); url :: redirect ( 'album'); public function update () $ album_data = array ('name' => $ this-> input-> post ('name'), 'author' => $ this-> input-> post ('author'), 'genre_id' => $ this-> input-> post ('genre_id')); $ This-> album_model-> Aggiornamento ($ this-> input-> Post ( 'album_id'), $ album_data); url :: redirect ( 'album'); public function delete ($ id) $ this-> album_model-> delete ($ id); url :: redirect ( 'album'); funzione privata get_genres_list () $ db_genres_list = $ this-> genre_model-> get_list (); $ genres_list = array (); if (sizeof ($ db_genres_list)> = 1) foreach ($ db_genres_list come $ item) $ genres_list [$ item-> id] = $ item-> nome; restituisce $ genres_list;Lascia che ti spieghi cosa fa questo codice.
Cinque variabili membri sono dichiarate all'inizio della classe:
private $ album_model; private $ genre_model; private $ list_view; private $ create_view; private $ update_view;Questi membri sono privati perché voglio limitare la visibilità solo a questa classe.
Nel metodo costrutto il modello e gli oggetti vista vengono creati usando i cinque membri:
$ this-> album_model = new Album_Model; $ this-> genre_model = new Genre_Model; $ this-> list_view = new View ('lista'); $ this-> update_view = new View ('update'); $ this-> create_view = new View ('create');Per creare un oggetto modello usa questa sintassi:
$ obj_name = new Name_Model;Per creare un oggetto vista, usa questa sintassi:
$ obj_name = new View ('view_filename_without_extension');Ora ci sono due oggetti per accedere all'album e al modello di genere e tre oggetti per accedere alle viste necessarie per il rendering della presentazione.
Il metodo index chiama il metodo show_albums_list che elenca tutti gli album memorizzati nel database.
$ albums_list = $ this-> album_model-> get_list (); $ This-> list_view-> set ( 'albums_list', $ albums_list); $ This-> list_view-> render (TRUE);In questo metodo puoi vedere come il modello e l'oggetto vista sono usati per accedere ai metodi relativi. "get_list" è un metodo di modello (vedremo in seguito) che restituisce tutti gli album memorizzati nel database. Il risultato viene salvato nella matrice "$ album_list". Per passare la matrice dei risultati dal controller alla vista, il metodo "set" viene chiamato sull'oggetto della vista. Questo metodo richiede due parametri: una nuova variabile vuota (album_list) per contenere i dati di una variabile esistente ($ album_list). Ora la nuova variabile "album_list" contiene l'array $ album_list (vedremo in seguito come mostrare il contenuto nella vista). Il metodo "render", con il parametro TRUE, è necessario per inviare i dati al browser.
Il metodo show_create_editor mostra l'interfaccia utente per inserire un nuovo album.
$ This-> create_view-> set ( 'genres_list', $ this-> get_genres_list ()); $ This-> create_view-> render (TRUE);L'elenco dei generi viene passato alla vista.
Il metodo show_update_editor mostra l'interfaccia utente per aggiornare un album esistente.
$ album_data = $ this-> album_model-> read ($ id); $ This-> update_view-> set ( 'album_id', $ album_data [0] -> id); $ This-> update_view-> set ( 'name', $ album_data [0] -> nome); $ This-> update_view-> set ( 'autore', $ album_data [0] -> autore); $ This-> update_view-> set ( 'genre_id', $ album_data [0] -> genre_id); $ This-> update_view-> set ( 'genres_list', $ this-> get_genres_list ()); $ This-> update_view-> render (TRUE);"read" è un metodo model (lo vedremo più avanti) che restituisce i dati ($ album_data) dell'album con un id uguale a $ id. Quindi, ogni singolo elemento dell'album dei dati restituiti viene passato alla vista.
Il metodo di creazione riceve i dati, per un nuovo album, dalla vista e i dati sono memorizzati nel database.
$ album_data = array ('name' => $ this-> input-> post ('name'), 'author' => $ this-> input-> post ('author'), 'genre_id' => $ this -> input-> post ('genre_id')); $ This-> album_model-> creare ($ album_data); url :: redirect ( 'album');$ album_data è una matrice che contiene i dati POST dalla vista. Per salvare l'album, la matrice viene passata al metodo di creazione del modello. L'ultima riga è una chiamata a un metodo di supporto. Gli helper sono semplicemente delle funzioni che ti assistono nello sviluppo. Le classi helper vengono automaticamente caricate dal framework. Gli helper sono dichiarati come metodi statici di una classe, quindi non c'è bisogno di istanziare la classe. In questo caso viene chiamato il metodo "redirect" dell'helper "url" e dice a Kohana di reindirizzare il browser al controller dell'album. Questo evita un nuovo inserimento (ad esempio premendo F5).
"Gli helper sono semplicemente delle funzioni che ti assistono nello sviluppo."
I metodi di aggiornamento ed eliminazione funzionano allo stesso modo del metodo di creazione sopra.
L'ultimo metodo get_genres_list ottiene la lista dei generi dal modello ($ db_genres_list) e crea un nuovo array ($ genres_list) per la casella di selezione nelle viste.
$ db_genres_list = $ this-> genre_model-> get_list (); $ genres_list = array (); if (sizeof ($ db_genres_list)> = 1) foreach ($ db_genres_list come $ item) $ genres_list [$ item-> id] = $ item-> nome; restituisce $ genres_list;Passaggio 8: Crea modello di progetto
Ora creiamo modelli per la nostra applicazione web. Ricorda queste convenzioni.
Ecco il codice del modello di album. Crea un file chiamato album.php nel application / modelli / e incollare il codice qui sotto su di esso.
album_table = 'album'; $ this-> genre_table = 'generi'; public function read ($ id) $ this-> db-> where ('id', $ id); $ query = $ this-> db-> get ($ this-> album_table); return $ query-> result_array (); public function delete ($ id) $ this-> db-> delete ($ this-> album_table, array ('id' => $ id)); aggiornamento della funzione pubblica ($ id, $ data) $ this-> db-> update ($ this-> album_table, $ data, array ('id' => $ id)); funzione pubblica create ($ data) $ this-> db-> insert ($ this-> album_table, $ data); public function get_list () $ this-> db-> select ('albums.id come id, albums.name come nome, albums.author come autore, genres.name as genre'); $ This-> db-> da ($ this-> album_table); $ This-> db-> join ($ this-> genre_table, 'genres.id', 'albums.genre_id'); $ query = $ this-> db-> get (); return $ query-> result_array ();
Tutti i metodi nei modelli utilizzano la sintassi del builder Query. Questo strumento Kohana accelera i tempi di sviluppo del database e semplifica la creazione di query.
Due variabili membri sono dichiarate all'inizio della classe:
private $ album_table; private $ genre_table;
Questi membri sono privati perché voglio limitare la visibilità solo a questa classe. Sono i contenitori per i nomi delle tabelle del database.
La prima riga nel metodo del costruttore carica la libreria del database Kohana in $ this-> db. Nella seconda e nella terza riga vengono inizializzati i due membri della classe.
parent :: __ construct (); $ this-> album_table = 'albums'; $ this-> genre_table = 'generi';
La query nel metodo di lettura recupera i record dell'album con un determinato identificatore ("$ id").
$ this-> db-> where ('id', $ id); $ query = $ this-> db-> get ($ this-> album_table); return $ query-> result_array ();
La query nel metodo delete cancella la riga della tabella degli album che ha un determinato identificatore ("$ id").
$ this-> db-> delete ($ this-> album_table, array ('id' => $ id));
La query nel metodo di aggiornamento aggiorna la riga della tabella degli album con un determinato identificatore ("$ id") con nuovi valori dall'array "$ dati".
$ this-> db-> update ($ this-> album_table, $ data, array ('id' => $ id));
L'array "$ data" deve contenere nomi di record come chiavi dell'array e valori come valori dell'array. La matrice "$ data" deve avere questo formato:
$ data = array ('name' => 'album_name', 'author' => 'author_name', 'genre_id' => 'genre_id');
La query nel metodo create inserisce un nuovo record con i valori dell'array "$ data".
$ this-> db-> insert ($ this-> album_table, $ data);
La matrice "$ data" deve avere questo formato:
$ data = array ('id' => 'album_id', 'name' => 'album_name', 'author' => 'author_name', 'genre_id' => 'genre_id');
La query nel metodo get_list recupera tutte le righe degli album.
$ this-> db-> select ('albums.id come id, albums.name come nome, albums.author come autore, genres.name as genre'); $ This-> db-> da ($ this-> album_table); $ This-> db-> join ($ this-> genre_table, 'genres.id', 'albums.genre_id'); $ query = $ this-> db-> get (); return $ query-> result_array ();
Ora, il modello di genere. Crea un file chiamato genre.php nel application / modelli / e incollare il codice sottostante:
genre_table = 'generi'; function get_list () $ query = $ this-> db-> get ($ this-> genre_table); return $ query-> result_array ();
Questo modello è molto semplice, quindi non sprecherò più tempo a commentarlo. I modelli e il controller sono pronti per partire. Ora lavoriamo sulle viste.
Le viste sono file che contengono il livello di presentazione per l'applicazione. Lo scopo è quello di mantenere queste informazioni separate dalla logica dell'applicazione per una facile riusabilità e un codice più pulito. Per questo progetto sono necessarie tre visualizzazioni: una vista per elencare la collezione di album, una vista per creare un nuovo album e una vista per modificare un album esistente.
Crea un file chiamato list.php nel application / views / e incolla il seguente codice in:
COLLEZIONE CD
Collezione di CD | ||||
Nome dell'album | Autore | Genere | "$ Item-> nome". | "; eco ""$ Item-> autore." | "; eco ""$ Item-> genere." | "; eco "" .Html :: anchor ( 'album / cancellare /'.$ item-> id, HTML :: immagine (' assets / images / delete.png ')) ". | "; eco "" .Html :: anchor ( '/ show_update_editor /'.$ item-> id album, HTML :: immagine (' assets / images / edit.png ')) ". | "; eco "";?>
Questa vista mostra una pagina HTML contenente un elenco di tutti gli album. Questo elenco è stato creato utilizzando il ciclo foreach che stampa le informazioni in una tabella html. Per ogni riga di album, ci sono due immagini: una "croce rossa" e un "libro tascabile". Collegano rispettivamente il metodo di eliminazione del controller e il metodo di aggiornamento. Entrambi passano l'id dell'album al controller dell'album usando una richiesta get. Sopra la lista c'è un pulsante per creare nuovi album. In questo codice utilizziamo anche un helper html fornito da Kohana che velocizza le operazioni per scrivere pagine html.
Creiamo ora un file chiamato create.php nel application / views /.
COLLEZIONE CD
Crea un nuovo album | ".form :: label ('name', 'Name:')." | "; eco "" .Form :: ingresso ( 'name', ")." | "; eco ""; eco "
".form :: label ('autore', 'Autore:')." | "; eco "" .Form :: ingresso ( 'autore', ")." | "; eco "
".form :: label ('genre', 'Genere:')." | "; eco "".Form :: discesa ( 'genre_id', $ genres_list)." | "; eco "
".form :: submit ('submit', 'Crea album')." | "; eco "
L'ultimo ma non meno importante è la vista di aggiornamento. Creiamo un file chiamato update.php nel application / views /.
COLLEZIONE CD
Aggiorna album | ".form :: label ('name', 'Name:')." | "; eco "".form :: input ('name', $ name)." | "; eco ""; eco "
".form :: label ('autore', 'Autore:')." | "; eco "".form :: input ('autore', $ autore)." | "; eco "
".form :: label ('genre', 'Genere:')." | "; eco "".form :: dropdown ('genre_id', $ genres_list, $ genre_id)." | "; eco "
".form :: submit ('submit', 'Aggiorna album')." | "; eco "
Il primo è un semplice editor che consente all'utente di inserire informazioni su un nuovo album.
I campi come autore e nome saranno inseriti usando un input e un genere html usando a
casella combinata. Una volta che l'utente fa clic sul pulsante di creazione, tutte le informazioni vengono passate,
come richiesta POST, al metodo di creazione / aggiornamento nel controller dell'album. Quando il controller riceve questi inviati
variabili, chiama il modello che inserisce un nuovo album nel database. Le forme, in entrambe le viste, si avvalgono dell'aiuto di forma Kohana.
Per dare un po 'di stile alla nostra applicazione, crea il risorse cartella nella radice Kohana allo stesso livello della cartella dell'applicazione. Ora aprilo e crea due nuove cartelle: css e immagini.
Nel css cartella crea un nuovo file chiamato style.css e incolla questo:
una fonte-famiglia: Verdana, Ginevra, Arial, Helvetica, sans-serif; font-weight: normal; font-size: 12px; colore: # 00F; vertical-align: text-top; img border: 0; label font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-weight: normal; font-size: 12px; input border: 1px solid # 000; seleziona width: 185px; table.editor text-align: center; famiglia di font: Verdana, Ginevra, Arial, Helvetica, sans-serif; font-weight: normal; font-size: 11px; colore: #fff; larghezza: 280 px; background-color: # 666; bordo: 0px; border-collapse: collapse; border-spacing: 0px; table.editor td.editor_title background-color: # 666; colore: #fff; imbottitura: 4px; allineamento del testo: a sinistra; font-weight: bold; font-size: 16px; table.editor td padding: 4px; table.list text-align: center; famiglia di font: Verdana, Ginevra, Arial, Helvetica, sans-serif; font-weight: normal; font-size: 11px; colore: #fff; larghezza: 280 px; background-color: # 666; bordo: 0px; border-collapse: collapse; border-spacing: 0px; table.list td.item background-color: #CCC; colore: # 000; imbottitura: 4px; allineamento del testo: a sinistra; bordo: 1px #fff solido; table.list td.list_title, table.list td.headers background-color: # 666; colore: #fff; imbottitura: 4px; allineamento del testo: a sinistra; border-bottom: 2px #fff solido; font-weight: bold; table.list td.list_title font-size: 16px; table.list td.headers font-size: 12px;
Ora copia le seguenti immagini su immagini cartella:
È tutto. Indirizza il tuo browser a http: //localhost/kohana/index.php/album e dovresti vedere qualcosa di simile a questo:
Se provi a creare un nuovo album o a modificarne uno esistente dovresti vedere qualcosa di simile a questo:
Naturalmente, sono necessari alcuni miglioramenti per questa applicazione, ma con una piccola quantità di codice, hai creato una piccola applicazione web.
Ora, sai come utilizzare il pattern MVC con Kohana e come utilizzare le librerie e gli helper del database. Per saperne di più, leggi la documentazione ufficiale.
Grazie a Kohana, la manutenzione del codice è un compito facile e l'aggiunta di nuove funzionalità è un gioco da ragazzi. Spero che questo tutorial ti sia piaciuto. Resta sintonizzato per saperne di più su Kohana.