Wzorzec MVC w PHP

Prędzej czy później, podczas przygody z programowaniem stron WWW natkniemy się na hasło MVC. Co to znaczy, o co chodzi? Odpowiedzmy sobie na te i kilka innych pytań na podstawie PHP.

MVC to nic innego, jak skrót od Model View Controller. Jest to wzorzec projektowy (a więc zbiór pewnych reguł, według których budowane są aplikacje na całym świecie), który cieszy się bardzo dużą popularnością wśród webdeveloperów.

Nie wiem, jak dotąd projektowałeś swoje aplikacje PHP. Jeśli robiłeś to strukturalnie, w oparciu o funkcje, ten artykuł raczej nie jest dla Ciebie – co prawda można użyć MVC w podejściu strukturalnym, byłaby to jednak w pewnym sensie kpina ze sztuki. Kod strukturalny w PHP jest, może już to gdzieś słyszałeś, niczym źle przyrządzone spaghetti – wygląda, jak nie wiadomo co i w dodatku ucieka z talerza.

Jeśli z kolei znasz i wiesz na czym polega programowanie obiektowe, mamy o czym ze sobą rozmawiać. Zacznijmy od teorii.

Z reguły proste aplikacje w PHP wyglądają tak, że sprawdzany jest adres wpisany do przeglądarki (na podstawie $_GET, bądź innych właściwości z $_SERVER), potem includowane są potrzebne pliki w zależności od pozyskanych danych. Absolutne podstawy podstaw.

Stosując MVC nie możemy opierać się, jak to zwykle bywa w tradycyjnym podejściu, tylko na jednym pliku, np. index.php, w którym mieszamy kod prezentacji (np. HTML) i logikę biznesową (dane np. z MySQL).

Działa to zupełnie inaczej, a mianowicie mamy 3 główne elementy aplikacji, gdzie każda odpowiedzialna jest tylko za jedną rzecz. Są nimi:

I tak, dobrą praktyką jest umieszczanie kontrolerów w folderze np. /controllers, widoków w /views, a modeli w /models. W ten sposób mamy jasny i prosty podział naszej aplikacji.

Jeśli więc uruchomimy przykładowo stronę index.php?controller=news&param=55, według MVC powinny dziać się następujące rzeczy:

Od strony kodu, przykładowe wywołanie MVC wygląda następująco:


//index.php

$controller = Router::getController();
$controller = new $controller;
$action = Router::getAction();

$controller->$action(Router::getParams());
//controllers/news.php

class news_Controller extends Controller
{
	public function index($params)
	{
		$model = Router::getModel(); // // pobierze Model
		$model = new $model;

		$view = Router::getView(); // pobierze Widok
		$view = new $view; 

		$data = $model->getData($params); // pobiera dane z Modelu
		$view->setData($data); // przekazuje dane do Widoku, by ten mógł je wyświetlić
		$view->Render(); // wyświetli stronę
	}
}

Zalety MVC:

Artykuł ten to tylko zalążek tego, co można by powiedzieć o MVC. Postanowiłem przedstawić temat powierzchownie, ale na tyle wystarczająco, aby można było łatwo dowiedzieć się, z czym to, przysłowiowo, się je.

Kto wie, jeśli zainteresowanie tematem będzie duże, spróbuję rozbudować materiał, tworząc tutorial, jak zbudować framework oparty o MVC. Decyzja należy do Was.

Komentarze

1

No w końcu ktoś pisze o MVC po ludzku, a nie w języku programistów :D Czekam na dalsze artykuły o MVC :D Proponuje opisać MVC na bazie jakieś gotowej aplikacji, którą tworzyłeś (może być też jakaś wyimaginowana) :D

2

Warto także wspomnieć o frameworkach korzystających z tego wzorca. Są to m.in. CodeIgniter i Kohana.

Po wczytaniu się w ich dokumentację (i zbudowanie nawet prostej aplikacji) wzorzec ten stanie się jeszcze łatwiejszy do przyswojenia ;)

