Napisałem sobie tutorial, dla trochę bardziej zaawansowanych w PHP o MVC. Mam zamiar zamieścić u siebie na blogu. Tym czasem idzie na TM.
MVC dla początkujących.
Tak, tak jest już bardzo dużo artykułów o tym jak działa model, widok i kontroler. Mimo to żaden z nich nie został dobrze zinterpretowany przeze mnie, i dopiero videocasty z zend framework uświadomiły mi jak to wszystko powinno wyglądać. Tak więc postanowiłem napisać własny, prosty i zrozumiały tutorial. A więc zaczynamy.
MVC, już zapewne słyszałeś o tym skrócie, oznacza on "Model View Controller" czyli nazwy warstw aplikacji.
Zakładamy że chcemy zrobić aplikację internetową, która będzie służyła do celów szpiegowania ludzi z naszego miasta. Tematyka nie typowa, ale może zainteresować. Podstawową funkcjonalnością naszej aplikacji będzie dodawanie danych na temat ludzi. Jak się teraz do tego zabrać? Najlepszym sposobem było by zaprojektowanie jakiegoś systemu który wywoływał by odpowiednie akcje (w naszym przypadku będzie to tylko dodawanie i wyszukiwanie ludzi). I tu najlepiej sprawdza się Model Widok i Kontroler, czyli filozofia separacji wywoływania zadań, pobierania danych i rysowania interfejsu.
Wytłumaczę na czym polega MVC w teorii.
Model - coś co zwraca nam potrzebne dane. I tak na przykład użyjemy modelu by wyszukać jakieś dane, czy dodać je do źródła danych.
Widok (View - V) - coś co rysuje nam interfejs, w naszym przypadku stronę.
Kontroler (Controller - C) - czyli to co zajmować się będzie tym by aplikacja działała jak trzeba.
Na początek stwórzmy plik index.php o takiej treści
<?php
// definujemy podstawową konfigurację
if(isset($_GET['module'])) $module = strtolower($_GET['module']).'Controller';
else $module = 'indexController';
if(isset($_GET['action'])) $action = strtolower($_GET['action']).'Action';
else $action = 'defaultAction';
if(!@include_once('classes/controllers/'.$module.'.php'))
{
// tutaj możesz zamieścić coś na wypadek nie odnalezienia strony
die('Nie odnaleziono strony.');
}
$controller = new $module;
if(method_exists($controller, $action)) $controller -> $action();
else die('Nie odnaleziono strony.');
?>
Mamy przygotowany plik, teraz czas na katalog z klasami. Utwórzmy sobie katalog classes a w nim podkatalogi controllers, models oraz views. W pierwszym z nich zamieszczać będziemy kontrolery które będą pobierały dane z modelu, formowały je odpowiednio i rysowały za pomocą widoków. Jeśli zinterpretujemy kod zrozumiemy że jego zadaniem jest po pierwsze załadowanie odpowiedniej klasy, a po drugie uruchomienie odpowiedniej funkcji (inaczej metody) z instancji naszej klasy jeśli oczywiście ona istnieje.
Zajmijmy się napisaniem naszego pierwszego kontrolera. Nazwijmy go indexController.php i zapiszmy w nim kod naszej nowej klasy. Będzie ona miała za zadanie narysować nagłówek strony, część główną i stopkę strony, oraz wywołanie takich metod z modelu których wymagać będzie nasza aplikacja. Zapiszemy więc taki kod:
<?php
// Tworzymy klasę kontrollera
class indexController
{
public function defaultAction()
{
include('classes/views/header.php');
echo '<h1>Witamy w szpegMachina 1.0</h1>';
echo '
<form action="?action=search" method="get">
<input type="text" name="name" /><br />
<button type="submit">Szukaj</button>
</form>';
include('classes/views/footer.php');
}
}
?>
Napisaliśmy nasz pierwszy kontroler. Ale czy na pewno poprawnie? NIE! Zadaniem kontrolera nie jest wypisywanie danych za pomocą echo tylko łączenie potrzebnych modeli z widokami. Nasz kod powinien więc wyglądać raczej tak:
<?php
// Tworzymy klasę kontrollera
class indexController
{
public function defaultAction()
{
include('classes/views/header.php');
include('classes/views/index/default.php');
include('classes/views/footer.php');
}
}
?>
Można sobie pomyśleć że nie ma to żadnego znaczenia, jednakże łatwo tu zauważyć po co nam w ogóle potrzebny MVC. Jeśli będziemy w jakikolwiek sposób chcieli zmodyfikować wygląd nie będziemy musieli babrać się w kontrolerze, a tym samym obawiać się że coś spieprzymy. Gotowe nasz pierwszy kontroler został zapisany, a w nim pierwsza jego akcja. Nie użyliśmy w nim modelu, jednak zrobiłem to celowo. Należy zapamiętać że model nie jest niezbędny do kontrolera, używa się go dopiero kiedy potrzebujemy zapisać czy pobrać jakieś dane. Dodamy teraz do naszego kodu metodę addAction, którą będziemy mogli uruchomić za pomocą odwołania get (?action=add).
<?php
...
public function addAction()
{
// klasycznie dodajemy nagłówek i stopkę
include('classes/views/header.php');
// jeśli wysłano dane będziemy je dodawać
if(!empty($_POST))
{
// sprawdzamy czy wszystkie dane są wprowadzone
if(!isset($_POST['name']) || !isset($_POST['desc']))
{
// jeśli jest nie tak jak trzeba wypiszemy informację o błędzie
include('classes/views/index/error.php');
}
else
{
// jest ok więc teraz czas na model
include('classes/models/spyModel.php');
// mamy już potrzebną nam klasę modelu, teraz instancja
$model = new spyModel();
$model -> add($_POST['name'], $_POST['desc']);
}
}
include('classes/views/footer.php');
}
...
?>
No i mamy gotowy kontroler z użytym modelem jeśli jest potrzebny. Czas więc zapisać model, którego użyliśmy.
<?php
class spyModel
{
public function add($name, $desc)
{
// na początek połączymy się z bazą danych
$connect = mysql_connect('localhost', 'root', 'pass');
// nie możemy zaomnieć o filtrowaniu danych
$name = mysql_real_escape_string($name);
$desc = mysql_real_escape_string($desc);
// teraz odpowiednie zapytanie
mysql_query('...');
// jeśli wystąpił błąd zwrcamy fałsz
if(@mysql_error()) return FALSE
else return TRUE;
}
}
?>
Zrobione. Teraz możemy odwołać się do tego modelu i użyć go w odpowiedniej sytuacji.
Tak właśnie działa MVC. Mamy podział i w dowolnym momencie możemy pozmieniać logikę aplikacji nie psując przy tym innych modułów. Dzięki temu możemy łatwo zarządzać naszą aplikacją. Zastosowany przeze mnie Model Widok Kontroler to najprostsze możliwe rozwiązanie tego wzorca projektowego. Do swoich rozwiązań można oczywiście dodać o wiele bardziej skomplikowane mechanizmy, udostępnić rodziców klasą, tak żeby zbierały różnorakie informacje itd.
Mam nadzieję że mój artykuł był prosty i zrozumiały, a także to że nie będziesz miał już więcej problemów ze zrozumieniem wzorca.