Jeżeli chcesz tworzyć bardzo dobry kod PHP ale nie lubisz korzystać z ciężkich Frameworków, które jedynie co robią to spowalniają działanie całej aplikacji i ograniczają cię przy rozwoju kodu dając w zamian jedynie złudne poczucie porządku i ładnie wyglądającego kodu – ten wpis jest dla ciebie. Pokażę ci jak stworzyć własny, lekki i skuteczny Framework MVC.
Co to jest MVC?
MVC to skrót od Model-View-Controller. Jest to wzorzec architektoniczny (czyli poprawny sposób rozwiązania danego problemu z zakresu programowania) służący do organizowania struktury aplikacji posiadających GUI czyli Graficzny Interfejs Użytkownika. Jeżeli zatem twoja aplikacja internetowa wyświetla informacje w przeglądarce i posiada formularze, powinieneś wykorzystać architekturę MVC.
Architektura MVC zakłada podział kodu na trzy wzajemnie połączone części:
Model – przechowuje logikę aplikacji czyli to w nim są zapisane algorytmy i tutaj powinno się odczytywać i zapisywać rekordy w bazie danych
View – czyli „Widok” to część kodu odpowiedzialna za wygląd aplikacji czyli w przypadku aplikacji internetowych to tutaj zaszyte są style CSS, i efekty wizualne – mówiąc ogólnie szablon
Controller – odpowiada za komunikację modeli z widokami i „odpala” poszczególne funkcje aplikacji.
Jakie to daje korzyści?
Czystość kodu – Kod odpowiedzialny za wygląd aplikacji nie miesza się z kodem odpowiedzialnym za działanie aplikacji innymi słowy unikasz np. sytuacji gdzie przeplatasz kod HTML z kodem PHP czyli coś takiego:
<?php while($record = mysqli_fetch_assoc($query)) {?> <tr> <td><label><input type="checkbox" name="post[]" value="<?=$record["product_id"]?>"></label></td> <td><?=$record["product_name"]?></td> <td><?=$record["category_name"]?></td><td><?=$record["product_quantity"]?></td> <td><?=$record["product_price"]?></td><td><?=$record["product_excerpt"]?></td> </tr> <?php } ?>
Nie powtarzasz się – kod jest zgodny z podejściem DRY, czyli nie robisz „kopiuj-wklej” tylko dlatego, że w innym miejscu chcesz użyć pobranych danych zaprezentowanych w innych sposób
Łatwiejsza rozbudowa widoku – widok nie zawiera logiki z modelu stąd zawiera o wiele mniej kodu, łatwiej go rozbudowywać i upiększać 🙂
Łatwość integracji – integrując aplikację z innym systemem, możesz odwoływać się do jej zasobów z całkowitym pominięciem widoku, w wyniku czego łatwiej jest zapanować nad komunikacją pomiędzy systemami.
Krok 1: Routing adresów URL w .htaccess
ścieżka: APLIKACJA/public/.htaccess
Options -MultiViews RewriteEngine On RewriteBase /public RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
Jak widać, przekierowujemy cały ruch do index.php
Krok 2: Wyłączamy indexy w folderze app
ścieżka: APLIKACJA/app/.htacces
Options -Indexes
Krok 3: Klasa App
ścieżka: APLIKACJA/app/core/App.php
<?php class App{ protected $controller = "home"; protected $method = "index"; protected $params = []; public function __construct(){ $url = $this -> parseUrl(); if(file_exists("../app/controllers/". $url[0] . '.php')){ $this->controller = $url[0]; unset($url[0]); } require_once ("../app/controllers/".$this->controller.".php"); $this -> controller = new $this -> controller; if(isset($url[1])){ if(method_exists($this->controller, $url[1])){ $this->method = $url[1]; unset($url[1]); } } $this -> params = $url ? array_values($url) : []; call_user_func_array([$this -> controller, $this -> method], $this -> params); } public function parseUrl(){ if(isset($_GET['url'])){ return $url = explode("/", filter_var(rtrim($_GET["url"], "/"), FILTER_SANITIZE_URL)); } } } ?>
Po kolei:
- tworzymy pola, w śród nich domyślny kontroler „home” dla strony głównej
- konstruktor parsujący adres url
- odpalamy kontroler według ścieżki i wyrzucamy kontroler z tablicy
- tworzymy obiekt kontrolera i sprawdzamy czy istnieje wskazana w URL metoda jeżeli tak to ją odpalamy
Krok 4: Klasa Controller
ścieżka: APLIKACJA/app/core/Controller.php
<?php if(!isset($_SESSION)) { session_start(); } require_once(__DIR__ ."/../dbconfig.php"); class Controller{ public function model($model){ require_once "../app/models/" . $model . ".php"; return new $model(); } public function view($view, $data=[]){ require_once ("../app/views/" . $view . ".php"); } } ?>
Krok 5: Inicjalizacja
ścieżka: APLIKACJA/app/init.php
<?php require_once("core/App.php"); require_once("core/Controller.php"); ?>
Krok 6: Połączenie z bazą danych (uwaga, dla uproszczenia wykonane strukturalnie – to nie jest „podejście OOP”)
ścieżka: APLIKACJA/app/dbconfig.php
function dbstart(){ $dbhost = "localhost"; $dbname = "qa"; $dbuser = "root"; $dbpass = ""; global $dbconn; $dbconn = mysqli_connect($dbhost,$dbuser,$dbpass) or die ("błąd połączenia z serwerem $host"); mysqli_select_db($dbconn, $dbname) or die("błąd połączenia z bazą danych"); } function dbstop(){ global $dbconn; mysqli_close($dbconn); }
To wszystko! Teraz czas na przykładowe wykorzystanie…
Krok 7: Przykładowy model pobierania postu z bazy danych
ścieżka APLIKACJA/app/models/Post.php
class Post{ function pobierzPost($qid = ""){ global $dbconn; dbstart(); $query = mysqli_query($dbconn, "SELECT * FROM posty WHERE id = $qid"); while($row = mysqli_fetch_assoc($query)){ $output = $row; } dbstop(); return $output; }
Strukturalnie, a co tam…
Krok 8: Przykładowy kontroler pobierania postu z modelu
ścieżka APLIKACJA/app/controllers/single.php
class Single extends Controller{ public function index($qid = ""){ $post = $this -> model("Post"); $data = [ "post" => $post -> pobierzPost($qid), "qid" => $qid ]; $this -> view("single/index", $data); } }
Krok 9: Przykładowy widok wyświetlania pobranego postu z kontrolera
ścieżka APLIKACJA/app/views/single/index.php
<html> <head> <title><?=$data["post"]["tytul_posta"]?></title> </head> <body> <?=$data["post"]["tresc_posta"]?> </body> </html>
Krok 10: Wyświetlenie strony
ścieżka w przegladarce: http://APLIKACJA/public/single/20
Czyli wyświetlamy post z bloga, którego unkalny id to 20
Podsumowanie
Mam nadzieję że już nakreśliłem ci jak MVC działa „od środka”. Jak widać wcale nie trzeba używać żadnego Frameworka by stosować wzorzec MVC we własnej aplikacji PHP. Tworzenie aplikacji faktycznie od podstaw daje dużo więcej satysfakcji. Jeżeli chcesz jednak budować aplikacje na Frameworku polecam CodeIgniter. Stosuje on dość podobny mechanizm i nie wymaga stosowania szablonów w widokach, które w największym stopniu spowalniają działanie aplikacji.
Odpowiedz lub skomentuj