3

Wzorzec niemalże obowiązkowy w kazdej rozbudowenej i dobrze napisanej aplikacji.
Ja także go dobrze poznałem dopiero przy okazji pracy z fw, ale… daawno temu, nie wiedząc nawet o istnieniu MVC, napisałem silniczek, który w dużej mierze oddawał zasady działania tego wzorca. Nic by w tym nie było dziwnego, gdyby nie to że wszystko własnie strukturalnie :) Dziś oczywiście nie pokusiłbym się o takie ekstrawagancje, ale ten kod do dziś wydaje mi się całkiem użyteczny. Nawet jeden sklepik internetowy na nim do dziś stoi :)

wzs
4

webdevil: Kohana to moim zdaniem strzal w 10 – lekki i latwy do nauczenia. Zreszta bazuje na CI wlasnie.

5

Co do Kohany, to faktycznie jest genialna, ale ma jedną zasadniczą wadę: wciąż jest w fazie tworzenia, przez co z wersji na wersję zachodzą zmiany uniemożliwiające prace nad większym projektem (vide zapowiadane rewolucje w wersji 2.3). Ale do nauki w sam raz :)

mck
6

Ja dzisiaj – nie wyobrażam sobie tworzenia stron internetowych inaczej. Osobiście jednak – nie pisałem nigdy własnego Frameworka – raz tylko pomagałem koledze, gdyż uważam, że pisanie własnego MVC to wynajdywanie koła na nowo. O Kohana nigdy nie słyszałem. Osobiście zaczynałem od CodeIgniter i jest to prosty framework. Jego zaletą, która jest ważana dla początkujących, jest fakt iż posiada dobrą dokumentację i można naprawdę szybko połapać się co gdzie jest. Na kolejny ogień poszedł CakePHP. Tam dowiedziałem się co to jest scaffolding. Z cech, które przemawiają za CakePHP moim zdaniem jest na pewno obsługa drzew i ACL, których nie spotkałem w żadnym innym frameworku. Szczególnie widać to w wersji 1.2, w której pojawiło się wsparcie dla internacjonalizacji. Szalenie również podoba mi się mechanizm “elements”, który moim zdaniem bardzo ułatwia tworzenie szablonów, z różnych powtarzalnych komponentów, pod, które możemy podkładać różne dane, co szalenie skraca pracę w tworzeniu szablonów. CakePHP posiada w najnowszej wersji mnóstwo innych bibliotek i wygląda mi na to, że obecnie jest to najlepszy framework. Obecnie tworzę projekt z użycie Symfony. CakePHP w wersji 1.2 na pewno chciał doścignąć Symfony. Moim skromnym zdaniem – przypadkiem go prześcignął. Co o symfony. Posiada mnóstwo pluginów i dużą społeczność. Używa Propel, modele są więc generowane i dostępne ad-hoc – bez pisania jakiegokolwiek kodu. Dzięki użycia Propel modele generowane są w bardzo inteligentny sposób. Na koniec – bez pisania nawet połowy linijki kodu – dostajemy gotowe klasy w PHP, które obsługują między innymi CRUD oraz posiadają metody automatycznie pobierające dane z innych tabel używając złączeń. Dodatkowo są one szalenie elastyczne. Kolejna rzecz to scaffolding, który jest naprawdę piekielnie użyteczny i pozwala w 1 minutę (naprawdę właśnie w tyle) stworzyć funkcjonalny panel administratora do prostej aplikacji. W moim przypadku problemem okazało się korzystanie z dokumentacji, która z racji niekompletności, rozstrzelenia oraz braku opisania każdego modułu od A do Z (istnieje tylko kompletny opis API) i z tej przyczyn prawdopodobnie do czasu aż to się nie zmieni – będę korzystał z innych frameworków. Na obronę powiem tylko, że dokumentacji, która istnieje obecnie jest dużo, nie można narzekać na jej brak czy na nie opisanie jakiś komponentów. Projekt jest jednak tak kolosalny, że stworzenie do niego dobrej dokumentacji to nie lada wyzwanie. Na razie, w moim mniemaniu jeszcze nie udało się temu wyzwaniu sprostać. Innym ciekawym moim zdaniem framerowkiem jest Akelos, który jak możemy wycztać na stronie internetowej, jest portem Ruby On Rails napisanym w PHP.

