Budujemy własny framework MVC w PHP – Część 1 – Podstawy
Dlaczego w ogóle budować własny framework PHP skoro jest już kilka całkiem ciekawych na rynku?
W większości przypadków nie ma sensu. Choćby ze względu na to, że będzie to dodatkowy kod, który należy uaktualniać, poprawiać i łatać, kod za który będziemy odpowiedzialni. W większości przypadków wybór jednego z pośród dostępnych frameworków to lepsze rozwiązanie które zaspokoić nasze potrzeby i które zapewni nam aktualizacje, nową funkcjonalność, usprawnienia, dokumentacje i pomoc społeczności skupionej wokół projektu.
Idea jest prosta. Nasz framework ma być na tyle elastyczny i prosty aby mogł być wykorzystany w każdym projekcie.
Na początek przekierujmy wszystkie zapytania do pliku index.php
# przekieruj nieuzywane pliki na nowe
Redirect 301 /stara_nazwa http://domena.pl/nowa_nazwa
# wylaczamy wspomaganie cachowania ETagi
Header unset ETag
FileETag none
# dajmy znac przegladarce ze pliki sa wazne np. 4 miesiace
# zmuszanie do odswiezania cachu w osobnym poscie
ExpiresActive On
ExpiresDefault "access plus 4 months"
# wlaczamy mod_rewrite
RewriteEngine on
RewriteBase /
# przekierujmy wszystkie nieistniejace wywolania do pliku index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)?$ index.php [QSA,L]
Inicjowanie
Skoro wszystkie „request’y” mamy przekierowane na plik index.php możemy zabrać się za główny plik naszego silnika.
Rozpoczynamy od zainicjowania skryptu:
require_once( '_application/init.php' );
Jest to jedne z miejsc gdzie warto użyć require_once, które jest wolniejsze od require, ale mieć gwarancje, że plik zostanie załączony tylko raz z uwagi na jego charakter. Plik ten będzie odpowiedzialny między innymi za dynamiczne ładowanie klas.
Przyjrzyjmy się zatem plikowi ini:
/* definiujemy glowna sciezke */
define('APP_PATH', $_SERVER['DOCUMENT_ROOT'].'/');
/* definiujemy srodowisko @PARAM stage / production */
define('APP_ENVIRONMENT', 'stage');
/* definiujemy wersje */
define('APP_VERSION', '0.1');
switch( APP_ENVIRONMENT )
{
case 'stage': error_reporting(E_ALL ^ E_NOTICE); break;
default: error_reporting(0);
}
/* definiujemy sciezke publiczna */
define('APP_WEB_PATH', 'http://'.$_SERVER['HTTP_HOST']);
/* zaladujmy konfiguracje */
require_once( APP_PATH.'_config/configuration.php' );
/* definiujemy dynamiczny autoload dla klas */
function __autoload($class_name)
{
require_once( APP_PATH . '_' . str_replace('_', '/', strtolower($class_name)) . '.php' );
}
/* inicjujemy sesje */
session_start();
Funkcja __autoload() jest wywoływana automatycznie gdy następuje próba odwołania do klasy, która nie została jeszcze zdefiniowana. Wtedy parser sięgnie do definicji naszej funkcji autoload i według zdefiniowanego tam wzoru spróbuje załadować klasę. W tym frameworku wszystkie klasy będą miały postać znaną już z bibliotek PEAR czyli np. Application_Router_Default co podpowie parserowi aby szukał definicji tej klasy, zgodnie z definicją autoload, w lokalizacji:
/home/user/public_html/_application/router/default.php
Zauważ, że funkcja dodała znak podkreślenia do ścieżki i zamieniła istniejące podkreślenia na znaki „/” tworząc tym samym ścieżkę do pliku klasy.
To dość nietypowe rozwiązanie wynika z faktu, że nasz framework będzie również trochę nietypowy ale o tym troche poźniej!
Struktura katalogów frameworka wygląda nastepująco:
- _application
- _cms
- _config
- _controllers
- _js
- _library
- _models
- _templates
- .htaccess
- index.php
Jak widać pliki naszej aplikacji znajdują się w katalogu publicznym ze względu na zaskakująco dużą popularność tego typu rozwiązania na polskich hostingach. W idealnej sytuacji powinny one znajdować się powyżej tego poziomu, tam gdzie będą bezpieczne, natomiast katalog publiczny powinien zawierać jedynie index.php , .htaccess i te katalogi, które będą używane do przetrzymywania danych użytkownika typu, obrazki galerii, ikony profili itp. itd.
Nie zostawimy oczywiście tych plików na pożarcie hakerom. Zastosujemy tu doraźne zabezpieczenie przed bezpośrednim odwoływaniem się do tych plików z poziomu http://domana.pl/includowany_plik.php
Mianowicie na początku każdego pliku z rozszerzeniem .php doklejamy:
defined('APP_PATH') or die();
Próba odwołania do takiego pliku w inny sposób aniżeli za pośrednictwem index.php zakończy się zakończeniem skryptu.
Po zainicjowaniu systemu i załadowaniu konfiguracji możemy przystąpić do pierwszych kroków naszego frameworka w modelu MVC (Model View Controller)
Ale to już w kolejnej części…
Data: lip 1, 2009
Komentuj na Skrypta.pl
Witam.
Chciałem zaprezentować również moją koncepcję:
http://baszczewski.pl/blog/show/php_prosty_framework_1