Wprowadzenie
W miarę jak aplikacje internetowe rosną w złożoności, organizacja kodu staje się kluczowa dla jego łatwego utrzymania i rozwoju. Jednym z najczęściej używanych wzorców projektowych w aplikacjach webowych jest MVC (Model-View-Controller). MVC dzieli aplikację na trzy główne części: Model, View i Controller, co ułatwia zarządzanie kodem, wprowadzenie zmian i utrzymanie aplikacji w dłuższym czasie. W tej lekcji omówimy dokładnie, czym jest wzorzec MVC, jak go zaimplementować w PHP oraz jakie korzyści oferuje.
Co to jest MVC?
MVC (Model-View-Controller) to wzorzec projektowy, który dzieli aplikację na trzy główne komponenty:
- Model: Odpowiada za logikę biznesową oraz operacje na danych (np. interakcje z bazą danych).
- View: Odpowiada za prezentację danych, czyli to, co użytkownik widzi (interfejs użytkownika).
- Controller: Odpowiada za przyjmowanie żądań użytkownika, kontrolowanie przepływu danych między modelem a widokiem oraz decydowanie, jakie dane powinny być wyświetlane.
Dzięki podziałowi aplikacji na te trzy komponenty, kod jest bardziej modularny, co ułatwia jego zarządzanie i rozbudowę. MVC pozwala na oddzielenie logiki biznesowej od prezentacji, co jest szczególnie ważne w dużych projektach.
Struktura aplikacji w MVC
W klasycznej aplikacji PHP pliki PHP, HTML i inne zasoby są często ze sobą wymieszane, co prowadzi do trudności w utrzymaniu kodu. MVC wprowadza porządek w strukturze aplikacji, organizując ją w odpowiednie foldery dla każdego z trzech komponentów.
Przykładowa struktura projektu MVC:
/app /controllers HomeController.php UserController.php /models User.php /views /home index.php /user login.php register.php /core Router.php Controller.php Model.php /config config.php /public index.php
Implementacja wzorca MVC w PHP
1. Model – Warstwa logiki biznesowej
Model odpowiada za dostęp do danych oraz logikę aplikacji. Modele są klasami, które komunikują się z bazą danych i dostarczają dane do kontrolera.
Przykład modelu User:
<?php class User { private $conn; public function __construct($db) { $this->conn = $db; } public function getUserById($id) { $stmt = $this->conn->prepare("SELECT * FROM users WHERE id = :id"); $stmt->bindParam(':id', $id, PDO::PARAM_INT); $stmt->execute(); return $stmt->fetch(PDO::FETCH_ASSOC); } public function createUser($username, $email, $password) { $stmt = $this->conn->prepare("INSERT INTO users (username, email, password) VALUES (:username, :email, :password)"); $stmt->bindParam(':username', $username); $stmt->bindParam(':email', $email); $stmt->bindParam(':password', password_hash($password, PASSWORD_DEFAULT)); return $stmt->execute(); } } ?>
W powyższym przykładzie model User zajmuje się operacjami związanymi z użytkownikami, takimi jak pobieranie danych użytkownika z bazy danych oraz tworzenie nowych użytkowników.
2. View – Warstwa prezentacji
Widoki są odpowiedzialne za wyświetlanie danych. Widoki są plikami HTML lub PHP, które są renderowane, aby użytkownik mógł zobaczyć wyniki działania aplikacji.
Przykład widoku login.php:
<!DOCTYPE html> <html lang="pl"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Logowanie</title> </head> <body> <h1>Zaloguj się</h1> <form action="/user/login" method="post"> <label for="username">Nazwa użytkownika:</label> <input type="text" id="username" name="username" required><br> <label for="password">Hasło:</label> <input type="password" id="password" name="password" required><br> <input type="submit" value="Zaloguj"> </form> </body> </html>
Widok odpowiada za prezentację i nie powinien zawierać logiki biznesowej ani bezpośrednich interakcji z modelem. Otrzymuje dane z kontrolera, które są następnie wyświetlane.
3. Controller – Warstwa kontrolera
Kontroler odpowiada za przyjmowanie żądań od użytkownika i interakcję z modelem oraz widokiem. Kontroler przetwarza żądania, pobiera dane z modelu i przekazuje je do odpowiedniego widoku.
Przykład kontrolera UserController.php:
<?php class UserController { private $model; public function __construct($model) { $this->model = $model; } public function login() { if ($_SERVER["REQUEST_METHOD"] == "POST") { $username = $_POST['username']; $password = $_POST['password']; $user = $this->model->getUserByUsername($username); if ($user && password_verify($password, $user['password'])) { $_SESSION['user'] = $user['username']; header("Location: /home"); } else { echo "Nieprawidłowa nazwa użytkownika lub hasło."; } } else { require 'app/views/user/login.php'; } } public function register() { if ($_SERVER["REQUEST_METHOD"] == "POST") { $username = $_POST['username']; $email = $_POST['email']; $password = $_POST['password']; $this->model->createUser($username, $email, $password); header("Location: /user/login"); } else { require 'app/views/user/register.php'; } } } ?>
Kontroler UserController odpowiada za obsługę logowania i rejestracji użytkownika. Otrzymuje dane od użytkownika (np. z formularza logowania), przekazuje je do modelu, a następnie decyduje, który widok powinien zostać wyświetlony.
Tworzenie routera (Routing)
W MVC potrzebujemy mechanizmu, który zarządza żądaniami użytkownika i przekierowuje je do odpowiedniego kontrolera i metody. W prostym przykładzie możemy stworzyć router, który interpretuje URL i przekierowuje żądanie do odpowiedniej akcji kontrolera.
Przykład prostego routera:
<?php class Router { public static function route($url) { $parts = explode('/', trim($url, '/')); $controller = !empty($parts[0]) ? ucfirst($parts[0]) . 'Controller' : 'HomeController'; $action = !empty($parts[1]) ? $parts[1] : 'index'; $controllerFile = "app/controllers/" . $controller . ".php"; if (file_exists($controllerFile)) { require_once $controllerFile; $controllerInstance = new $controller(); if (method_exists($controllerInstance, $action)) { $controllerInstance->$action(); } else { echo "Akcja nie istnieje."; } } else { echo "Kontroler nie istnieje."; } } } ?>
Router analizuje URL (np. /user/login
) i odpowiednio przekierowuje żądanie do kontrolera UserController i metody login().
Strona główna aplikacji – Plik index.php
Główne wejście do aplikacji, plik index.php
, może wyglądać tak:
<?php session_start(); require_once 'app/core/Router.php'; require_once 'app/models/User.php'; $url = $_SERVER['REQUEST_URI']; Router::route($url); ?>
Ten plik inicjuje sesje i uruchamia router, który obsługuje wszystkie żądania użytkownika.
Zalety wzorca MVC
- Separacja logiki biznesowej od prezentacji: Ułatwia zarządzanie kodem, ponieważ logika aplikacji i warstwa widoku są od siebie oddzielone.
- Łatwość rozbudowy: Wzorzec MVC sprawia, że rozbudowa aplikacji jest łatwiejsza, ponieważ możemy dodawać nowe funkcje bez zmieniania istniejących modułów.
- Wydajność zespołowa: Dzięki oddzieleniu warstw, programiści mogą pracować nad modelem, kontrolerem i widokiem niezależnie od siebie.
- Zwiększona czytelność kodu: Kod jest bardziej zorganizowany, co poprawia jego czytelność i ułatwia jego zrozumienie innym programistom.
Wyzwania związane z MVC
- Początkowa złożoność: W porównaniu do prostych skryptów PHP, struktura MVC może wydawać się bardziej złożona, co wymaga nauki i zrozumienia, jak działają poszczególne komponenty.
- Przesadne rozdzielenie kodu: Przy małych projektach MVC może wprowadzać nadmierną złożoność, która nie jest potrzebna.
Podsumowanie
W tej lekcji dowiedzieliśmy się, czym jest wzorzec MVC, jak dzieli aplikację na trzy warstwy (Model, View, Controller) oraz jak zbudować prostą aplikację w PHP z wykorzystaniem MVC. MVC pozwala na lepszą organizację kodu, co jest kluczowe dla rozwoju i utrzymania złożonych aplikacji. Wzorzec ten nie tylko pomaga w rozwoju dużych aplikacji, ale także sprzyja pracy zespołowej, gdzie różne osoby mogą pracować nad różnymi częściami aplikacji.
Gratulacje! Ukończyłeś lekcję 12.
Przejdź teraz do lekcji 13 >> Zaawansowane techniki pracy z bazami danych w PHP
Spis Treści - darmowy kurs PHP
Wprowadzenie: Instalacja środowiska PHP
Lekcja 1: Podstawy składni PHP
Lekcja 2: Funkcje i instrukcje warunkowe w PHP
Lekcja 3: Pętle w PHP
Lekcja 4: Tablice w PHP
Lekcja 5: Dodatkowe podstawy funkcji w PHP
Lekcja 6: Praca z formularzami HTML w PHP
Lekcja 7: Obsługa plików w PHP
Lekcja 8: Sesje i ciasteczka w PHP
Lekcja 9: Podstawy operacji na bazach danych MySQL z PHP
Lekcja 10: Prepared Statements w PHP i bezpieczeństwo aplikacji
Lekcja 11: Zarządzanie użytkownikami – rejestracja, logowanie i autoryzacja w PHP
Lekcja 12: Wzorce projektowe w PHP – wprowadzenie do wzorca MVC
Lekcja 13: Zaawansowane techniki pracy z bazami danych w PHP
Lekcja 14: Testowanie jednostkowe w PHP z PHPUnit
Lekcja 15: Tworzenie i korzystanie z API RESTful w PHP
Lekcja 16: Obsługa plików JSON i XML w PHP
Dodatki
- Spis najważniejszych funkcji PHP