Front Controller – co to jest, po co to jest oraz przykładowa implementacja. Część 1.
Jeszcze nie tak bardzo dawno temu sam zadawałem sobie to pytanie. Ciężko było znaleźć odpowiedź. Mało która książka o PHP mówi coś o Front Controllerze. Przyznam się szczerze że booki nie okazały się w tym przypadku pomocne. Sieć okazała się w tym wypadku również mało przydatna. Być może źle szukałem ale googlując za front controllerem natrafiłem na szczątkowe informacje.
Polecam te linki osobą które jeszcze nie wiedzą nic na temat wzorca projektowego “Front Controller” (nie mówiłem że to wzorzec projektowy? Coż… to wzorzec projektowy). Jednak materiały te nie za wiele mówią nt. samej implementacji.
Jak można wyczytać w w/w materiałach front controllerem można nazwać nawet takich kawałek kodu:
$page = $_GET['page'];
swith($page) {
case 'home':
include_once('index.php');
break;
case 'galeria':
include_once('galleria.php');
break;
case 'onas':
include_once('onas.php');
break;
}
Nie trzeba chyba tłumaczyć nikomu że taki mechanizm to żadna Ameryka, to coś co większość z nas robiła na początku przygód z programowaniem w PHP (a jeżeli robi tak dalej to na pewno powinna czytać dalej).
Więc co to jest tak naprawde ten front controller? Może wypiszę w liście co tak naprawdę robi dla nas front controller:
- Jest miejscem przez które przechodzą wszystkie zapytania do naszej aplikacji.
- Możemy w nim wykonywać działania które są wspólne dla wszystkich stron aplikacji (np. autoryzacja, zainicjalizowanie logera itd, zaincludowanie odpowiednich bibliotek).
- Przekierowuje “dalej” zapytanie, do odpowiedniego pliku/klasy/funkcji według parametrów podanych w URL i odpowiedniej strategi którą obmyśliliśmy i zaimplementowaliśmy w naszej klasie front control
Przykładowy plik index.php który implementuje (wykorzystuję) front controller może wyglądać tak:
< ?php
// wlaczenie raportowania bledow
ini_set('display_errors','on');
ini_set('html_errors','on');
//error_reporting(E_ALL);
require_once ('./config/config.php'); // ustawianie include_path
ini_set ('include_path', ini_get('include_path').PATH_SEPARATOR.ROOT_DIR.'/library'.PATH_SEPARATOR.ROOT_DIR.'/models'); // ladowanie klas
require_once('FrontController.php');
require_once('Smarty.php');
require_once('Authorize.php'); // ustawiamy smarty
$smarty = new Smarty();
$smarty->compile_dir = ROOT_DIR.'/appshop/views/compile';
$smarty->template_dir = ROOT_DIR.'/appshop/views';
Zend::register('smarty',$smarty); // autoryzacja
$authorize = new Authorize();
if (!$authorize->authorize()) {
Zend_Log::log('użytkownik niezalogowany, przekierowanie do logowania');
$_GET['controller'] = 'index';
$_GET['action'] = 'index';
} else {
Zend_Log::log('użytkownik zalogowany');
} // front controller (proces dispatch).
try {
$controller = new FrontController(ROOT_DIR.'/appshop/controllers/');
$controller->dispatch();
} catch (Exception $e) {
echo $e->getMessage();
}
?>
Przeanalizuj powyższy kod. Tak wiem, może wydawać się trochę dziwne, ale już tłumacze co i jak. Wpierw wykonujemy działania wspólne dla całej aplikacji, grzebiemy trochę w ustawieniach serwera zmieniając wartości w php.ini w czasie “run time”, tworzymy i ustawiamy obiekt smarty, przeprowadzamy autoryzacje użytkownika, widzimy też parę wywołań logera (dla czytelności kodu nie będę wnikał w inicjalizację i szczegóły klasy Zend_Log).
Dopiero na końcu, w bloku try… catch dzieje się magia. Używamy naszej klasy FrontController dla procesu dispatchowania (przepraszam za takie chamskie spolszczenie), czyli wywołania odpowiedniego miejsca naszej aplikacji. Klasa FrontController użyta tutaj pobiera z tablicy GET dwa parametry: controller i action. Controller to nazwa klasy, a action to nazwa metody która kontroler ma wywołać. Używając przy tym pomocy mod_rewrite tworzymy te tzw SEO linki, czyli podając URL np. strona.pl/news/archiwum wywołujemy controller news, action archiwum (wszystko jasne i czytelne). To jest jedna z możliwych strategi dispaczowania, mogę istnieć oczywiście inne np. dwa parametry get, pierwszy to nazwa pliku który wywołujemy a drugi to parametr dla jakieś instrukcji swith, która wie co robić dalej. Ale to zagadnienie wychodzące trochę poza Front Controller a wchodzące na wzorzec projektowy MVC.
Dzięki temu wszystkiemu, my mamy scentralizowaną w jednym miejscu nad praktycznie każdym zapytaniem do naszej aplikacji (można np. w łatwy sposób rejestrować w tym miejscu adresy IP hostów itd.) i zautomatyzowany, dzięki klasie FrontController dostęp do całego serwisu. Nie będziemy już musieli więcej dopisywać kolejnych ifów jeżeli w serwisie pojawi się nowa strona. Kierując się paroma zasadami które ustawimy przy inicjalizacji FrontControllera (obiektu klasy Front Controller) możemy sobie zapewnić spokojny sen i mieć pewność że jeżeli dany plik/klasa/funkcja istnieją to użytkownik w łatwy sposób będzie mógł ja wywołać bez naszej dodatkowej pracy.
Postarałem się odpowiedź na pytanie po co, co to i dlaczego. W następnej części zaprezentuje moją klasę FC.
Proszę o konstruktywne komentarze. Chciałbym dodać na koniec że to jest moje podejście, oparte bardziej na doświadczniu niż fachowej literaturze, dlatego mogą znaleźć się tutaj luki.
About this entry
You’re currently reading “Front Controller – co to jest, po co to jest oraz przykładowa implementacja. Część 1.,” an entry on BartoszRychlicki.com
- Published:
- 11.26.06 / 3pm
- Category:
- php
8 Comments
Jump to comment form | comments rss [?] | trackback uri [?]