بنية Laravel 11 ودورة حياة الطلب (Request Lifecycle)
1. السؤال الذي يتجاهله الجميع: ماذا يحدث بعد الضغط على Enter؟
أنت تفتح المتصفح وتكتب http://127.0.0.1:8000/articles وتضغط Enter.
ظهرت لك قائمة المقالات.
الواجهة تبدو بسيطة — لكن ما الذي حدث خلف الكواليس خلال أجزاء من الثانية؟
كثير من الطلاب يتعلمون Laravel وينجحون في بناء مشاريع دون أن يعرفوا إجابة هذا السؤال. وهذا مقبول في البداية. لكن عندما يواجهون مشكلة في الـ Middleware أو يريدون إنشاء Service Provider خاص بهم، يجدون أنفسهم تائهين. هذا الدرس يمنعك من الوقوع في هذا الموقف.
القصة القصيرة: عندما يصل طلبك إلى Laravel، يمر بـ خمس محطات رئيسية قبل أن تظهر لك الصفحة على الشاشة. لنشرحها واحدة واحدة بطريقة إنسانية لا تقنية.
2. المحطة الأولى: ملف public/index.php — الباب الوحيد
تخيّل مبنى حكومي كبير فيه عشرات الأقسام. لكن له مدخل رئيسي واحد فقط — لا يمكن لأحد الدخول إلا من خلاله. عند هذا المدخل يوجد حارس أمن يسجّل كل شخص داخل ويحوّله للقسم المناسب.
هذا بالضبط ما يفعله ملف public/index.php في Laravel.
كل طلب يصل إلى موقعك — بغض النظر عن الرابط — يمر عبر هذا الملف أولاً.
إذا طلبت /articles أو /users/5 أو /contact،
الكل يمر من هنا.
هذا الملف يفعل شيئين فقط:
-
يحمّل Composer Autoloader — وهو الملف الذي يعلّم PHP كيف تجد وتحمّل أي كلاس
في المشروع تلقائياً بدون أن تكتب
requireيدوياً في كل مكان. - يسلّم الطلب إلى نواة التطبيق (Kernel) لتبدأ عملية المعالجة الفعلية.
// 1. تحميل كل كلاسات المشروع تلقائياً
require __DIR__.'/../vendor/autoload.php';
// 2. تحميل التطبيق نفسه
$app = require_once __DIR__.'/../bootstrap/app.php';
// 3. تسليم الطلب للمعالجة وإرجاع الاستجابة
$response = $app->handleRequest(Request::capture());
$response->send();
هذا النمط يُسمى Front Controller Pattern. فائدته أن كل إعدادات الأمان والتسجيل والمعالجة الأولية تحدث في مكان واحد، مما يجعل الصيانة أسهل بكثير من وجود مئات الملفات PHP كل منها يدير نفسه.
3. المحطة الثانية: HTTP Kernel — مدير العمليات
تخيّل الـ Kernel (النواة) كمدير مطعم كبير. عندما يدخل زبون (الطلب)، المدير لا يذهب فوراً ليطبخ الطعام. أولاً يتأكد من الاستعداد الكامل للمطعم: هل الطاولات جاهزة؟ هل الطاخون حاضرون؟ هل الصحون نظيفة؟ ثم يوجّه الزبون للطاولة المناسبة.
الـ HTTP Kernel يفعل نفس الشيء — يتأكد أن التطبيق كلّه مُعدّ ومجهّز قبل معالجة الطلب:
- يحمّل ملفات الإعداد المحفوظة في مجلد
config/(قاعدة البيانات، البريد، التخزين...). - يُعدّ نظام اكتشاف الأخطاء ومعالجتها.
- يضبط المنطقة الزمنية ولغة التطبيق من ملف
.env. - يُشغّل جميع الـ Service Providers (سنشرحها في الخطوة التالية).
- يمرّر الطلب عبر قائمة الـ Middleware.
.env تلقائياً في كل مكان في الكود
دون أن تستدعيها بنفسك.
4. المحطة الثالثة: Service Providers — من يُشغّل كل شيء؟
هذا هو أكثر جزء يُربك الطلاب في Laravel. دعني أشرحه بطريقة مختلفة تماماً.
تخيّل أنك وصلت إلى مكتبك في الصباح. قبل أن تبدأ العمل، تفعل روتيناً معيناً: تفتح الكمبيوتر ← تفتح بريدك ← تفتح مشروعك ← تفتح أدوات التطوير. هذا الروتين هو ما يجعلك مستعداً للعمل.
Service Providers هي روتين الصباح لـ Laravel. كل Provider مسؤول عن "إيقاظ" جزء معين من التطبيق وجعله جاهزاً للاستخدام:
DatabaseServiceProvider— يفتح الاتصال بقاعدة البياناتMailServiceProvider— يُجهّز نظام إرسال البريد الإلكترونيAuthServiceProvider— يُحضّر نظام المصادقة والصلاحياتRouteServiceProvider— يحمّل ملفات الـ Routes
كل هذا يحدث قبل أن يصل طلبك إلى أي متحكم (Controller). عندما يصل الطلب أخيراً للكود الذي كتبته أنت، كل الأدوات التي تحتاجها جاهزة للاستخدام.
عندما تبني حزمة (Package) أو تريد تسجيل شيء في التطبيق يحتاج أن يكون "جاهزاً" دائماً عند بدء التشغيل. في المشاريع الصغيرة والمتوسطة، ستستخدم الـ Providers الموجودة ولن تحتاج لإنشاء واحد جديد.
5. المحطة الرابعة: Middleware — بوابات الفحص
تخيّل مطار فيه عدة نقاط تفتيش: أولاً تفحص بطاقة الصعود، ثم الجوازات، ثم الأمن. لا يمكنك الوصول للطائرة إلا بعد المرور من كل النقاط بالترتيب. وعند العودة، تمر من نقاط التفتيش بالاتجاه المعاكس.
Middleware في Laravel يعمل بنفس المنطق. هي طبقات تفحص الطلب قبل الوصول للـ Controller، وتفحص الاستجابة قبل إرسالها للمستخدم.
أمثلة على Middleware موجودة في كل مشروع Laravel:
- auth: يتحقق أن المستخدم سجّل دخوله قبل السماح له بالوصول. إذا لم يسجّل، يعيد توجيهه تلقائياً لصفحة Login.
- csrf: يتأكد أن الطلب جاء من النموذج الحقيقي في موقعك وليس من موقع آخر (حماية CSRF).
- throttle: يمنع أي مستخدم من إرسال أكثر من عدد معين من الطلبات في الدقيقة (حماية من هجمات Brute Force).
// هذا المسار يشترط تسجيل الدخول — سيتحقق Middleware تلقائياً
Route::get('/dashboard', [DashboardController::class, 'index'])
->middleware('auth');
// يمكن تطبيق أكثر من Middleware دفعةً واحدة
Route::get('/admin', [AdminController::class, 'index'])
->middleware(['auth', 'admin']);
6. المحطة الخامسة: Router ← Controller ← Response — الوجهة النهائية
بعد اجتياز كل نقاط الفحص، وصل الطلب أخيراً للمرحلة التي كتبتَ فيها كودك:
أولاً — Router: أين تذهب يا طلب؟
الـ Router يبحث في ملفات routes/web.php
أو routes/api.php
عن الرابط المطابق لما طلبه المستخدم.
إذا وجد المطابقة، يوجّه الطلب للكود المحدد.
إذا لم يجد — يُرجع صفحة 404 Not Found تلقائياً.
هذا الأمر يعرض لك قائمة بكل Routes المسجّلة في مشروعك — مفيد جداً للتشخيص.
ثانياً — Controller: هنا كودك يعمل
المتحكم (Controller) هو المكان الذي تكتب فيه منطق تطبيقك. هنا تجلب البيانات من قاعدة البيانات، تعالجها، وترسل النتيجة للعرض.
class ArticleController extends Controller
{
public function index()
{
// جلب كل المقالات من قاعدة البيانات
$articles = Article::latest()->get();
// إرسالها إلى صفحة العرض (View)
return view('articles.index', compact('articles'));
}
}
ثالثاً — Response: الرحلة العكسية
بعد أن ينفّذ Controller عمله، يُرجع استجابة (Response). هذه الاستجابة تسلك نفس الطريق معكوساً: تمر عبر Middleware مرة أخرى (باتجاه الخروج)، ثم يرسلها Kernel للمستخدم، وأخيراً يعرضها المتصفح على الشاشة.
Response يمكن أن تكون:
- صفحة HTML: عبر
return view('articles.index', $data); - JSON: عبر
return response()->json($data);(للـ API) - إعادة توجيه: عبر
return redirect('/home'); - ملف للتحميل: عبر
return response()->download($path);
7. الصورة الكاملة لدورة حياة الطلب في Laravel
الآن لنجمع كل ما تعلمناه في تسلسل واضح:
المتصفح يرسل طلب GET /articles
↓
public/index.php ← نقطة الدخول الوحيدة
↓
HTTP Kernel ← إعداد التطبيق والبيئة
↓
Service Providers ← تشغيل قاعدة بيانات، بريد، auth...
↓
Middleware (قبل) ← هل المستخدم مسجّل دخوله؟ هل الطلب آمن؟
↓
Router ← أي Controller يعالج هذا الرابط؟
↓
Controller ← جلب البيانات + منطق الأعمال
↓
View (Blade) ← تحويل البيانات إلى HTML
↓
Middleware (بعد) ← إضافة Headers، ضغط الاستجابة...
↓
المتصفح يعرض الصفحة ✓
8. Service Container — المفهوم الذي يخيف الجميع (لكنه بسيط)
الـ Service Container هو المفهوم الأكثر إرباكاً في Laravel للمبتدئين. لكن في الحقيقة هو بسيط جداً عرفت مثاله.
تخيّل مخزن ضخم فيه كل الأدوات التي يحتاجها التطبيق: اتصال بقاعدة البيانات، عميل بريد إلكتروني، نظام التخزين، نظام التسجيل... عوضاً عن أن تبني هذه الأدوات بنفسك في كل مكان تحتاجها، تطلب من المخزن أن يعطيك ما تحتاج وهو يجلبه تلقائياً.
في Laravel، هذا يعني أنك في الـ Controller لا تحتاج لكتابة:
// ❌ بدون Service Container — تُنشئ كل شيء يدوياً
class ArticleController extends Controller {
public function __construct() {
$db = new DatabaseConnection('host', 'user', 'pass', 'db');
$this->repo = new ArticleRepository($db);
$this->mailer = new Mailer(new SmtpTransport('host', 587));
}
}
// ✅ مع Service Container — تطلب فقط وLaravel يجلب
class ArticleController extends Controller {
public function __construct(
private ArticleRepository $repo,
private Mailer $mailer
) {
// Laravel ينشئ هذه الكائنات ويمررها تلقائياً
}
}
هذا المفهوم يُسمى Dependency Injection — ستتعامل معه بشكل تلقائي في Laravel حتى لو لم تعرف اسمه. Laravel يديره في الخلفية دون أن تضطر لإعداده بنفسك.
أسئلة شائعة عن بنية Laravel ودورة حياة الطلب
هذه أسئلة طرحها طلاب حقيقيون بعد قراءة هذا الدرس:
سؤال ذكي. المنطق المعاكس في الواقع هو الصحيح: ملف واحد = أسرع وأأمن. كل الإعداد يحدث مرة واحدة في مكان واحد. بدلاً من أن كل صفحة تحمّل إعداداتها الخاصة (مما يرفع احتمال الأخطاء والتكرار)، مشاريع PHP الكبيرة مثل Symfony وYii2 وCakePHP كلها تستخدم نفس النمط (Front Controller Pattern).
لا. يمكنك بناء مشاريع Laravel كاملة دون أن تتعمق في Service Container. الإجابة الإجمالية: تعامل معه عندما تحتاجه. ستستخدمه بشكل تلقائي عبر Type Hinting في الـ Controllers دون أن تدرك ذلك. الفهم العميق يأتي لاحقاً عند بناء Packages أو تطبيقات ضخمة.
الفرق في المسؤولية والتوقيت:
- Middleware: يعمل قبل الـ Controller. مسؤوليته الفحص والتصفية (هل المستخدم مصرّح له؟ هل الطلب صالح؟). إذا فشل الفحص — لا يصل الطلب للـ Controller أصلاً.
- Controller: يعمل بعد Middleware. مسؤوليته منطق الأعمال (جلب البيانات، المعالجة، إعداد الاستجابة).
جزئياً — نعم. مثلاً يمكنك إخراج Route معين من Middleware معين باستخدام
withoutMiddleware(). لكن الـ Kernel وService Providers
يعملان دائماً لأنهما ضروريان لتشغيل التطبيق أصلاً.
هذا التصميم يضمن أن التطبيق دائماً في حالة مُعدَّة وآمنة.
هيكل مجلدات مشروع Laravel — وظيفة كل ملف 📁
الآن تفهم كيف يتحرك الطلب داخل Laravel. الخطوة التالية: نفتح مجلد المشروع ونكتشف وظيفة كل مجلد وملف. من أين تبدأ الكتابة؟ أين تضع الصور؟ أين ملف الإعداد؟ كل هذا في الدرس القادم.
اكتشف هيكل المجلدات