Robert.BrainUsers.net

CakePHP i własna strona - wprowadzenie

Główna zaleta frameworka CakePHP to szybkość tworzenia internetowych aplikacji z wykorzystaniem MVC i CRUD oraz doskonała dokumentacja. Prosta strona napisana za pomocą Cake'a to poświęcenie nie więcej niż 30 minut. Aby zaprezentować podstawowe możliwości tego narzędzia napisałem krótkie wprowadzenie.

Artykuł pokazuje jak napisać prostą stronę za pomocą CakePHP 2. Jeśli jakiekolwiek informacje zawarte w tym artykule okażą się niejasne - odsyłam do wyśmienitego podręcznika oraz szczegółowego API projektu.

Instalacja krok po kroku

Wymagania:

  • serwer HTTP,
  • PHP >= 5.2.8 z obsługą PDO,
  • relacyjna baza danych (można i bez, ale co to za frajda?).

Zakładam że mamy najpopularniejszą konfigurację tzn. Apache z mod_rewrite i bazę MySQL. Dobrze też, jeśli PHP będzie wyświetlał wszystkie błędy (opcja error_reporting) - również NOTICE, STRICT i DEPRECATED. Pomimo tego, że PHP pozwala na wiele i ignoruje błędy typu brak zmiennej/klucza w tablicy, to potem bardzo ciężko dojść dlaczego aplikacja nie zachowuje się tak jak powinna. Mocno zalecam wyświetlanie wszystkich błędów i uwag interpretatora PHP.

CakePHP jest na jednej z najbardziej liberalnych licencji, X11 (inaczej MIT): kod można używać, przekształcać, rozpowszechniać i sprzedawać z zachowaniem licencji i informacji o autorze. W praktyce nie sprzedaje się kodu frameworka a jedynie napisany przez siebie kod aplikacji oraz schemat bazy danych.

Pobierzmy paczkę z Cake'iem z oficjalnej strony i rozpakujmy. Należy nadać uprawnienia do zapisu dla całego folderu app/tmp (rekursywnie):

chmod a+rw app/tmp -R

Dla wersji deweloperskiej DocumentRoot Apacha można ustawić na folder główny Cake'a, ale w wersji produkcyjnej (żywy serwis) DocumentRoot powinien wskazywać folder app/webroot.

Konfiguracja

Spróbujmy wywołać teraz naszą przyszłą stronę w przeglądarce (np. http://localhost/ albo http://twoja-domena/). Naszym oczom ukaże się strona testowa, która poinformuje nas jakie jeszcze kroki powinniśmy poczynić. Jeśli nie nadaliśmy uprawnień zapisu dla folderu app/tmp, na tej stronie pojawi się taka informacja. Ważną sprawą jest zmiana soli i ziaren, które są używane do celów bezpieczeństwa (szyfrowanie, hashowanie, generowanie losowych ciągów). Zmian dokonujemy w pliku app/Config/core.php, który zawiera główne ustawienia aplikacji.

/**
* A random string used in security hashing methods.
 */
Configure::write('Security.salt', 'blabla_losowy_ciag_znakow_72727272727272727272');

/**
* A random numeric string (digits only) used to encrypt/decrypt strings.
*/
Configure::write('Security.cipherSeed', '5634791694172984723057820357893649');

Druga sprawa to połączenie z bazą danych. Zakładam, że posiadamy na localhoście, na standardowym porcie bazę MySQL o nazwie cake_tutorial z użytkownikiem cake_www i hasłem admin1. ;) Musimy zmienić nazwę pliku app/Config/database.php.default na database.php i zmienić odpowiednie klucze w tablicy przechowującej informacje o połączeniu.

public $default = array(
   'datasource' => 'Database/Mysql',
   'persistent' => false,
   'host' => 'localhost',
   'login' => 'cake_www',
   'password' => 'admin1',
   'database' => 'cake_tutorial',
   'prefix' => '',
   'encoding' => 'utf8',
);

Oczywiście kodowanie znaków dla całej aplikacji to UTF-8 (choć można je zmienić). Szczegółowa konfiguracja opisana jest w manualu.

