O MVC
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 zajmuje się ich wysyłaniem i obróbką. 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, nie tak dokładnie, bo przecież wybiera on odpowiednie zadania i sprawdza czasem kilka rzeczy, aczkolwiek nie powinniśmy generować jako tako treści przez controller a realizować to za pomocą widoku. 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.
Zacznijmy od tego, że to jest blog. Może jestem za mało “webdwazerowy”, ale nie podoba mi się, że na blogu jest zamieszczony artykuł. Tak, to jest artykuł. Bardzo nie podoba mi się idea umieszczania artykułów na blogu, bo to jest po prostu sprzeczne z ideą bloga. Na blogu wsyzstkie notki są umieszczone chronologicznie, ponieważ jest znaczenie, kiedy coś zostało napisane. Jest sensownym umieszczać na nim swoje przemyślenia, opinie, etc, głównie związane z jakimiś aktualnymi wydarzeniami, czy np. informować o np. postępie prac (b-log, tak jak change-log). Natomiast artykuły na blogu to IMHO bardzo źle trafiony pomysł.
Co do samego tekstu to mam dwie uwagi:
1. kod jest rozjechany (wcięcia), trzaby to wstawić w jakiś blok kodu.
2. Model nie tylko jest od pobierania danych (głównie z DB), ale ogólnie od *obróbki* tych danych, czyli też dodawanie, zmiana i usuwanie. Czasem też stosownym jest umieścić w modelu powtarzające się fragmenty kodu związane z jakimś zadaniem - nie można tego czasem umieścić w kontrolerze, bo jest to potrzebne z wielu podstron.
PS. Wybacz, że tak niespójnie to napisałem, ale już prawie śpię
Dzięki za poprawkę, i jak to zwykle bywa wiem, ale nie napiszę
Apropo artykułów na blogu, jest masa blogów z tutorialami, stwierdzam że raz na 6 miesięcy jeden tutek nikomu nie zawadzi…
A sam miałem zamiar coś na kształt artykułów we wpisach dodawać, akurat przyszedł Radex i powiedział swoje racje.
O przydatności artykułu mam mieszane uczucia - chociaż to kawał dobrej roboty, to sam mam inne pojęcie na temat tego, czym jest MVC. (Notabene MWL mi pierwszy o istnieniu czegoś takiego powiedział).
Swoją drogą może pomyślisz o plug-inie do WordPressa do kolorowania składni itp? Mam konkretnie na myśli http://wordpress.org/extend/plugins/syntaxhighlighter/
Nie używałem tego pluginu, być może to dobry pomysł. Jeśli chodzi o dodawanie artykułów na blogu to w ogóle nie zgadzam się z tezą radexa. Nasza praca jest częścią nas, nasz blog też, kiedy chcemy coś zademonstrować zróbmy to!