Kohana este un cadru PHP 5 care utilizează modelul arhitectural al Model View Controller (MVC). Există mai multe motive pentru care ar trebui să alegeți Kohana, dar cele mai importante sunt securitatea, greutatea și simplitatea. În acest tutorial, vă voi prezenta principalele caracteristici ale acestuia și, cu o simplă demonstrație, vă voi arăta cât timp vă poate salva Kohana.
Kohana este un framework PHP5 care utilizează modelul arhitectural al Model View Controller. MVC păstrează logica aplicației
separat de prezentare. Acest lucru ne permite să creăm un cod mai curat și să economisim timp pentru căutarea de erori.
În necunoscut cu acest model:
Kohana a fost inițial o furculiță a CodeIgniter (CI), care este un produs open-source de la EllisLab. Există multe asemănări între CI și Kohana, dar tot codul este fie nou, fie complet rescris. După cum puteți citi pe site-ul oficial Kohana, principalele caracteristici sunt:
Să începem. Vizitați site-ul oficial Kohana http://kohanaphp.com și faceți clic pe caseta verde din colțul din dreapta pentru a descărca ultima versiune. Toate bibliotecile, ajutoarele și vizualizările Kohana sunt incluse în pachetul de descărcare implicit, dar puteți selecta module suplimentare, instrumente de furnizor și limbi dacă doriți. În scopul acestui tutorial, pachetul implicit poate fi suficient. Faceți clic pe "Descărcați Kohana!" pentru a începe descărcarea.
După ce ați terminat descărcarea:
$ config ['site_domeniu'] = 'localhost / kohana';
Kohana va rula în aproape orice mediu cu o configurație minimă. Există câteva cerințe minime ale serverului:
Există, de asemenea, unele extensii necesare.
Dacă instalarea se termină cu succes, veți fi redirecționat către această pagină de test:
Dacă oricare dintre teste eșuează, trebuie să le corectați înainte de a vă deplasa înainte.
Dacă au trecut toate testele, accesați directorul Kohana și eliminați sau redenumiți scriptul install.php. Reîmprospătați și veți vedea o pagină de bun venit astfel:
Kohana este gata să plece. Nu este necesară nicio altă configurație. Acest cadru este uimitor. Nu-i așa? Să revedem un cod. urmați-mă.
Tutorialele de programare canonic încep cu exemplul "Bună ziua". Cred că, în schimb, o aplicație simplă vă poate oferi o idee clară despre funcționarea cadrului. Deci, vom construi un manager de colecție CD-uri - doar pentru o demonstrație distractivă. Înainte de a începe codarea, este necesară o scurtă introducere în sistemul de fișiere Kohana.
Cererea noastră va fi plasată în cerere pliant. În acest dosar există mai multe subdirectoare, dar avem nevoie de următoarele pentru proiectul nostru:
Subpoldurile rămase nu sunt necesare pentru acest tutorial, așa că vă invit să aflați mai multe pe site-ul web Kohana.
sistem directorul găzduiește nucleul Kohana și instrumentele Kohana cum ar fi bibliotecile, ajutoarele și fișierele de configurare predefinite. În acest proiect vom folosi câteva biblioteci și niște ajutoare - instrumente bune pentru a vă grăbi munca.
bunuri dosarul nu este un dosar predefinit Kohana. Am creat-o pentru fișiere media precum CSS, JS și imagini. Vă voi arăta cum să includeți aceste fișiere în proiect.
module folderul este locul pentru a pune colecții reutilizabile de fișiere înrudite, care împreună adaugă o anumită funcționalitate unei aplicații. Modulul de autentificare, furnizat de echipa Kohana, este un exemplu de modul.
Aceasta este o scurtă introducere a sistemului de fișiere Kohana, dar este suficient pentru scopurile acestui tutorial. Nu vreau să te deranjez mai mult cu teoria.
Am ales MySQL ca DBMS-ul meu, dar amintiți-vă că Kohana sprijină, de asemenea, MsSQL, MySQLi, PostgreSQL, PDOSqlite. Creați o bază de date numită "cd_collection" sau alegeți numele pe care îl preferați și executați următorul SQL prin phpMyAdmin sau orice alt instrument pentru a gestiona administrarea MySQL.
CREATE TABLE "album" ('id' int (11) NOT NULL auto_increment, 'nume' varchar (50) collate utf8_bin NOT NULL, 'autor' varchar (50) collate utf8_bin NOT NULL, 'genre_id' int , KEY PRIMARY ('id'), CHEIE 'genre_id' ('genre_id')) ENGINE = InnoDB DEFAULT CHARSET = utf8 COLLATE = utf8_bin AUTO_INCREMENT = 19; INSERT IN 'albums' ('id', 'name', 'author', 'genre_id') VALUES (2, 'Lines, Vines and Trying Times' , "The Black Eyed Peas", 16), (4, "Relapse", "Eminem", 18), (5, "Monuments and Melodies", Incubus, Jackson, 16), (7, "Înapoi în negru", "AC / DC", 4), (8, "Partea întunecată a Lunii", Pink Floyd, (10), "Backstreet Boys", "Millennium", 16), (11, "Rumors", "Fleetwood Mac", 4) , Denumită în continuare "Shania Twain", 16), (13, "Led Zeppelin IV", "Led Zeppelin", 4), (14, "Jagged Little Pill", Alanis Morissette, (16, "Falling in You", "C'line Dion", 16), (17, "Music Box", "Mariah Carey", 16 ), (18, 'Născut în SUA', 'Bruce Springsteen', 4); CREATE TABLE 'genres' ('id' int (11) NOT NULL auto_increment, varchar (50) collate utf8_bin NOT NULL, PRIMARY KEY ('id'), nume de cod UNIQUE '(' name ')) ENGINE = I nnoDB CARACTERISTICI DEFAULT = utf8 COLLATE = utf8_bin AUTO_INCREMENT = 22; INSERT IN 'genres' ('id', 'name') VALORI (1, "Alternative Rock"), (2, "Blues" , "Țara"), (6, "Dance"), (7, "Folk" Indie Music "), (12," Jazz "), (13," latină "), (14," New Age " Soul "), (18," Rap "), (20," Soundtracks "), (21," World Music "); ALTER TABLE 'albumuri' ADD CONSTRAINT 'genre_inter_relational_constraint' FOREIGN KEY ('genre_id') REFERINȚE 'genres' ('id') DESCHISE CASCADE LA UPCATE CASCADE;
După cum puteți vedea, SQL creează două tabele, albume și genuri și le populare cu unele date. Ultima instrucțiune SQL adaugă o constrângere pentru cheia externă "genre_id".
Structura bazei de date este foarte simplă și nu are nevoie de prea multe explicații.
Acum, trebuie să-i spui lui Kohana unde se află baza dvs. de date și cum să-l accesezi. Editați fișierul global de configurare Sistem / config / database.php după cum urmează
$ config ['default'] = array ('benchmark' => TRUE, 'persistent' => FALSE, 'connection' => array (' pass '=>' localhost ',' port '=> FALSE,' socket '=> FALSE,' database '=>' cd_collection '),' character_set '=> 'table_prefix' => ',' obiect '=> TRUE,' cache '=> FALSE,' escape '=> TRUE);
Acest cod îi spune lui Kohana să se conecteze la o bază de date MySQL numită "cd_collection" pe localhost cu numele de utilizator "root" și parola "root". Trebuie să modificați aceste setări în funcție de configurația serverului de bază de date.
Să creăm acum primul nostru controlor. Amintiți-vă aceste convenții.
De asemenea, rețineți cum Kohana structurează adresele URL și cum puteți apela o metodă de controler; de exemplu http: //hostname/kohana_directory/index.php/controller/function.
Să aruncăm o privire la acest controler simplu.
PHP5 OOP este o condiție prealabilă. Deci, dacă nu sunteți bine-versat, puteți afla mai multe aici.
Funcția constructor, numită __construct, inițializează clasa și apelează constructorul părinte.
Funcția index este funcția implicită, deci va fi apelată dacă sunăm fără controler
specificând orice funcție (de exemplu, http: //localhost/index.php/kohana/album. După ce controlerul de nume
nu există nici o funcție, se va apela funcția index implicită.)Având în vedere aceste reguli de bază, să ne concentrăm asupra aplicației noastre. Controlerul de alb implementează toate acțiunile pentru
gestionarea colecțiilor de albume. Acest controler ne permite să creăm un nou album pentru a afișa albumele stocate în baza noastră de date,
pentru a actualiza un album și pentru a șterge un album.Deci, să schimbăm clasa după cum urmează.
Creați un fișier numit album.php în application / controllers / și lipiți următoarele.
album_model = nou model_model; $ this-> genre_model = genre_model nou; $ this-> list_view = new Vezi ('list'); $ this-> update_view = new Vezi ('update'); $ this-> create_view = new Vizualizați ('creați'); indexul funcției publice () $ this-> show_albums_list (); funcția privată show_albums_list () $ albums_list = $ this-> album_model-> get_list (); $ This-> list_view-> set ( 'albums_list', $ albums_list); $ This-> list_view-> render (TRUE); funcția publică show_create_editor () $ this-> create_view-> set ('genres_list', $ this-> get_genres_list ()); $ This-> create_view-> render (TRUE); funcția publică show_update_editor ($ id) $ album_data = $ this-> album_model-> citește ($ id); $ This-> update_view-> set ( 'album_id', $ album_data [0] -> id); $ This-> update_view-> set ( 'name', $ album_data [0] -> nume); $ This-> update_view-> set ( 'autor', $ album_data [0] -> autor); $ 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); funcția publică create () $ album_data = array ('name' => $ this-> input-> post ('name'), 'genre_id' => $ this-> input-> post ('genre_id')); $ This-> album_model-> crea (album_data $); URL :: redirecționare ( 'albumul'); public post funcțional () $ album_data = array ('name' => $ this-> input-> post ('name'), 'genre_id' => $ this-> input-> post ('genre_id')); $ This-> album_model-> actualizare ($ this-> introducere de text> post ( 'album_id'), $ album_data); URL :: redirecționare ( 'albumul'); funcția publică șterge ($ id) $ this-> album_model-> șterge ($ id); URL :: redirecționare ( 'albumul'); funcția privată get_genres_list () $ db_genres_list = $ this-> genre_model-> get_list (); $ genres_list = array (); dacă sizeof ($ db_genres_list)> = 1) foreach ($ db_genres_list ca element $) $ genres_list [$ item-> id] = $ item-> name; return $ genres_list;Permiteți-mi să vă explic ce face acest cod.
Cinci variabile de membru sunt declarate în partea de sus a clasei:
privat $ album_model; privat $ genre_model; privat $ list_view; private $ create_view; privat $ update_view;Acești membri sunt privați, pentru că vreau să limitez vizibilitatea numai la această clasă.
În metoda constructivă modelul și obiectele de vizualizare sunt create folosind cei cinci membri:
$ this-> album_model = nou Album_Model; $ this-> genre_model = genre_model nou; $ this-> list_view = new Vezi ('list'); $ this-> update_view = new Vezi ('update'); $ this-> create_view = new Vizualizați ('creați');Pentru a crea un obiect model utilizați această sintaxă:
$ obj_name = nou nume_model;Pentru a crea un obiect de vizualizare, utilizați această sintaxă:
$ obj_name = nou Vizualizare ('nume_file_exemplu');Acum există două obiecte pentru a accesa modelul de album și gen și trei obiecte pentru a accesa vizualizările necesare pentru a face prezentarea.
Metoda index indică metoda show_albums_list care conține toate albumele stocate în baza de date.
$ albums_list = $ acest-> album_model-> get_list (); $ This-> list_view-> set ( 'albums_list', $ albums_list); $ This-> list_view-> render (TRUE);În această metodă puteți vedea modul în care modelul și obiectul de vizualizare sunt folosite pentru a accesa metodele relative. "get_list" este o metodă de model (vom vedea mai târziu) care returnează toate albumele stocate în baza de date. Rezultatul este salvat în matricea "$ album_list". Pentru a trece matricea de rezultate de la controler la vedere, metoda "set" este apelată pe obiectul de vizualizare. Această metodă necesită doi parametri: o nouă variabilă gol (album_list) care să conțină datele unei variabile existente ($ album_list). Acum, noua variabilă "album_list" conține arhiva $ album_list (vom vedea mai târziu cum să afișăm conținutul din vizualizare). Metoda "rendere", cu parametrul TRUE, este necesară pentru a trimite date către browser.
Metoda show_create_editor afișează interfața de utilizator pentru a insera un nou album.
$ This-> create_view-> set ( 'genres_list', $ this-> get_genres_list ()); $ This-> create_view-> render (TRUE);Lista genurilor este transmisă spre vizualizare.
Metoda show_update_editor arată interfața de utilizator pentru a actualiza un album existent.
$ album_data = $ this-> album_model-> citește ($ id); $ This-> update_view-> set ( 'album_id', $ album_data [0] -> id); $ This-> update_view-> set ( 'name', $ album_data [0] -> nume); $ This-> update_view-> set ( 'autor', $ album_data [0] -> autor); $ 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" este o metodă model (vom vedea mai târziu) care returnează datele ($ album_data) ale albumului cu un id egal cu $ id. Apoi, fiecare element al albumului de date returnat este transmis la vizualizare.
Metoda de creare primește date din nou, pentru un nou album, iar datele sunt stocate în baza de date.
$ album_data = array ('name' => $ this-> input-> post ('name'), 'author' => $ this-> input-> post ('author'), 'genre_id' => $ this -> intrare-> post ("genre_id")); $ This-> album_model-> crea (album_data $); URL :: redirecționare ( 'albumul');$ album_data este un matrice care conține datele POST din vizualizare. Pentru a salva albumul, matricea este trecută la metoda modelului de creare. Ultima linie este un apel la o metodă de ajutor. Ajutorii sunt pur și simplu funcții care vă ajută în dezvoltarea. Clasele auxiliare sunt încărcate automat de cadru. Ajutorii sunt declarați ca metode statice ale unei clase, deci nu este nevoie să instanțiați clasa. În acest caz este apelată metoda "redirect" a ajutorului "url" și îi spune lui Kohana să redirecționeze browserul spre controlerul de albume. Acest lucru evită o inserție nouă (de exemplu, apăsând F5).
"Ajutorii sunt pur și simplu funcții care vă ajută în dezvoltarea."
Metodele de actualizare și ștergere funcționează în același mod ca și metoda de creare de mai sus.
Ultima metodă get_genres_list primește lista de genuri din model ($ db_genres_list) și construiește o nouă matrice ($ genres_list) pentru caseta de selectare din vizualizări.
$ db_genres_list = $ acest-> genre_model-> get_list (); $ genres_list = array (); dacă sizeof ($ db_genres_list)> = 1) foreach ($ db_genres_list ca element $) $ genres_list [$ item-> id] = $ item-> name; return $ genres_list;Pasul 8: Creați un model de proiect
Să creați acum modele pentru aplicația noastră web. Amintiți-vă aceste convenții.
Aici este codul de model al albumului. Creați un fișier numit album.php în cerere / modele / și lipiți codul de mai jos.
album_table = 'albume'; $ this-> genre_table = "genuri"; funcția publică citește ($ id) $ this-> db-> unde ('id', $ id); $ interogare = $ this-> db-> get ($ this-> album_table); returnează $ query-> result_array (); funcția publică șterge ($ id) $ this-> db-> șterge ($ this-> album_table, array ('id' => $ id)); actualizarea funcției publice ($ id, $ data) $ this-> db-> actualizare ($ this-> album_table, $ data, array ('id' => $ id)); funcția publică crează ($ date) $ this-> db-> insert ($ this-> album_table, $ data); funcția publică get_list () $ this-> db-> selectați ('albums.id ca id, albums.name ca nume, albums.author ca autor, genres.name ca gen "); $ This-> DB> de la ($ this-> album_table); $ This-> DB> se alăture ($ this-> genre_table, 'genres.id', 'albums.genre_id'); $ interogare = $ this-> db-> get (); returnează $ query-> result_array ();
Toate metodele din modele fac uz de sintaxa Builder Query. Acest instrument Kohana accelerează timpul de dezvoltare a bazei de date și simplifică crearea de interogări.
Două variabile membre sunt declarate în partea de sus a clasei:
privat $ album_table; privat $ genre_table;
Acești membri sunt privați, pentru că vreau să limitez vizibilitatea numai la această clasă. Acestea sunt containerele pentru numele tabelelor de baze de date.
Prima linie din metoda constructorului încarcă biblioteca de baze de date Kohana în $ this-> db. În al doilea și al treilea rând cei doi membri ai clasei sunt inițializați.
părinte :: __ construct (); $ this-> album_table = 'albume'; $ this-> genre_table = "genuri";
Interogarea din metoda de citire preia înregistrările din album care au un anumit identificator ("id id").
$ this-> db-> unde ('id', $ id); $ interogare = $ this-> db-> get ($ this-> album_table); returnează $ query-> result_array ();
Interogarea din metoda de ștergere șterge rândul de tabele al albumelor care au un anumit identificator ("id id").
$ this-> db-> șterge ($ this-> album_table, array ('id' => $ id));
Interogarea din metoda de actualizare actualizează rândul de tabele al albumelor care are un anumit identificator ("$ id") cu valori noi din matricea "$ data".
$ this-> db-> actualizare ($ this-> album_table, $ data, array ('id' => $ id));
Matricea "$ data" trebuie să conțină nume de înregistrări ca chei ale matricei și valoare ca valori ale matricei. Matricea "$ data" trebuie să aibă acest formular:
$ data = array ('name' => 'numele albumului', 'author' => 'autor_name', 'genre_id' => 'genre_id');
Interogarea din metoda de creare inserează o nouă înregistrare cu valorile matricei "$ data".
$ this-> db-> inserați ($ this-> album_table, $ data);
Matricea "$ data" trebuie să aibă acest formular:
$ data = array ('id' => 'album_id', 'name' => 'numele albumului', 'author' => 'autor_name', 'genre_id' => 'genre_id');
Interogarea din metoda get_list preia toate rândurile de albume.
$ this-> db-> select ('albums.id ca id, albums.name ca nume, albums.author ca autor, genres.name ca gen'); $ This-> DB> de la ($ this-> album_table); $ This-> DB> se alăture ($ this-> genre_table, 'genres.id', 'albums.genre_id'); $ interogare = $ this-> db-> get (); returnează $ query-> result_array ();
Acum, modelul de gen. Creați un fișier numit genre.php în cerere / modele / și lipiți codul de mai jos:
genre_table = 'genuri'; funcția get_list () $ interogare = $ this-> db-> get ($ this-> genre_table); returnează $ query-> result_array ();
Acest model este foarte simplu, așa că nu voi mai pierde timp pentru a comenta acest lucru. Modelele și controlerul sunt gata de plecare. Să lucrăm acum la Viziuni.
Vizionările sunt fișiere care conțin stratul de prezentare pentru aplicația dvs. Scopul este să păstrați aceste informații separate de logica aplicațiilor pentru reutilizarea ușoară și codul curat. Pentru acest proiect, sunt necesare trei vizualizări: o listă pentru a afișa colecția de albume, o vizualizare pentru a crea un album nou și o vedere pentru a edita un album existent.
Creați un fișier numit list.php în application / opinii / și lipiți următorul cod în:
CD COLECȚIE
Colecția CD | ||||
Numele albumului | Autor | gen literar | "$ Item-> numele." | "ecou""$ Item-> autor." | "ecou""$ Item-> gen." | "ecou"“.Html :: ancora ( 'album / șterge /'.$ item-> id, html :: imagine (' Active / images / delete.png ')).“ | "ecou"“.Html :: ancora ( '/ show_update_editor /'.$ item-> ID album, html :: imagine (' Active / images / edit.png ')).“ | "ecou"";>>
Această vizualizare arată o pagină html care conține o listă a tuturor albumelor. Această listă a fost creată utilizând buclă foreach care tipărește informațiile într-o tabelă html. Pentru fiecare rând de albume, există două imagini: o "cruce roșie" și o "buzunar". Acestea vizează, respectiv, metoda de ștergere a controlerului și metoda de actualizare. Ambele transferă id-ul albumului la controlerul albumului folosind o cerere de solicitare. Deasupra listei există un buton pentru a crea noi albume. În acest cod folosim de asemenea un html helper oferit de Kohana care accelerează operațiile de scriere a paginilor html.
Să creați acum un fișier numit create.php în application / opinii /.
CD COLECȚIE
Creați un nou album | ".form :: label ('name', 'Nume:')." | "ecou"“.Form :: input ( 'nume', ")." | "ecou""ecou"
".form :: label (" autor "," autor: ")." | "ecou"“.Form :: input ( 'autor', ")." | "ecou"
".form :: label ('genre', 'Genre:')". | "ecou"".Form :: drop-down ( 'genre_id', $ genres_list)." | "ecou"
".formate :: submit ('submit', 'Creare album')." | "ecou"
Ultima, dar nu în ultimul rând, este actualizarea. Să creăm un fișier numit update.php în application / opinii /.
CD COLECȚIE
Actualizați albumul | ".form :: label ('name', 'Nume:')." | "ecou"".form :: input ('name', $ name)." | "ecou""ecou"
".form :: label (" autor "," autor: ")." | "ecou"".form :: input (" autor ", $ autor)." | "ecou"
".form :: label ('genre', 'Genre:')". | "ecou"".form :: dropdown ('genre_id', $ genres_list, $ genre_id)." | "ecou"
".formate :: submit ('submit', 'Update album')." | "ecou"
Primul este un editor simplu care permite utilizatorului să introducă informații despre un nou album.
Câmpurile precum autorul și numele vor fi inserate utilizând o intrare și un gen HTML folosind a
cutie combo. Odată ce utilizatorul face clic pe butonul de creare, toate informațiile sunt transmise,
ca cerere POST, la metoda de creare / actualizare din controlerul de albume. Atunci când controlorul primește aceste postate
variabile, el numește modelul care introduce un nou album în baza de date. Formele, în ambele puncte de vedere, utilizează ajutorul lui Kohana.
Pentru a da un pic de stil aplicației noastre, creați bunuri folder din rădăcina Kohana la același nivel al dosarului aplicației. Deschideți-l și creați două foldere noi: css și imagini.
În css folder crea un nou fișier numit style.css și lipiți aceasta:
o font-familie: Verdana, Geneva, Arial, Helvetica, sans-serif; font-weight: normal; font-size: 12px; culoare: # 00F; vertical-align: text-top; img frontieră: 0; etichetă font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-weight: normal; font-size: 12px; intrare border: 1px solid # 000; selectați width: 185px; table.editor text-aliniere: centru; font-familie: Verdana, Geneva, Arial, Helvetica, sans-serif; font-weight: normal; font-size: 11px; culoare: #fff; lățime: 280px; fundal-culoare: # 666; frontieră: 0px; colaps de frontieră: colaps; spațierea distanței: 0px; table.editor td.editor_title background-color: # 666; culoare: #fff; padding: 4px; text-aliniere: stânga; font-weight: bold; font-size: 16px; table.editor td padding: 4px; table.list text-aliniere: centru; font-familie: Verdana, Geneva, Arial, Helvetica, sans-serif; font-weight: normal; font-size: 11px; culoare: #fff; lățime: 280px; fundal-culoare: # 666; frontieră: 0px; colaps de frontieră: colaps; spațierea distanței: 0px; table.list td.item fundal-culoare: #CCC; culoare: # 000; padding: 4px; text-aliniere: stânga; frontieră: 1px #fff solid; table.list td.list_title, table.list td.headers fundal-culoare: # 666; culoare: #fff; padding: 4px; text-aliniere: stânga; margine de fund: 2px #fff solid; font-weight: bold; table.list td.list_title font-size: 16px; table.list td.headers font-size: 12px;
Acum, copiați următoarele imagini la imagini pliant:
Asta e tot. Punctați browserul dvs. la http: //localhost/kohana/index.php/album și ar trebui să vedeți ceva similar cu acesta:
Dacă încercați să creați un album nou sau să editați unul existent, ar trebui să vedeți ceva similar cu acesta:
Desigur, unele îmbunătățiri sunt necesare pentru această aplicație, dar cu o cantitate mică de cod, ați creat o mică aplicație web.
Acum, știi cum să folosești modelul MVC cu Kohana și cum să folosești bibliotecile bazei de date și ajutoarele. Pentru a afla mai multe, citiți documentația oficială.
Mulțumită lui Kohana, întreținerea codului este o sarcină ușoară, iar adăugarea de noi caracteristici este un cinch. Sper că ți-a plăcut acest tutorial. Stay tuned pentru a afla mai multe despre Kohana.