MVC مخفف Model-View-Controller است و یک الگوی طراحی (Design Pattern) محسوب میشود که معمولاً در توسعه نرمافزار، بهویژه توسعه اپلیکیشنهای وب، استفاده میشود. همانطور که از نام آن مشخص است، در این الگو اپلیکیشن به سه مؤلفه مرتبط با یکدیگر تقسیم میشود تا ماژولار بودن، نگهداری و توسعه آن سادهتر شود.
مدل (Model) مسئول مدیریت دادهها و منطق کسبوکار اپلیکیشن است؛ به این معنی که وظیفه دریافت، پردازش، تغییر و ذخیرهسازی دادهها را بر عهده دارد.
ویو (View) لایه نمایش اپلیکیشن است و وظیفه ارائه دادهها به کاربر نهایی را بر عهده دارد.
کنترلر (Controller) نقش واسط بین Model و View را ایفا میکند. کنترلر ورودیهای کاربر را دریافت میکند و تصمیم میگیرد کدام مدل یا مدلها فراخوانی شوند و کدام ویو به کاربر نمایش داده شود.
با توجه به این توضیحات، الگوی MVC با تفکیک مسئولیتها، مدیریت دادهها (Model)، رابط کاربری (View) و منطق اجرایی اپلیکیشن (Controller) را از یکدیگر جدا میکند. این جداسازی باعث میشود درک، نگهداری و توسعه اپلیکیشن آسانتر شود.
پیشنیازها
در این آموزش یاد میگیرید چگونه یک فریمورک ساده MVC در PHP را از صفر بسازید. برای دنبال کردن مراحل آموزش، بهتر است با مفاهیم زیر آشنایی اولیه داشته باشید:
- مفاهیم برنامهنویسی شیءگرا در PHP
- Composer؛ ابزار مدیریت پکیجهای PHP
- HTML و CSS؛ برای ساخت صفحات اپلیکیشن پس از آماده شدن فریمورک (برای ساخت خود فریمورک الزامی نیستند)
راهاندازی پروژه
ابتدا یک دایرکتوری جدید برای پروژه ایجاد کنید و آن را در ویرایشگر کد دلخواه خود باز کنید. سپس دستور زیر را در ترمینال اجرا کنید تا یک پروژه جدید Composer راهاندازی شود:
composer init
میتوانید با فشردن کلید Enter از پرسشهای اولیه عبور کنید. هنگام پرسش درباره افزودن وابستگیها (Dependencies) و وابستگیهای توسعه (Dev Dependencies)، فعلاً گزینه no را وارد کنید.
پس از اتمام فرایند، پیامی مشابه پیام زیر مشاهده خواهید کرد:
PSR-4 autoloading configured.
Use "namespace Maheshsamudra\SimplePhpMvcStarter;" in src/
برای سادهتر شدن مثال، فضای نام (Namespace) پروژه را به نام کوتاهتری مانند App تغییر میدهیم. برای این کار، کلید مربوط به psr-4 را در فایل composer.json به شکل زیر تغییر دهید:
"Maheshsamudra\\SimplePhpMvcStarter\\": "App\\"
سپس دستور زیر را اجرا کنید تا فایلهای Autoload مربوط به کلاسهای پروژه بهروزرسانی شوند:
composer dump-autoload
ساختار دایرکتوریها
ساختار اولیه پروژه به شکل زیر خواهد بود:
public/ # دایرکتوری عمومی و نقطه ورود درخواستهای وب
src/
Controllers/ # کنترلرها
Models/ # مدلها
Routes/ # تعریف مسیرها
Views/ # فایلهای نمایش
vendor/ # فایلهای تولیدشده توسط Composer
پیادهسازی مؤلفههای اصلی
راهاندازی پوشه public
یک فایل با نام index.php در پوشه public/ ایجاد کنید. این فایل نقطه ورود (Entry Point) اپلیکیشن خواهد بود.
<?php
require '../vendor/autoload.php';
$router = require '../src/Routes/index.php';
با این کار، ابتدا Autoloader مربوط به Composer بارگذاری میشود و سپس فایل تعریف مسیرهای اپلیکیشن اجرا خواهد شد.
مدیریت مسیرها (Routes)
فایلی با نام Router.php در پوشه src/ ایجاد کنید. این کلاس وظیفه نگاشت مسیرهای ورودی به کنترلر و متد مناسب را بر عهده خواهد داشت.
<?php
namespace App;
class Router
{
protected $routes = [];
private function addRoute($route, $controller, $action, $method)
{
$this->routes[$method][$route] = [
'controller' => $controller,
'action' => $action
];
}
public function get($route, $controller, $action)
{
$this->addRoute($route, $controller, $action, "GET");
}
public function post($route, $controller, $action)
{
$this->addRoute($route, $controller, $action, "POST");
}
public function dispatch()
{
$uri = strtok($_SERVER['REQUEST_URI'], '?');
$method = $_SERVER['REQUEST_METHOD'];
if (array_key_exists($uri, $this->routes[$method])) {
$controller = $this->routes[$method][$uri]['controller'];
$action = $this->routes[$method][$uri]['action'];
$controller = new $controller();
$controller->$action();
} else {
throw new \Exception("No route found for URI: $uri");
}
}
}
اکنون برای تعریف مسیرهای اولیه، فایلی با نام index.php در پوشه src/Routes/ ایجاد کنید. در این فایل میتوانید مسیرهای مربوط به درخواستهای GET و POST را تعریف کنید.
<?php
use App\Controllers\HomeController;
use App\Router;
$router = new Router();
$router->get('/', HomeController::class, 'index');
$router->dispatch();
در این مثال، درخواست GET به مسیر / به متد index از کلاس HomeController هدایت میشود.
کنترلرها؛ مدیریت صفحه اصلی
ابتدا فایلی با نام Controller.php در پوشه src/ ایجاد کنید.
<?php
namespace App;
class Controller
{
protected function render($view, $data = [])
{
extract($data);
include "Views/$view.php";
}
}
متد render دادههای موردنیاز ویو را دریافت میکند و آنها را در اختیار فایل مربوط به صفحه قرار میدهد.
اکنون باید یک کنترلر برای مدیریت درخواستهای صفحه اصلی ایجاد کنیم. در پوشه src/Controllers/ فایلی با نام HomeController.php بسازید و متد index را در آن تعریف کنید.
<?php
namespace App\Controllers;
use App\Controller;
class HomeController extends Controller
{
public function index()
{
$this->render('index');
}
}
در اینجا، HomeController از کلاس پایه Controller ارثبری میکند و با فراخوانی متد render، ویوی صفحه اصلی را نمایش میدهد.
افزودن ویوها (Views)
در نهایت، برای نمایش صفحه اصلی، فایلی با نام index.php در پوشه src/Views/ ایجاد کنید.
<h1>به فریمورک ساده MVC در PHP خوش آمدید!</h1>
آزمایش عملکرد پروژه
اکنون اپلیکیشن آماده نمایش صفحه اصلی است. برای آزمایش، وارد پوشه public شوید و وبسرور داخلی PHP را اجرا کنید:
cd simple-php-mvc-starter/public
php -S localhost:9999
اگر همهچیز بهدرستی تنظیم شده باشد، با مراجعه به آدرس زیر در مرورگر، صفحه اصلی را مشاهده خواهید کرد:
http://localhost:9999

