9.óra – CodeIgniter Framework #1
Gyimesi Ákos
[email protected] http://webprog.gy-i-m.com
Miért van szükség keretrendszerre? ●
„Keretet” ad, hogyan álljunk neki a feladatnak –
Előre definiált felépítés, ami az esetek 90%-ában jó
–
Jól kitalált architektúra ⇒ nem lesz „spagettikód”
Miért van szükség keretrendszerre? ●
Tipikus webes feladatok megkönnyítése –
űrlapkezelés (input validáció, kirajzolás...)
–
munkamenet (session) kezelés
–
adatbázis kezelés ● ●
–
rendes email küldő rendszer ●
–
csatolmányok, HTML levelek
hibakezelés ●
–
DB kapcsolat(ok) nyilvántartása ismétlődő feladatok (pl. egyszerű INSERT) megkönnyítése
PHP error helyett „We're sorry” oldal + naplózás
cache-elés
Miért van szükség keretrendszerre? ●
Jobb keretrendszerekben van ezenkívül: –
fejlesztői - tesztelő - éles konfigurációk elkülönítése
–
automatikus adatbázis migrálás éles rendszeren
–
tesztelői keretrendszer ● ● ●
unit tesztek futtatása, kiértékelése összetett cselekvéssorozat (pl. regisztráció) tesztelése tesztadatok kezelése (külön adatbázisban)
–
web service támogatás
–
admin felület generátor Nem nekünk kell feltalálni a spanyolviaszt...
Egy kis történelem... ●
2004: Ruby on Rails megjelenése –
szerző: David Heinemeier Hansson (37signals)
–
forradalmi újítás az akkori keretrendszerekhez képest: ● ● ● ●
nagyon minimalista, MVC alapú felépítés Convention over Configuration DRY (Don't Repeat Yourself!) a kód tömör, olvasható, „élvezet” kódolni
Ruby on Rails - példa ●
Egyszerű könyvadatbázis alkalmazás: –
http://example.com - könyvek listázása
–
http://example.com/create - új könyv beszúrása ● ●
–
űrlap validáció van jogosultságellenőrzés nincs
adott: egy SQL adatbázis 'books' táblával:
Ruby on Rails - példa app/controllers/book_controller.rb: class BookController < ApplicationController def index @books = Book.find :all end end Adatbázis lekérés ... helyett
Ruby on Rails - példa app/models/book.rb: class Book < ActiveRecord::Base end
?!
Ruby on Rails - példa app/views/news/index.rhtml: <% @books.each do |book| %>
<%= h book.title %>
<%= h book.description %>
<% end %> htmlspecialchars() ☺
Ruby on Rails - példa app/views/layouts/application.rhtml:
Könyvesbolt <meta content='text/html; charset=utf-8' http-equiv='Content-type' /> include-ok helyett
<%= yield %>
Ruby on Rails - példa app/controllers/book_controller.rb: class BookController < ApplicationController def index @books = Book.find :all end beszúródik VAGY megjelenik
def create POST adattal @book = Book.new feltöltés if request.post? @book.update_attributes params[:book] redirect_to(:action => 'index') if book.save end end validál + beszúr end + redirect-el
Ruby on Rails - példa app/models/book.rb: class Book < ActiveRecord::Base validates_presence_of :title, :price validates_numericality_of :price end
??!!
Ruby on Rails - példa app/views/news/create.rhtml:
validációs hibák kiírása
<% form_for :book do |f| %> <%= f.error_messages %>
űrlap mezők kiírása + kitöltése a POST-olt adatokkal
Title: <%= f.text_field :title %>
Description: <%= f.text_area :description %>
Price: <%= f.text_field :price %>
<%= submit_tag 'OK' %>
<% end %>
submit gomb
Ruby on Rails - példa
Listázó oldal + beszúró űrlap validációval: 33 sor
Ezért már érdemes keretrendszert használni!... (bár azért PHP-tól ilyen szintű kényelmet ne várjunk...)
MVC keretrendszerek ●
Ruby on Rails alapelvek (ismétlés): –
egyszerű, MVC alapú felépítés
–
Convention over Configuration
–
Don't Repeat Yourself
MVC - Model View Controller ●
Elv: élesen szét kell választani 3 dolgot: –
Model: adatok kezelése ● ●
–
View: megjelenítés ● ●
–
adatbázisműveletek adatok ellenőrzése (validáció) HTML vagy más output előállítása tehát csak ebben van print utasítás
Controller: oldal logikáját adja: ● ●
●
bemenete az user input (GET, POST, SESSION) user input alapján a Model-el műveleteket végez (pl. rekordokat kér el az adatbázisból) Model outputját átadja a View-nak ⇒ megjelenítés
MVC - Model View Controller ●
Másképpen megfogalmazva: –
Model: ● ●
–
View: ● ●
–
adatbáziskezelő osztályok összessége csak itt vannak SQL-ek HTML sablonok összessége más nincs itt, csak: print, if-then-else, foreach, kiíráshoz szükséges segédfüggvények
Controller: ● ● ●
ez az, amit az user közvetlenül meghív a böngészőből csak itt van: GET, POST, SESSION, redirect az ő feladata, hogy kiválassza a működéshez szükséges Model-t és View-t
MVC - Model View Controller
HTTP kérés
http://example.com/create + POST adatok
WEB APPLICATION
SQL
Database HTTP válasz HTML oldal vagy redirect kérés
MVC - Model View Controller
isAdmin( $_SESSION['uid'] )
create()
Book Controller
User Model
true
SELECT
createBook($formData) URL POST, COOKIE
$errors
Dispatcher
HTML
$formData $errors
Create Book View
WEB APPLICATION
Book Model
INSERT
Database
MVC - Model View Controller ●
Miért jó ez a kódelválasztás? –
Model: nem függ az user inputtól ●
–
⇒ pl. User model bármilyen controllerből használható
View: pár input paraméter alapján ír ki HTML-t ● ●
⇒ design bátran átalakítható ⇒ HTML kiírás is újrahasznosítható –
–
pl. létrehozás űrlapot lehet szerkesztésre is használni, csak a $formData-ban kell mást átírni
Controller: nem lesz spagettikód ●
itt van a legbonyolultabb logika ⇒ jó, hogy nem itt van minden más is
Convention over Configuration ●
Válasz az „enterprise” rendszerekre:
●
„mindent konfiguráljunk XML-ben” - helyett: –
legyen egy default, ami az esetek 90%-ában jó ⇒ semmi teendőnk
–
biztosítsunk lehetőséget a maradék 10%-ra is
Convention Over Configuration ●
Példa: URL parse-olás –
megfigyelés: a legtöbb oldal 2-3 szintű: ●
news – – – –
●
index view ● ID create edit ● ID
user – – –
login register forgot_password
Convention Over Configuration ●
Példa: URL parse-olás –
megfigyelés: a legtöbb oldal 2-3 szintű:
–
ötlet: legyen az URL struktúrája is ilyen! http://example.com/news http://example.com/news/create http://example.com/news/view/123
action id
Convention Over Configuration ●
Példa: URL parse-olás –
megfigyelés: a legtöbb oldal 2-3 szintű:
–
ötlet: legyen az URL struktúrája is ilyen! http://example.com/news http://example.com/news/create http://example.com/news/view/123 controller action id
ötlet 2: legyen a controller struktúrája is ilyen!
Convention over Configuration ●
Controllerek felépítése (most már PHP): application/controllers/news.php: class News extends Controller { function index() { // http://example.com/news } function create() { // http://example.com/news/create }
}
function view($id) { // http://example.com/news/view/123 }
Ahol ez nem jó: regexp alapú URL parse-olás
Don't Repeat Yourself ●
Gyakran használt funkciók megkönnyítése –
Példa: SQL select // Ruby on Rails @news = News.find_by_id(42) // CodeIgniter $result = $this->db->get_where('news', array( 'id' => 42 ));
PHP MVC keretrendszerek ●
●
Legismertebb PHP keretrendszerek: –
Zend Framework
–
Symfony
–
CakePHP
–
CodeIgniter
–
Kohana
–
Yii
–
...
Mindegyik kb. hasonló felépítésű, hasonló elvekre épül
CodeIgniter ●
A CodeIgniter keretrendszer –
Első keretrendszernek ideális, mert: ●
●
Kicsi, egyszerű, a keretrendszer kódja is könnyen átlátható Minimális „magic” van benne: – –
● ● ●
csak osztály leszármazás + függvényhívás ⇒ könnyű átlátni, melyik hívás hova megy View: egyszerű PHP szkriptek
Nagyon jól dokumentált (http://codeigniter.com) Működik „out-of-the-box” (kb. csak egy unzip kell) Mindent tud, ami kell a nagyházihoz: – – – –
fel- és letöltések támogatása email küldés űrlap validáció ...
CodeIgniter ●
A CodeIgniter hátrányai: –
PHP 4 alapú: ●
régi stílusú osztályok használata –
●
nincs benne SQLite3 támogatás –
–
⇒ PDO driver-t telepíteni kell
Hiányzó funkciók: ● ●
–
konstruktor neve: __construct() helyett ClassName()
nincs automatikus CSRF védelem DB réteg (ActiveRecord) elég primitív (PHP5 kéne...)
Továbblépéshez ajánlott: Kohana Framework ● ●
CodeIgniter-ből vált le, de újraírták PHP 5-ben elegánsabb, modernebb - de hiányos a dokumentáció...