Mapowanie obiektowo-relacyjne (ORM)

Stwórzmy w bazie danych tabelę z artykułami:

CREATE TABLE articles (
   id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
   title VARCHAR(255),
   body TEXT,
   created DATETIME DEFAULT NULL,
   modified DATETIME DEFAULT NULL
);

CakePHP posiada szereg konwencji nazewniczych, zgodnie z którymi nazwa tabeli powinna być angielskojęzycznym rzeczownikiem w liczbie mnogiej pisanym małymi literami. Sama tabela powinna posiadać kolumnę id, która jest samoinkrementującym się kluczem głównym przechowującym liczby naturalne (dodatnie integery zwiększają zakres). Dodajmy, że kolumny created i modified zawierające odpowiednio czas powstania i ostatniej edycji rekordu będą automatycznie uzupełniane przez framework.

Możemy teraz utworzyć model, czyli odwzorowanie tabeli w systemie bazy danych za pomocą klasy PHP dziedziczącej po klasie AppModel. Stwórzmy plik app/Model/Article.php:

class Article extends AppModel {
}

Według Cake'owych konwencji, klasa naszego modelu posiada nazwę rozpoczynającą się od wielkiej litery, która jest rzeczownikiem w liczbie pojedynczej. Plik z klasą nazywa się tak samo jak klasa (Article.php) - proszę zwrócić uwagę na wielkie i małe litery, to bardzo ważne w systemach uniksopodobnych. Cake sam przetłumaczy nazwę modelu na nazwę tabeli w liczbie mnogiej. Czy to nie magia?

Za pomocą obiektu klasy Article będziemy wykonywali wszystkie operacje CRUD: pobieranie rekordów z tabeli articles, dodawanie nowych, edycja oraz usuwanie istniejących. Możliwa jest szczegółowa konfiguracja modelu, definiowanie relacji między modelami, określanie reguł walidacji danych a nawet odejście od niektórych konwencji. Dodatkowo możemy zdefiniować wyzwalacze dla wszystkich akcji CRUD (i nie tylko) na poziomie aplikacji PHP jako metody klasy modelu. I wiele, wiele więcej...

Kontroler czyli logika aplikacji

Żeby nasza strona cokolwiek robiła, potrzeba zaprogramować jej logikę, czyli algorytm obsługujący pewne procesy, które najczęściej korzystają danych zgromadzonych w bazie. Konwencją frameworka jest, że dla każdego modelu tworzymy kontroler, czyli klasę dziedziczącą po AppController, która obsługuje wszystkie procesy wykorzystujące główne dany model. Pojedynczy proces nazywamy akcją i jest reprezentowany przez publiczną metodę klasy kontrolera.

W naszym tutorialu mamy już jeden model: Article. Napiszmy zatem kontroler, który obsłuży podstawowe akcje (CRUD) modelu. Stwórzmy plik app/Controller/ArticlesController.php.

class ArticlesController extends AppController {
   public function index() {}
   public function view($id) {}
   public function edit($id = null) {}
   public function delete() {}
}

Klasa kontrolera powinna być rzeczownikiem w liczbie mnogiej wskazującym na powiązany model (+Controller). Cake znowu sam powiąże kontroler z odpowiednim modelem, jeśli taki istnieje. W przykładzie utworzyłem trzy akcje:

  • index - wyświetlanie artykułów,
  • edit - dodawanie i edycja, w zależności od argumentu $id (Create i Update z CRUD),
  • delete - usuwanie rekordu, dla bezpieczeństwa parametr będzie wysyłany metodą POST (Delete z CRUD),
  • view - wyświetlenie wybranego artykułu, którego $id podano w argumencie (Read z CRUD).

Implementacją wszystkich metod zajmiemy się później.

Jak widać, kontroler jest najważniejszym elementem aplikacji. Szerzej na ten temat poczytamy w manualu Cake'a.

Warstwa prezentacji w Widoku