Tyle z moich doświadczeń. Może okażą się dla kogoś pomocne w dalszej przygodzie z MVC. Mam nadzieję, że nie będzie niegrzecznością jeżeli polecę swój artykuł, w którym również swojego czasu opisałem MVC. Jeżeli jest inaczej – poproszę tylko o usunięciu przez autora bloga linku do tego wpisu. Swoją drogą – świetny blog :]

7

Kohana jest ciekawa, ma duże możliwości ale obecnie nie nadaje się do pracy nad poważnymi projektami, vide wywalenie forge w wersji 2.2. Obecnie zachwycam się Zend Framework i jestem pod wielkim wrażeniem. Dokumentacja jest doskonała a Webinar’s pokazuja w rpzystępny sposob jak korzystać z Frameworka na podstawie tak zwanych “best practices”

Oczywiście jest bardzo ciekaw artykułu o stworzenia własnego Frameworka. Kiedyś na potrzeby małego pojektu taki sam napisałem, ale obecnie korzystam z ZF i chętnie się poducze :)

8

A widział ktoś framework dostępny publicznie, który nie korzysta z MVC? Chciałbym zobaczyć jak takie dziwadło by wyglądało…

Osobiście używam Zend Framework. Może nie jest tak łatwy jak Symfony (wcześniej trzeba sobie przygotować wszystkie klasy, samemu je wczytać i wybrać komponenty, z których będzie się korzystało), jednak daje dużo większą władzę nad kodem. Wymiana jednego elementu (np. zastosowanie innego silnika szablonów) jest całkowicie banalną sprawą.

Swoją drogą, CI to w dzisiejszych czasach staroć, dobrze że powstaje Kohana. Swojego czasu bazując na CI, CakePHP napisałem framework z użyciem Propela. Naprawdę wygodnie się tego używało (ale nie tak jak ZF ;)).

A co do samego MVC – wzorzec naprawdę świetny. Od kiedy zacząłem go używać pisanie aplikacji stało się przyjemnością.

Albi
9

@Albi:
Istnieje taka architektura jak REST i z wielu przesłanek wynika, ze istnieje Ona w Ruby On Rails [tu] oraz w CakePHP [tu].

10

W internecie jest bardzo mało informacji o tworzeniu własnego frameworka MVC od zera, więc myślę, że taki artykuł byłby trafną decyzją. Na pewno wiele osób, które nie chcą od razu używać gotowych (często rozbudowanych) rozwiązań, skorzystało by z niego. Podstawy rzeczowo i zrozumiale wytłumaczyłeś, więc już zachęciłeś mnie do samodzielnych ekspertymentów.

Bywalec
11

Bardzo dobry tekst, oczywiscie czekam na tutoriala jak zbudowac framework oparty o mvc. Pozdrawiam :)

eprom
12

Jeśli chodzi o budowę własnego frameworka to sprawa wcale nie jest taka prosta, jakby mogło się wydawać. Na własne potrzeby można stworzyć prosty szkielet, który będzie używał MVC, systemu szablonów czy warstwy abstrakcji dla bazy danych. Podstawowym argumentem przemawiającym na korzyść frameworka to jego lekkość oraz idealne dopasowanie do naszych potrzeb. Jednak rozwiązania takie jak Zend są bardziej elastyczne i uniwersalne, oczywiście kosztem złożoności samego frameworka i jego ostatecznej wydajności.

