PHP Frameworks and MVC
60 minPHP frameworks provide structure, tools, and conventions for building web applications more efficiently. Frameworks handle common tasks like routing, database access, templating, authentication, and more, allowing you to focus on application logic. Popular frameworks include Laravel (most popular, elegant syntax), Symfony (enterprise-grade, highly flexible), CodeIgniter (lightweight, easy to learn), and Slim (minimal, for APIs). Understanding frameworks helps you choose the right one and build applications faster.
MVC (Model-View-Controller) is an architectural pattern that separates application concerns into three components: Models (data and business logic), Views (presentation/templates), and Controllers (handle requests, coordinate models and views). This separation improves code organization, maintainability, and testability. Models interact with databases, Views render output, and Controllers handle user input and coordinate the flow. Understanding MVC helps you organize code effectively.
Models represent data and business logic. They interact with databases, validate data, and contain business rules. Models are independent of presentation and can be reused across different views. In frameworks, models often use ORMs (Object-Relational Mappers) that map database tables to objects. Understanding models helps you separate data logic from presentation and create reusable business logic.
Views handle presentation and user interface. They receive data from controllers and render HTML, JSON, or other output formats. Views should contain minimal logicāmostly presentation and formatting. In PHP frameworks, views often use templating engines that provide features like inheritance, partials, and escaping. Understanding views helps you create maintainable, reusable templates.
Controllers handle HTTP requests, process input, interact with models, and return responses (views or JSON). Controllers are the entry points for application logic and coordinate between models and views. They should be thinādelegate business logic to models and services. Understanding controllers helps you structure request handling and application flow.
Best practices include following framework conventions, keeping controllers thin, putting business logic in models/services, using framework features (routing, ORM, validation), and understanding the framework's architecture. Frameworks provide structure, but you must understand their patterns to use them effectively. Understanding frameworks and MVC enables you to build scalable, maintainable PHP applications.
Key Concepts
- PHP frameworks provide structure and tools for web application development.
- MVC separates concerns into Models, Views, and Controllers.
- Models handle data and business logic.
- Views handle presentation and user interface.
- Controllers handle requests and coordinate models and views.
Learning Objectives
Master
- Understanding MVC architecture and its benefits
- Working with PHP frameworks (Laravel, Symfony, etc.)
- Organizing code using MVC pattern
- Using framework features for routing, ORM, and templating
Develop
- Application architecture thinking
- Understanding separation of concerns
- Designing scalable, maintainable applications
Tips
- Follow framework conventions for better productivity.
- Keep controllers thinādelegate business logic to models/services.
- Use framework features (routing, ORM, validation) instead of reinventing.
- Understand the framework's architecture to use it effectively.
Common Pitfalls
- Not following framework conventions, making code harder to maintain.
- Putting business logic in controllers instead of models.
- Not using framework features, reinventing the wheel.
- Choosing the wrong framework for your project needs.
Summary
- PHP frameworks provide structure and tools for efficient development.
- MVC separates concerns into Models, Views, and Controllers.
- Models handle data; Views handle presentation; Controllers coordinate.
- Understanding frameworks and MVC enables scalable applications.
- Frameworks help you build applications faster with best practices.
Exercise
Create a simple MVC framework structure and implement basic routing.
<?php
// Simple MVC Framework Structure
// Router class
class Router {
private $routes = [];
public function addRoute($method, $path, $handler) {
$this->routes[] = [
'method' => $method,
'path' => $path,
'handler' => $handler
];
}
public function get($path, $handler) {
$this->addRoute('GET', $path, $handler);
}
public function post($path, $handler) {
$this->addRoute('POST', $path, $handler);
}
public function dispatch($method, $uri) {
foreach ($this->routes as $route) {
if ($route['method'] === $method && $this->matchPath($route['path'], $uri)) {
return $route['handler'];
}
}
throw new Exception('Route not found');
}
private function matchPath($routePath, $uri) {
return $routePath === $uri;
}
}
// Base Controller class
abstract class Controller {
protected function render($view, $data = []) {
extract($data);
ob_start();
include "views/$view.php";
return ob_get_clean();
}
protected function redirect($url) {
header("Location: $url");
exit();
}
protected function json($data) {
header('Content-Type: application/json');
echo json_encode($data);
exit();
}
}
// User Controller
class UserController extends Controller {
public function index() {
$users = [
['id' => 1, 'name' => 'Alice', 'email' => 'alice@example.com'],
['id' => 2, 'name' => 'Bob', 'email' => 'bob@example.com']
];
return $this->render('users/index', ['users' => $users]);
}
public function show($id) {
$user = ['id' => $id, 'name' => 'User ' . $id, 'email' => 'user' . $id . '@example.com'];
return $this->render('users/show', ['user' => $user]);
}
public function create() {
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = $_POST['name'] ?? '';
$email = $_POST['email'] ?? '';
if (!empty($name) && !empty($email)) {
// In a real app, save to database
$this->redirect('/users');
}
}
return $this->render('users/create');
}
}
// Database Model (simplified)
class User {
private $pdo;
public function __construct($pdo) {
$this->pdo = $pdo;
}
public function all() {
$stmt = $this->pdo->query("SELECT * FROM users");
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
public function find($id) {
$stmt = $this->pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
return $stmt->fetch(PDO::FETCH_ASSOC);
}
public function create($data) {
$stmt = $this->pdo->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
return $stmt->execute([$data['name'], $data['email']]);
}
}
// Application bootstrap
$router = new Router();
// Define routes
$router->get('/users', [UserController::class, 'index']);
$router->get('/users/create', [UserController::class, 'create']);
$router->post('/users/create', [UserController::class, 'create']);
$router->get('/users/{id}', [UserController::class, 'show']);
// Dispatch request
try {
$method = $_SERVER['REQUEST_METHOD'];
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$handler = $router->dispatch($method, $uri);
if (is_array($handler)) {
[$controllerClass, $method] = $handler;
$controller = new $controllerClass();
echo $controller->$method();
} else {
echo $handler();
}
} catch (Exception $e) {
http_response_code(404);
echo "Page not found: " . $e->getMessage();
}