MVC (Model-View-Controller) is a software architectural pattern commonly used for developing user interfaces that divides an application into three interconnected components. This is done to separate internal representations of information from the ways information is presented to or accepted from the user, improving modularity and allowing for easier development, testing, and maintenance.
* Model: The Model represents the core logic, business rules, and data of the application. It encapsulates the application's state and behavior. The Model is independent of the user interface. It interacts with data sources (like databases, APIs, or files), performs data validation, and handles data storage and retrieval. When its state changes, it typically notifies its associated View(s) and Controller(s).
* View: The View is responsible for presenting the data from the Model to the user. It is the visual representation of the application and what the user interacts with. Views should be as "dumb" as possible, meaning they contain very little logic and primarily focus on displaying data provided by the Controller. A single Model can have multiple Views displaying different aspects of its data.
* Controller: The Controller acts as an intermediary between the Model and the View. It receives user input from the View, processes it, and then instructs the Model to update its state or requests data from the Model. After the Model has been updated or data has been retrieved, the Controller then selects the appropriate View to display the result to the user. Essentially, it orchestrates the flow of data and application logic.
How MVC Works (Flow):
1. User Interaction: A user interacts with the View (e.g., clicks a button, submits a form).
2. Controller Receives Input: The Controller intercepts this input.
3. Controller Updates Model: The Controller processes the input and, if necessary, sends instructions to the Model to update its state or retrieve data.
4. Model Processes Request: The Model performs the requested operations (e.g., fetches data from a database, saves data).
5. Model Notifies Controller/View (Optional but good practice): In some MVC implementations, the Model notifies the Controller (or directly the View) about changes.
6. Controller Selects View: Based on the Model's response or the initial request, the Controller selects the appropriate View to render.
7. View Renders Data: The View receives data from the Model (often passed via the Controller) and presents it to the user.
Benefits of MVC:
* Separation of Concerns: Each component has a distinct responsibility, making the code easier to understand, manage, and debug.
* Modularity and Reusability: Components are loosely coupled, allowing them to be reused in different parts of the application or even in other applications. For example, a Model can be used with different Views.
* Maintainability: Changes in one component have minimal impact on others. Developers can work on the View without affecting the Model or Controller logic.
* Testability: The distinct responsibilities make it easier to write unit tests for each component independently.
* Parallel Development: Different developers can work on the Model, View, and Controller simultaneously.
Example Code
```php
// File: models/Product.php
<?php
class Product {
private $products;
public function __construct() {
// Simulate database data
$this->products = [
1 => ['id' => 1, 'name' => 'Laptop', 'price' => 1200.00, 'description' => 'High-performance laptop.'],
2 => ['id' => 2, 'name' => 'Smartphone', 'price' => 800.00, 'description' => 'Latest generation smartphone.'],
3 => ['id' => 3, 'name' => 'Headphones', 'price' => 150.00, 'description' => 'Noise-cancelling headphones.'],
];
}
public function getProductById($id) {
return $this->products[$id] ?? null;
}
public function getAllProducts() {
return $this->products;
}
}
?>
// File: views/product_view.php
<?php
// The $product variable is expected to be passed from the controller
if (isset($product) && $product !== null) {
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Product Details</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.product-container { border: 1px solid #ccc; padding: 15px; border-radius: 5px; max-width: 500px; margin: auto; }
h1 { color: #333; }
p { margin-bottom: 5px; }
.price { font-weight: bold; color: #007bff; font-size: 1.2em; }
</style>
</head>
<body>
<div class="product-container">
<h1>Product Details</h1>
<p><strong>ID:</strong> <?php echo htmlspecialchars($product['id']); ?></p>
<p><strong>Name:</strong> <?php echo htmlspecialchars($product['name']); ?></p>
<p><strong>Description:</strong> <?php echo htmlspecialchars($product['description']); ?></p>
<p class="price"><strong>Price:</strong> $<?php echo number_format(htmlspecialchars($product['price']), 2); ?></p>
<p><a href="/">Back to Home</a></p>
</div>
</body>
</html>
<?php
} else {
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Product Not Found</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.error-container { border: 1px solid #dc3545; background-color: #f8d7da; color: #721c24; padding: 15px; border-radius: 5px; max-width: 500px; margin: auto; }
</style>
</head>
<body>
<div class="error-container">
<h1>Product Not Found</h1>
<p>The requested product could not be found.</p>
<p><a href="/">Back to Home</a></p>
</div>
</body>
</html>
<?php
}
?>
// File: controllers/ProductController.php
<?php
require_once 'models/Product.php';
class ProductController {
private $productModel;
public function __construct() {
$this->productModel = new Product();
}
public function show($id) {
$product = $this->productModel->getProductById($id);
// Pass data to the view
include 'views/product_view.php';
}
public function index() {
$products = $this->productModel->getAllProducts();
// For simplicity, let's create a basic list view or redirect
// In a real application, you'd have an 'all_products_view.php'
echo "<h1>All Products</h1>";
echo "<ul>";
foreach ($products as $product) {
echo "<li><a href=\"/product.php?id=" . htmlspecialchars($product['id']) . "\">" . htmlspecialchars($product['name']) . "</a> - $" . number_format(htmlspecialchars($product['price']), 2) . "</li>";
}
echo "</ul>";
echo "<p>Try navigating to <a href=\"/product.php?id=1\">/product.php?id=1</a> or <a href=\"/product.php?id=2\">/product.php?id=2</a></p>";
}
}
?>
// File: index.php (Main Entry Point for general navigation)
<?php
require_once 'controllers/ProductController.php';
$controller = new ProductController();
// Basic routing for homepage, showing all products
$controller->index();
?>
// File: product.php (Entry point for a specific product detail)
<?php
require_once 'controllers/ProductController.php';
$controller = new ProductController();
$productId = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ($productId > 0) {
$controller->show($productId);
} else {
// If no ID is provided, or ID is invalid, show 'Product Not Found'
$product = null; // Indicate no product found
include 'views/product_view.php';
}
?>
```
To run this example:
1. Create the following directory structure in your web server's document root (e.g., `htdocs` for Apache):
```
. (your web root)
├── index.php
├── product.php
├── controllers/
│ └── ProductController.php
├── models/
│ └── Product.php
└── views/
└── product_view.php
```
2. Copy the respective code into each file.
3. Access the application in your browser:
* `http://localhost/index.php` to see a list of all products.
* `http://localhost/product.php?id=1` to view details for Product ID 1.
* `http://localhost/product.php?id=2` to view details for Product ID 2.
* `http://localhost/product.php?id=99` (or any non-existent ID) to see the "Product Not Found" message.








MVC Architecture