ایجاد یک مدل (Model)
فایلی با نام Journal.php در پوشه Models/ ایجاد کنید. این کلاس نمایانگر یک یادداشت یا ورودی ژورنال در اپلیکیشن خواهد بود.
<?php
namespace App\Models;
class Journal
{
public $name;
public $publishedYear;
public function __construct($name, $publishedYear)
{
$this->name = $name;
$this->publishedYear = $publishedYear;
}
}
در این کلاس، دو ویژگی name و publishedYear برای نگهداری عنوان و سال انتشار تعریف شدهاند. سازنده کلاس نیز این مقادیر را هنگام ایجاد یک شیء دریافت میکند.
حالا بیایید چند ورودی ژورنال به صفحه اصلی اضافه کنیم. برای این کار، فایل HomeController.php را به شکل زیر بهروزرسانی کنید:
<?php
namespace App\Controllers;
use App\Controller;
use App\Models\Journal;
class HomeController extends Controller
{
public function index()
{
$journals = [
new Journal('My Third Journal Entry', '2023'),
new Journal('My Second Journal Entry', '2022'),
new Journal('My First Journal Entry', '2021')
];
$this->render('index', ['journals' => $journals]);
}
}
در این نسخه، سه شیء از کلاس Journal ایجاد میشوند و آرایه آنها از طریق متد render به ویو ارسال میشود.
در نهایت، فایل index.php در پوشه Views/ را به شکل زیر تغییر دهید:
<h1>به فریمورک ساده MVC در PHP خوش آمدید!</h1>
<ul>
<?php foreach ($journals as $journal) : ?>
<li>
<?= $journal->name ?> (<?= $journal->publishedYear ?>)
</li>
<?php endforeach; ?>
</ul>
با استفاده از حلقه foreach، تمام ورودیهای ژورنال پیمایش میشوند و عنوان و سال انتشار هرکدام در صفحه نمایش داده میشود.
به همین سادگی، شما اولین فریمورک MVC خود را در PHP از صفر ساختهاید.

با وجود سادگی این پروژه، ساخت یک فریمورک MVC در PHP از ابتدا میتواند تجربه ارزشمندی باشد و به درک بهتر ساختار داخلی فریمورکها، نحوه مسیریابی درخواستها، تفکیک مسئولیتها و ارتباط بین مدل، ویو و کنترلر کمک کند. البته این پیادهسازی صرفاً نقطه شروع است و برای استفاده در محیط عملیاتی (Production) به بهبودهای بیشتری نیاز دارد.

دیدگاهها
ثبت دیدگاه