Programując aplikacje internetowe nie unikniemy rozważań na temat architektury i inżynierii oprogramowania. CakePHP narzuca nam wzorzec architektury MVC, który charakteryzuje się podziałem aplikacji na trzy hermetyzowane warstwy: model mapujący tabelę bazy danych, kontroler implementujący logikę dla modelu oraz widok. W ogóle wzorzec MVC dla aplikacji WWW to dość kontrowersyjny temat.

Widok w skrócie jest warstwą, która odpowiada za prezentację danych dostarczanych przez kontroler. Ale wygenerowany dokument HTML wraz z przeglądarką odpowiada za komunikację w odwrotnym kierunku: od użytkownika do aplikacji (za pomocą żądań HTTP) a cała komunikacja powiązana jest sesją na podstawie ciasteczka z identyfikatorem sesji. Miejmy jednak na uwadze, że widok może wyświetlać dane nie tylko w formacie HTML.

Widok należy do konkretnej akcji kontrolera i musi nazywać się tak samo jak akcja. Np. widok dla akcji ArticlesController::index() będzie umieszczony w app/View/Articles/index.ctp. W widoku umieszczamy kod PHP, który wyświetli dane z kontrolera, lecz zwyczajowo plik ma rozszerzenie ctp.

Widok odpowiada za prezentację pojedynczej akcji, więc potrzebujemy mechanizmu do uniknięcia powtarzania większości kodu odpowiedzialnego za stałe elementy strony. Takim mechanizmem jest layout, czyli widok nadrzędny dla wszystkich widoków. Domyślny layout definiujemy w pliku app/View/Layouts/default.ctp, a różne layouty przełączamy odpowiednimi właściwościami kontrolera. To, co zostanie wyświetlone w widoku, CakePHP przechwyci do zmiennej $content_for_layout.

<html>
   <head>
       <title>Moja strona</title>
   </head>
   <body>
      <div id="top"><h1>Tytuł</h1></div>
      <div id="content"><?php echo $content_for_layout; ?></div>
   </body>
</html>

Komentarze

vito
Witam,
Dzięki za tutek wprowadzający do CakePHP, chyba jako jedyny obecnie dostępny po Polsku i opisany ładnie krok po kroku. Z niecierpliwością czekam na kolejne części.
pozdrawiam
Dziękuję, w końcu jakaś odezwa ze strony wszechświata. :) Na pewno zachęci mnie to do napisania części 2.
Niestety czytania angielskiej dokumentacji nie da się pominąć, bo żaden tutorial nie będzie tak szczegółowy jak świetny podręcznik do CakePHP: http://book.cakephp.org
hugy
potwierdzam że wpisy są czytane ;)
poza ogólnym brakiem tutoriali dochodzi do tego szybkie starzenie się wpisów - tym cenniejsze jest znalezienie tego opartego na najnowszych wersjach - oby więcej części
skurc
Tak, czekamy na następne wpisy. Może później coś o helperach? Pozdrawiam :)
blk
No i kurczaki się nie doczekam tej drugiej części? ;)
cake_user
Robert, dzięki za część I, czekamy dalej na II... :)
NibyJa
No i gdzie ta II część?
Marcin Białasek
Fajny tutorial, mam nadzieję, że powstanie część II, III i jeszcze wiele kolejnych, bo w cakephp pisze się naprawdę łatwo. lekko i przyjemnie.
Nowicjusz
Widze ze sporo ludzi czeka ja również a tymczasem sięgam do Angielszczyzny :)
PS. Czekam na kolejne części
Czekający
Wciąż czekamy :)
DB
Fajneee :)
Srebrny
Ja również czekam na ciąg dalszy :-)
nath
Będzie ta druga część czy nie? :< Mam nadzieję, że tak ;)
projektowanie stron
dobry tutorial. czekam na ciąg dalszy
zniecierpliwiony
I gdzie ta 2 część i 2 i 4 i 5 ............
:D
Krawaty
Mam zadanie napisać stronę producent krawatów w jakimś frameworku, wybrałem Cake i dlatego trafiłem na ten blog. Szkoda ze autor poprzestał na części pierwszej, ale dobre i to, nie zniechęci mnie to do napisania strony o krawatach.

Dodaj komentarz