Podczas wyboru frameworka dla danego projektu powinniśmy się kierować zarówno złożonością aplikacji, możliwościami rozwoju i wsparcia, ale także zasadnością użycia w konkretnym przypadku.

13

Ja polecam Zend Framework, projekt dynamicznie się rozwija, posiada dość duże grono developerów skupionych wokół projektu.

14

Frameworków jest sporo, to fakt, ale dobrych CRUD-ów jak na lekarstwo :(.

qwertyuiop
15

A niby dlaczego nie jest to wpis dla tych od kodu strukturalnego, może to wreszcie by zachęciło ich do przejścia na pisanie “obiektowe” w php, i wreszcie kod źródłowy ich serwisów wyglądałby normalnie a nie pomieszanie z poplątaniem.

Co do wpisu, przykładowe kody zalatują mi Zend_Frameworkiem, co w sumie jest na plus bo biblioteki sprawują się całkiem fajnie.

Warto też dodać, że trudno przejść na programowanie w Konwencji MVC, a to dlatego, że wciąż część operacji na danych wykonujemy w kontrolerach, a Modele często są traktowane jako obiekty dostępu do bazy danych (co jest podejściem błędnym).

16

A ja byłbym za tym, żeby napisać coś o własnym frameworku, na razie sam nieraz próbuję coś sklecić, a php dopiero się uczę i jestem zdania, że przez każdy przykład mogę nauczyć się coś nowego, zauważyć coś, czego sam bym nie wymyślił :) Dlatego, jeżeli decyzja należy do czytelników, to ja jestem za ;) [powtarzam się xD]

TheCube
17

A co sądzicie o Prado? nie jest to wzorzec MVC ale wzorowany na asp.net programowanie oparte na zdarzeniach no i bardzo prosto się pisze.

pablosan
18

Prado super! Używam często, programowanie oparte o komponenty i zdarzenia, naprawdę ciekawe podejście do programowania w PHP.

Poprosimy więcej artykułów o MVC :)

dd
19

Bardzo proszę o jakieś tutoriale systemów czy aplikacji dotyczących objektowego php z wykorzystaniem bazy mysql i modelu MVC.
Tylko tego mi tutaj brakuje.
Pozdro. Dobra robota.

fifi
20

Zerknijcie jeszcze na silverstripe.org.

przemio
21

Ja również chętnie przeczytałbym taki tutorial. Moim zdaniem świetnie piszesz i ktoś kto jest początkujący(tak jak ja) naprawdę może skorzystać wiele. Kawał świetnej roboty:)
pozdrawiam.

Krzysztof
22

Spoko artykuł, gratuluję. W zalewie nudnego BLA BLA BLA w sieci, twój czyta się wyjątkowo przyjemnie. Zabrakło przykładowego kodu do wykorzystania w praktyce, rozwiązanie $model = new $model; mi się nie podoba, ale generalnie wielki plus.

Croc
23

w 7 linijce wkradła się mały blond..

lol
24

Pierwszy w polskim internecie artykuł o MVC który zrozumiałem od razu… Bardzo przyjemnie się czyta.
Zdaję sobie sprawę, że propozycja padła dawno temu ale naprawdę byłoby miło poczytać więcej na ten temat…

ooo_michal
25

Ja mogę polecić Zend Framework. Pomimo tego, iż jest bardzo rozbudowany, po spędzeniu nad nim kilku dni, można już zacząć kumać co i jak:)

Przed Zendem przerabiałem Kohana. Bardzo fajny lekko framework lecz cały czas dynamicznie rozwijany.

26

Ja zastanawiam się od jakiego frameworka najlepiej zacząć.
Chyba wybór padnie na Zend Framework, w dużym stopniu przeważa to, że np. Facebook jest napisany przy pomocy Zend’a [potrzebne źródło]. ;]

test30
27

Troche jakby malo o tym MVC ;P Zero przykladow, nie napisane czym w praktyce rozni sie kontroler od modelu

