شنو هو MVC فالبرمجة؟ مثال PHP و MySQL بالدارجة
شنو هو MVC فالبرمجة؟ كنرتبو CRUD ديال PHP و MySQL بلا framework: Model وView وController وRouter، مع مثال PHP كامل بالدارجة.
كاين حتى ب : Français

MVC (Model, View, Controller) هو طريقة باش نقسمو الكود ديال التطبيق على 3 أدوار: Model كيتكلم مع la base، View كتعرض HTML، وController كيستقبل الطلب وكينسق بيناتهم. فدرس E10، طبقنا هاد الفكرة على CRUD حقيقي بـ PHP و MySQL، بلا framework، وزدنا Router كيدخل منو كل طلب من باب واحد. وهادي هي نفس التنظيم اللي غادي تلقى فـ Laravel.
علاش الفيشي الواحد كيولي كيكسر كلشي؟
فالبداية، كلشي كيكون فـ index.php: الكونيكسيون، la requête SQL، الخدمة ديال الفورم، والطابلو ديال HTML. هادا هو الفيشي اللي بان فالبداية ديال الدرس، مختصر:
<?php require "db.php";
$users = $pdo->query("SELECT * FROM users")->fetchAll();
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$pdo->prepare("INSERT INTO users ...")->execute([...]);
}
?>
<h1>Les utilisateurs</h1>
<table>
<?php foreach ($users as $u): ?>
<tr><td><?= $u["nom"] ?></td></tr>
<?php endforeach; ?>
</table>SQL والمنطق و HTML مخلطين. ملي كيكون المشروع صغير، كيدوز. ولكن ملي كيكبر، ما كتبقاش عارف فين تبدل، وأي تعديل صغير يقدر يكسر ليك شي حاجة أخرى.
شنو هو MVC، بمثال ساهل؟
فالدرس خدمنا بمثال الريسطو:
- Controller هو السرباي: كياخد la commande وكيعرف شكون خاصو يخدم؛
- Model هو الكوزينة: كيتكلم مع MySQL وكيوجد المعلومات؛
- View هي الطبسيل: كتعرض المعلومات فـ HTML، وصافي.
فالدوسيات، كتولي عندنا هاد البنية:
app/
Models/User.php
Views/users/index.php
Controllers/UserController.php
config/db.php
public/index.php ← الباب الوحيد ديال السيتModel: هو الوحيد اللي كيتكلم مع la base
فـ app/Models/User.php، كل requête SQL ديال CRUD كتولي méthode. والكلاس كتاخد $pdo من db.php:
<?php
class User {
public function __construct(private PDO $pdo) {}
public function all(): array {
return $this->pdo->query("SELECT * FROM users")->fetchAll();
}
public function find(int $id): array|false {
$stmt = $this->pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
return $stmt->fetch();
}
public function create(string $nom, string $email): void {
$stmt = $this->pdo->prepare("INSERT INTO users (nom, email) VALUES (?, ?)");
$stmt->execute([$nom, $email]);
}
// update() et delete() : même principe
}القاعدة: Model ما كيعرف والو على HTML، وما كيشوفش $_POST. غير المعلومات. وفالدرس شفنا جوج فوائد: إلا احتاجيتي نفس la requête فبلاصة أخرى، كتعيط للـ méthode وما كتعاودش تكتب SQL؛ وإلا شي نهار بدلتي la base، كتبدل غير Model، والباقي ما كيتقاس.
View: HTML نقي، بلا SQL
app/Views/users/index.php ما بقا فيها غير الطابلو. كتوصلها $users واجدة:
<h1>Les utilisateurs</h1>
<a href="/users/create">Ajouter</a>
<table>
<?php foreach ($users as $u): ?>
<tr>
<td><?= htmlspecialchars($u["nom"]) ?></td>
<td><?= htmlspecialchars($u["email"]) ?></td>
<td><a href="/users/edit?id=<?= $u["id"] ?>">Modifier</a></td>
</tr>
<?php endforeach; ?>
</table>ما كاين حتى SELECT، وما كاين حتى $pdo: View ما كتسولش la base. ولكن htmlspecialchars ديما فـ View، حيت هي اللي كتعرض، إذن هي اللي خاصها تحمي من XSS. والكتابة بـ <?= و endforeach كتخلي HTML نقي، حتى designer ما كيعرفش PHP يقدر يفهمو. وبغيتي تبدل le design؟ كتبدل غير View.
Controller: كينسق، بلا SQL وبلا HTML
app/Controllers/UserController.php فيه méthode لكل صفحة. la méthode index فيها سطر واحد مهم، ومن بعد render:
<?php
class UserController {
public function __construct(private User $user) {}
public function index(): void {
$users = $this->user->all();
$this->render("users/index", ["users" => $users]);
}
private function render(string $view, array $data): void {
extract($data); // ["users" => …] devient $users
require __DIR__ . "/../Views/$view.php";
}
}render فونكسيون صغيرة: extract كترد الطابلو variables، و require كيجيب View.
فين نديرو la validation ديال الفورم؟
فـ Controller، ماشي فـ View. la méthode store كتقرا $_POST، كتتأكد من l'email، ومن بعد كتعيط لـ Model:
public function store(): void {
$email = trim($_POST["email"] ?? "");
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$this->render("users/create", ["erreur" => "Email invalide"]);
return;
}
$this->user->create($_POST["nom"], $email);
header("Location: /users");
exit;
}إلا كان l'email غالط، كنرجعو للفورم مع رسالة. وإلا كان مزيان، header("Location: …") و exit، بحال فـ CRUD. Controller ما كيكتب لا SQL لا HTML.
Router: شكون كيعرف أنهي Controller نعيطو ليه؟
كل الطلبات كتدخل من public/index.php، وهادا كنسميوه front controller. وفـ .htaccess، كاين قاعدة كتصيفط أي URL لـ index.php بلا ما يبانو الفيشيات ديال PHP:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]وفـ index.php، طابلو ديال les routes كيربط كل « méthode + chemin » بـ Controller و méthode:
<?php
require __DIR__ . "/../config/db.php";
require __DIR__ . "/../app/Models/User.php";
require __DIR__ . "/../app/Controllers/UserController.php";
$routes = [
"GET /users" => [UserController::class, "index"],
"GET /users/create" => [UserController::class, "create"],
"POST /users" => [UserController::class, "store"],
"GET /users/edit" => [UserController::class, "edit"],
];
$method = $_SERVER["REQUEST_METHOD"];
$path = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
$route = $routes["$method $path"] ?? null;
if (!$route) { http_response_code(404); exit("Page introuvable"); }
[$class, $action] = $route;
(new $class(new User($pdo)))->$action();إلا la route ما كايناش، الزائر كيشوف 404 نقية، ماشي صفحة بيضة عامرة بالأخطاء.
الطريق كامل ديال GET /users
- le navigateur كيطلب
/users. public/index.phpكيستقبلها، و Router كيصيفطها لـUserController::index().index()كتسول ModelUserعلى المستخدمين.- Model كيدير
SELECTفـ MySQL وكيرجع النتيجة. - Controller كيعطي
$usersلـ View. - View كتبني HTML، وهو اللي كيرجع للـ navigateur.
كل واحد دار الخدمة ديالو، وما دخلش فخدمة الآخر.
والـ login ديال الدرس اللي فات؟
كيولي méthode خاصة فـ Controller، كنعيطو ليها فالبداية ديال كل صفحة محمية:
private function requireLogin(): void {
if (!isset($_SESSION["user_id"])) { // cours E09
header("Location: /login");
exit;
}
}
public function index(): void {
$this->requireLogin();
$users = $this->user->all();
$this->render("users/index", ["users" => $users]);
}شنو العلاقة مع Laravel؟
فالـ récap ديال الدرس، حطينا جوج التنظيمات حدا بعضياتهم:
| الدور | فهاد الدرس | فـ Laravel |
|---|---|---|
| Model | app/Models/User.php | app/Models/User.php |
| View | app/Views/users/ | resources/views/users/ |
| Controller | app/Controllers/ | app/Http/Controllers/ |
| Router | public/index.php | routes/web.php |
إلا فهمتي هاد النسخة اللي درناها بيدينا، Laravel غادي يبان ليك ساهل بزاف: غادي تعرف شنو كيدير الـ framework فبلاصتك.
أسئلة كيتعاودو
فين نحطو SQL فمشروع MVC؟
فـ Model، وغير تما. فالدرس، كل requête ديال CRUD ولات méthode فـ User (all، find، create، update، delete). Controller كيعيط ليهم، و View عمرها ما كتشوف $pdo.
واش خاص framework باش ندير MVC فـ PHP؟
لا. الدرس كيبني MVC كامل بـ PHP بوحدو: 3 دوسيات، فونكسيون render، و Router فشي سطور فـ public/index.php. و framework بحال Laravel كيدير نفس الأدوار أوتوماتيكيا.
شنو الفرق بين MVC و Laravel؟
MVC طريقة باش ترتب الكود؛ و Laravel framework كيطبقها وكيزيد بزاف ديال الأدوات. الفيشيات تقريبا كيتقابلو واحد بواحد: routes/web.php هو Router، app/Http/Controllers/ هما Controllers، و resources/views/ هما Views.
فين نتأكدو من الفورم: فـ Controller ولا فـ View؟
فـ Controller. la méthode store كتتأكد من l'email بـ filter_var، وإلا كان غالط كترجع الفورم مع رسالة. View غير كتعرض هاد الرسالة.
شنو خاصك تحفظ
- Model كيتكلم مع MySQL، وما كيعرفش HTML ولا
$_POST. - View كتعرض، ما فيها حتى SQL، وكتحمي المعلومات بـ
htmlspecialchars. - Controller كيستقبل الطلب، كيتأكد من المعلومات، كيعيط لـ Model، وكيختار View.
- Router كيدخل كل الطلبات من
public/index.php، وكيرد 404 نقية إلا la route ما كايناش. - هاد التنظيم هو اللي فـ Laravel و Symfony.
شوف الدرس
الدرس كامل (5 دقايق و14 ثانية، بالدارجة) فالصفحة ديالو: نظّم الكود ديالك بـ MVC (E10).
- 0:00 المقدمة: الكود spaghetti
- 0:29 الفكرة: 3 أدوار، الريسطو، والدوسيات
- 1:06 Model
- 1:51 View
- 2:30 Controller
- 3:15 Router (front controller)
- 3:59 الطريق ديال requête و requireLogin
- 4:38 Récap، Laravel والتحدي
زيد قدام
- قبل هاد الدرس: CRUD صغير بـ PHP و MySQL و PDO (E05) و login و sessions فـ PHP (E09).
- نفس التنظيم بـ JavaScript: Node.js و Express بالدارجة.
- باش تدخل لـ Laravel بلا ما تزاپي les bases: تحدي mini Laravel.
- المسار كامل: تطوير الويب Full Stack.
- تعلّم مع الذكاء الاصطناعي بلا ما تفقد يدّك: البرمجة بلا نسخ ولصق.
المصادر
Quiz: 3 أسئلة باش تتأكد
حتى حاجة ما كتصيفط: الأجوبة ديالك كيبقاو ف المتصفح ديالك.
تكتب من الدرس والنص ديالو بمساعدة أدوات الذكاء الاصطناعي، وراجعو وتأكد منو Mehdi Laraibi نهار 4 نونبر 2026.



