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:

MVC w PHP

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.

Źródła

Oceń artykuł na temat: Własny Framework MVC dla PHP
Średnia : 4.5 , Maksymalnie : 5 , Głosów : 42