28

Artykuł super i z niecierpliwością czekam na kolejną część o budowie własnego frameworka. Właśnie jestem na etapie pisanie projektu ,a właściwie aplikacji w php do wizualizacji systemu zasilania awaryjnego. Wymagania są takie, że serwer ma śmigać na jak najsłabszym sprzęcie. Zacząłem coś tworzyć samemu ale nie do końca wygląda to dobrze, raczej jak to spaghetti w artykule. Przydał by mi się bardzo lekki framework. Co polecacie do takiego prokektu?

maroo
29

Zdaje się, że autor nie zamierza napisać dalszej części o MVC a szkoda

ben
30

w końcu! pokazane czysto i przejrzyście jak działa MVC w praktyce, może autor jednak pokusi się o kolejną “część”, myślę, że wielu by to pomogło, pozdrawiam ;)

smiechowy
31

Świetne wprowadzenie! Na prawdę wielkie dzięki :) Czekam z niecierpliwością na ciąg dalszy.

32

Ciekawy art.
Mam jednak jedno ale. To co przedstawiłeś w kontrolerze to raczej implementacja MVP a niżeli MVC.
W MVC to widok pobiera dane z modelu, a nie tak jak to pokazałeś kontroler, który potem dane przekazuje do widoku. Według mnie kontroler wykonuje akcje. Pobiera obiekt modelu i przekazuje go wybranemu widokowi. Ten pobiera z modelu dane i je wyświetla.
To oczywiście mój punkt widzenia, a jak już gdzieś usłyszałem:
“ilu programistów tyle implementacji tego wzorca” :)
Pozdrawiam.

ChemikPIL
33

Dzięki wielkie za to wprowadzenie. Bardzo dobrze napisane, chętnie poczytał bym więcej o MVC tekstów na tej stronie ;)

spaw
34

statyczne wywołanie typu: $controller = Router::getController(); średnio mi się podoba. Rozumiem, że zasada abstrakcji wzięła górę nad bezpieczeństwem. Brakuję minimalnej wzmianki o obsłudze błędów (braki w źródle)

@Chemik
zgadzam się, kontroler nie musi “zaglądać do modelu” czy w jakikolwiek sposób operwać na danych modelu.

//$data = $model->getData($params); zbędne!
$view->setData($model); // wystarczy
$view->render();

ad4s
35

Witam, czytam Twoje artykuły i bardzo mi się podobają, fajnie że piszesz o MVC, chciałbym się zapytać czy nie masz może jakiejś prostego przykładu (tutorialu) ? A jak wiadomo najlepiej się uczy na przykładach, oczywiście są gotowce ale z nich coś wywnioskować to niekiedy masakra:)
Pozdrawiam marcin.

marcinsm
36

Witam, w którym z trzech elementów aplikacji MVC następuje np. walidacja danych wprowadzanych przez użytkownika. Z powyższego art wynika że za tą czynność odpowiada model. ale pewności nie mam.

Kriss
37

No super … a jak z MVC pogodzić Ajaxa?

Dabidi
38

@Kriss: Model. Dobra zasada przy MVC (MVP) to Skinny Controller, Fat Model.
@Dabidi: Zmień Widok.

39

Witam,

Kod kontrolera pisze się samemu? Czy korzysta się z gotowego pliku?

Adam
40

Nie umiem wyświetlać np. danych z bazy danych w widoku :/ Ma ktoś jakiś pomysł jak przesłać dane z Model do View?

Michal
41

niewazne :D

Michal
42

Tak, zrób takie coś .

43

i jak? buja się ten temat dalej czy nie?

44

Prosimy o rozwinięcie :)

tomek
45

Czy istnieje jakiś framework do tworzenia aplikacji w PHP, jak np. Spring w Javie?

46

Każdy z nas zetknął się z tematem, rekomenduję zapoznanie się z
materiałem.