Tworzenie witryn internetowych PHP/Java (mgr inż. Marek Downar)
Co narzuca MVC? Architekturę aplikacji wykonaną w konwencji Model Widok - Kontroler Model reprezentacja danych i dostępu do nich Widok elementy interfejsu użytkownika Kontroler realizacja logiki biznesowej, sterowanie aplikacją, modułami
Zalety MVC Brak zależności kodowych warstwy modelu od warstwy widoku Łatwiejsza możliwość wprowadzania zmian do widoku (występuje częściej niż modelu) Przejrzystość aplikacji w strukturze Możliwość rozgraniczenia prac pomiędzy specjalistów z określonych dziedzin
Wady MVC struktura projektu wprowadzenie dodatkowej abstrakcji, wystąpienie nowych zachowań, całość trudniejsza do debugowania Zmiana modelu pociąga za sobą konieczność zmian wszystkich widoków na nim bazujących Trudne testowanie warstwy widoku
ORM Object-Relational Mapping Odwzorowanie obiektowo-relacyjne Przedstawienie modelu bazy danych przy pomocy podejścia obiektowego z zachowaniem relacji
Jak używać ORM? Każdej tabeli odpowiada klasa Każdemu polu w klasie odpowiada zmienna w klasie Realizacja zmian w bazie danych powinna być oparta na działaniu na klasach bez konieczności wprowadzania zapytań SQL
Zastosowanie ORM Gdzie go stosować? System wykorzystujący bazę danych jako źródło danych jest zapisany obiektowo Baza danych jest relacyjna (zawiera wskazania jednej tabeli na inną lub na siebie samą) Przy średnich i dużych projektach
Zalety ORM Developer operuje w całym projekcie wyłącznie na obiektach Brak konieczności znajomości zapytań SQL dla podstawowych operacji Utrzymywanie połączeń i zarządzanie nimi Wstępna ochrona przed atakami SQL Injection
Wady ORM Występowanie problemów z wydajnością Konieczność wprowadzania ręcznych zmian w ORM w przypadku bardziej skomplikowanych zapytań
OOP Powiązanie danych (pól) z zachowaniami (procedurami) w ramach obiektu (klasy) Różne w stosunku do pisania proceduralnego (gdzie brak jest powiązań między polami, a procedurami)
Zastosowanie OOP Jeśli można to wszędzie Dobre przedstawienie zależności komponentów Ułatwione testowanie wybranych komponentów z całej aplikacji Możliwość podmiany klasy zachowując interfejs wiążący ją z innymi
MVC, ORM, OOP Dobry projekt powinien umieć wiązać wszystkie wymienione elementy: MVC, ORM, OOP Powinien wspierać programistę w wytwarzaniu aplikacji zgodnie z wymienionymi zasadami Powinien ułatwiać testowanie, utrzymanie i zarządzanie zmianami w tworzonym projekcie zachowując pierwotną koncepcję
Kierunek rozwoju Pisanie aplikacji samodzielnie od podstaw w języku PHP: Monotonne i czasochłonne Wysoki nakład pracy potrzebny w wytworzenie koniecznych klas i funkcji podstawowych (ORM) Konieczność samodzielnego porządkowania plików w strukturze Jak można ułatwić sobie pracę pisząc w PHP i chcąc zachować wymienione standardy, a jednocześnie robić to wydajnie? Zastosować jeden ze szkieletów aplikacji webowej wspomagający developerów podczas pracy
CakePHP Darmowy framework służący do szybkiego wytwarzania aplikacji internetowych przy zachowaniu ich elastyczności i modyfikowalności Szerokie i aktywne community Dogodne licencjonowanie Kompatybilność z PHP 4 i 5 Zgodność z MVC Zintegrowany generator CRUD Wbudowany mechanizm walidacji formularzy Lokalizacja, cache, ACL...
Model MVC w CakePHP
Komponenty Wspomagają kontrolery, posiadając własny element logiki biznesowej. beforefilter() - wykonanie przed logiką kontrolera BeforeRender() - wykonanie po logice kontrolera ale przed wygenerowaniem widoku AfterFilter() - wykonanie po logice kontrolera oraz po wygenerowaniu widoku.
Helpery Tak jak komponenty dla kontrolerów elementy wpomagają generowanie widoku Wykorzystywane w różnych widokach, bądź w widokach generowanych z listy
Behaviours Tak jak komponenty oraz helpery, zachowania dodają nową funkcjonalność po stronie modelu aplikacji beforefind() afterfind() beforevalidate() beforesave() aftersave() beforedelete() afterdelete()
CakePHP typowe żądanie
Struktura folderów Config - pliki konfiguracyjne, szczegóły połączenia z bazą danych, uruchamiania, konfiguracja podstawowa silnika Controllers zawiera kontrolery i komponenty aplikacji Libs zawiera własne biblioteki Locale pliki internacjonalizacji Models źródła danych, modele i zachowania (behaviours) Plugins dodatki Tmp pliki tymczasowe Vendors biblioteki i klasy pochodzące od innych dostawców
Konwecje CakePHP Plik zawierający klasę MojaKlasa powinien posiadać nazwę moja_klasa.php MojController moj_controller.php MojComponent, MojBehaviour, MojView, MojHelper moj.php Nazwy kontrolerów dla danej tabeli modelu są w liczbie mnogiej (model User kontroler UsersController) Tabela w bazie danych: "people" Model opisujący tę tabelę: "Person" (/app/models/person.php) Klasa kontrolera: "PeopleController" (/app/controllers/people_controller.php) widok /app/views/people/index.ctp
Kontroler (1) Klasa AppController zdefiniowana w /app/app_controller.php powinna zawierać metody wspólne dla wszystkich kontrolerów aplikacji <?php?> # /app/controllers/recipes_controller.php class RecipesController extends AppController { } function view($id) { } function share($customer_id, $recipe_id) { } function search($query) { }
Kontroler (2) Zdefiniowane atrybuty class RecipesController extends AppController { var $name = 'Recipes'; var $uses = array('recipe', 'User'); var $helpers = array('ajax'); var $components = array('email'); }
Kontroler (3) - dane $this->params['form'] $this->params['admin'] $this->params['bare'] $this->params['isajax'] $this->params['action'] $this->data
Kontroler(4) - metody set(string $var, mixed $value) render(string $action, string $layout, string $file) redirect(mixed $url, integer $status, boolean $exit) flash(string $message, string $url, integer $pause, string $layout) beforefilter() beforerender() afterfilter() string referer(mixed $default = null, boolean $local = false) loadmodel(string $modelclass, mixed $id)
Model(1) class Ingredient extends AppModel { } var $name = 'Ingredient'; class IngredientsController extends AppController { } function index() { $ingredients = $this->ingredent->find('all'); //$ingredients = $this->recipe->ingredient->find('all'); $this->set('ingredients', $ingredients); }
Model(2) find($type, $params) array( 'conditions' => array('model.field' => $thisvalue), 'recursive' => 1, //int 'fields' => array('model.field1', 'DISTINCT Model.field2'), 'order' => array('model.created', 'Model.field3 DESC'), 'group' => array('model.field'), 'limit' => n, //int 'page' => n, //int 'offset'=>n, //int 'callbacks' => true )
Model(3) zapisywanie danych W kontrolerze function edit($id) { if(!empty($this->data)) { if($this->recipe->save($this->data)) { $this->session->setflash("recipe Saved!"); $this->redirect('/recipes'); } } $this->data = $this->recipe->findbyid($id); }
Widok set() - analogiczna metoda jak dla kontrolera, umieszczenie zmiennej w viewvar (do wykorzystania dla elementów, które będą później renderowane, np. layoutu) getvar() - pobieranie zawartości zmiennej z viewvar error() - wyświetla błąd na stronie element() - wyświetla element, partial uuid() - generuje automatyczne ID dla danego elementu drzewa DOM
Nawigacja echo $html->link('view Post', array('controller' => 'posts', 'action' => 'index')) echo $this->html->link( ('TranslatedText', true), 'http://www.example.org')
I18n Internacjonalizacja strona w wielu językacj Wykorzystanie funkcji () w celu oznaczenia tekstu do tłumaczenia Stworzenie plików /app/locale/pol/lc_messages/default.po msgid token msgstr zamiennik Zmiana języków Configure::write('Config.language', 'pol'); // dla całej aplikacji $this->session->write('config.language', 'pol'); // dla użytkownika
Paginacja Kontroler var $paginate = array( 'limit' => 10); $data = $this->paginate('post'); $this->set('data', $data); Widok <?php echo $this->paginator->sort('title', 'title');?> <?php echo $this->paginator->numbers();?> <?php echo $this->paginator->prev('«previous', null, null, array('class' => 'disabled'));?> <?php echo $this->paginator->next('next»', null, null, array('class' => 'disabled'));?> <?php echo $this->paginator->counter();?>
Uwierzytelnianie var $components = array('auth', 'Session'); (AppController) Wykorzystanie ACO oraz ARO http://book.cakephp.org/view/1549/an- Automated-tool-for-creating- ACOs#!/view/1543/Simple-Acl-controlled- Application $this->session->read('auth.user')
Sesja - koszyk Utworzenie własnej klasy i umieszczenie jej w katalogu apps/vendors Przed wykorzystaniem import klasy dla danego kontrolera bądź dla całej aplikacji AppController w funkcji beforefilter() App::import('Vendor', 'Koszyk',array('file' => 'Koszyk.class.php')); Umieszczenie obiektu w sesji Pobranie obiektu z sesji $kosz = new Koszyk(); $this->session->write("koszyk.kosz",$kosz); <?php $kosz = $this->session->read("koszyk.kosz")?>
Sesja - koszyk <?php class Koszyk{ var $items = array(); public function drukuj(){ echo "Twój koszyk (".count($this->items).")";} public function pokaz(){foreach($this->items as $item){echo $item;}} public function add_to_cart($item){} public function rem_from_cart($item){} }?>
Flash Zmienne tymczasowe działające tylko w obrębie następnego żądania $this->session->setflash( ('Invalid post', true)) echo $this->session->flash('auth');
Pluginy www.cakedc.com komentarzy Wyszukiwania TinyMCE Tagi migracja