في هذا الدرس 6تصفّح المواضيع
تعتمد علاقات Eloquent افتراضياً على التحميل الكسول، أي أن السجلات المرتبطة لا يتم جلبها من قاعدة البيانات إلا لحظة قراءة خاصية العلاقة فعلياً في الكود. عند الدوران على 50 مقالاً وقراءة اسم المؤلف داخل الحلقة، ينفذ الإطار استعلاماً واحداً للمقالات متبوعاً بـ 50 استعلاماً منفصلاً لكل مؤلف، مما يسبب اختناق الأداء المعروف بمشكلة N+1.
- الجلب عند الطلب (Lazy Loading): لا يتم تنفيذ استعلام العلاقة إلا عند قراءة الخاصية الديناميكية لأول مرة.
- مضاعف الاستعلامات (N+1 Queries): استعلام واحد للآباء يتبعه N استعلام داخل الحلقة لكل سجل فرعي على حدة.
- البطء الخفي في الإنتاج (Production Bottleneck): لا يظهر أثره مع 3 سجلات محلياً لكنه يبطئ الخادم بشدة عند نمو البيانات.
// Bad: Triggers 1 + N queries!
$posts = Post::all();
foreach ($posts as $post) {
$author = $post->user->name;
}
يحل التحميل المسبق مشكلة استعلامات N+1 جذرياً عبر تحديد العلاقات المطلوب جلبها مسبقاً باستخدام دالة with قبل تنفيذ الاستعلام. بدلاً من إطلاق عشرات الاستعلامات داخل الحلقة، يجمع Eloquent كافة المفاتيح الأجنبية من الاستعلام الأول ويجلب جميع السجلات المرتبطة باستعلام ثانٍ واحد فقط يستخدم جملة WHERE IN.
- ثبات عدد الاستعلامات (Constant 2 Queries): سواء عرضت 10 مقالات أو 1000 مقال مع مؤلفيها، ينفذ النظام استعلامين اثنين فقط.
- تعدد العلاقات (Multiple Relations): تقبل دالة with اسم علاقة مفردة أو مصفوفة علاقات لتحميلها معاً بكفاءة.
- انعدام استعلامات الحلقة (In-Memory Access): قراءة العلاقة داخل حلقة التكرار تتم فوراً من الذاكرة المحملة مسبقاً.
// Good: Runs only 2 queries total!
$posts = Post::with(['user', 'tags'])->get();
foreach ($posts as $post) {
$author = $post->user->name;
}
يمكنك تطبيق التحميل المسبق على العلاقات المتداخلة عبر عدة نماذج باستخدام الصيغة النقطية، مثل تحميل مؤلف المقال وملفه الشخصي معاً عبر user.profile. ولتقليل استهلاك الذاكرة بشكل أكبر، حدد الأعمدة المطلوبة فقط بعد نقطتين رأسيتين مثل user:id,name مع الالتزام الدائم بتضمين عمود المعرف الأساسي.
- التداخل بالصيغة النقطية (Dot Notation): حمّل العلاقات الفرعية المتسلسلة بسهولة عبر كتابة مسار العلاقة مفصولاً بنقطة.
- اختيار أعمدة محددة (Column Selection): حدد أسماء الأعمدة المطلوبة بعد النقطتين لتجنب جلب النصوص الطويلة غير اللازمة.
- إلزامية مفاتيح الربط (Key Requirement): احرص دائماً على تضمين عمود id ومفتاح الربط الأجنبي وإلا ستعود العلاقة فارغة.
$posts = Post::with([
'user:id,name',
'comments.author:id,name',
])->get();
عندما تحتاج لتصفية أو ترتيب السجلات داخل العلاقة المحملة مسبقاً نفسها، مرر مصفوفة ترابطية إلى دالة with يكون مفتاحها اسم العلاقة وقيمتها دالة مغلقة تخصص الاستعلام. أما إذا كان كائن النموذج الأب محملاً مسبقاً في الذاكرة، فاستخدم دالتي load أو loadMissing لتحميل علاقاته لاحقاً بكفاءة.
- تقييد التحميل المسبق (Constrained with): صفِّ أو رتب السجلات المرتبطة داخل دالة with المغلقة دون التأثير على نتائج النموذج الأب.
- التحميل اللاحق (load Method): يحمل العلاقات مسبقاً لكائن نموذج أو مجموعة نماذج موجودة بالفعل في الذاكرة.
- التحميل الذكي بدون تكرار (loadMissing): يجلب العلاقة فقط إذا لم تكن قد حُملت مسبقاً خلال دورة الطلب الحالية.
$posts = Post::with(['comments' => function ($q) {
$q->where('is_approved', true)->latest();
}])->get();
$post->loadMissing('tags');
لاكتشاف استعلامات N+1 غير المقصودة مبكراً قبل وصول الكود إلى بيئة الإنتاج، يتيح لك Laravel تعطيل التحميل الكسول كلياً عبر استدعاء Model::preventLazyLoading داخل المزود AppServiceProvider. تمرير شرط عدم كون البيئة إنتاجية يطلق استثناءً واضحاً ينبه المبرمج فوراً أثناء التطوير مع الحفاظ على استمرار عمل الموقع في الإنتاج.
- منع التحميل الكسول (preventLazyLoading): يأمر Eloquent بإطلاق استثناء تنبيهي فور محاولة قراءة علاقة لم يتم تحميلها مسبقاً.
- الربط ببيئة التطوير (Non-Production Guard): تفعيله في غير بيئة الإنتاج يكشف أخطاء الأداء للمطور فوراً دون تعطيل الزوار الفعليين.
- الوضع الصارم الشامل (Model::shouldBeStrict): يفعل منع التحميل الكسول ويمنع تجاهل الحقول غير القابلة للتعبئة بصمت.
use Illuminate\Database\Eloquent\Model;
public function boot(): void
{
Model::preventLazyLoading(
! $this->app->isProduction()
);
}
يُعد القضاء على مشكلة استعلامات N+1 عبر التحميل المسبق أهم خطوة لتحسين أداء قواعد البيانات في التطوير اليومي بتطبيقات Laravel. يضمن الجمع بين استدعاء دالة with صراحة في المتحكمات وتفعيل preventLazyLoading أثناء التطوير ثبات عدد الاستعلامات مهما تضخم حجم البيانات.
| وجه المقارنة الهندسي | الأسلوب اليدوي أو غير المحسن | معيار Laravel 12 الحديث |
|---|---|---|
| الدوران على العلاقات | قراءة اسم المؤلف مباشرة بعد Post::all مما يولد N+1 استعلاماً | التحميل المسبق عبر Post::with('user:id,name') باستعلامين فقط |
| العلاقات المتداخلة | إطلاق سلسلة استعلامات كسولة متتالية عبر ثلاثة جداول | استخدام الصيغة النقطية with('comments.author') لتحميلها معاً |
| نموذج أب محمل مسبقاً | كتابة استعلام منفصل لجلب الأبناء بمعرف الأب يدوياً | استدعاء دالة loadMissing على الكائن المحمل عند الحاجة |
| اكتشاف أخطاء الأداء | انتظار شكاوى البطء في خادم الإنتاج الحي بعد النشر | تفعيل Model::preventLazyLoading في بيئة التطوير المحلية |
$posts = Post::with(['user:id,name', 'tags'])
->withCount('comments')
->latest()
->get();
ملخص الدرس
حصاد الدرسمراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي
ماذا تعلّمت في هذا الدرس؟
أتقنت في هذا الدرس حول «التحميل المسبق وحل مشكلة استعلامات N Plus 1 في Eloquent» مفاهيم التحميل الكسول ومشكلة استعلامات N1، والتحميل المسبق للعلاقات بدالة With، والتحميل المتداخل وتحديد الأعمدة وفق معايير Laravel 12 الحديثة.
الخطوة التالية والدرس القادم
انتقل الآن إلى الدرس التالي «ربط النماذج بالمسارات وترقيم الصفحات في Eloquent» للبناء التراكمي على ما تعلمته.
سجّل الدخول لحفظ تقدمك
تابع إنجاز المواضيع والمصطلحات والمهام، وكمّل من آخر خطوة على أي جهاز.
المصطلحات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 Eager Loading التحميل المسبق
- تشخيص مشكلة الأداء N+1 Query الناتجة عن التحميل الكسول وحلها جذرياً عبر التحميل المسبق بالدالة with ومنع التحميل الكسول.
- للمراجعة
- 02 Lazy Loading and Query Bottlenecks التحميل الكسول ومشكلة استعلامات N1
- المفهوم الهندسي والتطبيق العملي المباشر لقسم التحميل الكسول ومشكلة استعلامات N1 في إطار العمل Laravel 12.
- للمراجعة
- 03 Eager Loading Relations With Method التحميل المسبق للعلاقات بدالة With
- المفهوم الهندسي والتطبيق العملي المباشر لقسم التحميل المسبق للعلاقات بدالة With في إطار العمل Laravel 12.
- للمراجعة
- 04 Nested and Specific Column Loading التحميل المتداخل وتحديد الأعمدة
- المفهوم الهندسي والتطبيق العملي المباشر لقسم التحميل المتداخل وتحديد الأعمدة في إطار العمل Laravel 12.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
الاختصارات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 MVC MVC
- Model View Controller
- النمط المعماري الذي يفصل بين نماذج البيانات Models، وطبقات العرض Views، والمتحكمات Controllers في Laravel.
- للمراجعة
- 02 CLI CLI
- Command Line Interface
- واجهة سطر الأوامر التي تعمل عبر أداة php artisan لتوليد الملفات وإدارة التطبيق.
- للمراجعة
- 03 HTTP HTTP
- Hypertext Transfer Protocol
- بروتوكول نقل النص الفائق الذي ينظم طلبات المتصفح واستجابات خادم Laravel.
- للمراجعة
- 04 PSR PSR
- PHP Standards Recommendations
- المعايير القياسية للغة PHP مثل التحميل التلقائي PSR-4 التي يلتزم بها إطار العمل Laravel.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
مهامك قبل الاختبار
خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.
-
اكتب ونفّذ المثال البرمجي المشروح في قسم «التحميل الكسول ومشكلة استعلامات N1» داخل مشروع Laravel 12 المحلي وتحقق من النتيجة.
-
بدّل بين الحالات الثلاث في المحاكي التفاعلي ضمن قسم «التحميل المسبق للعلاقات بدالة With» وقارن مخرجات التنفيذ.
تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.
اختبر فهمك.
ووصلها للإتقان.
كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.
أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.
الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.
لمحة عن التحدي8 أسئلة تنتظرك +
ما الهدف الهندسي الأساسي من التحميل الكسول ومشكلة استعلامات N1 في إطار العمل Laravel 12؟
يسهم التحميل الكسول ومشكلة استعلامات N1 في تنظيم منطق التطبيق بأسلوب معياري آمن وقابل للصيانة في Laravel 12.
يساعد الالتزام باصطلاحات Laravel 12 الرسمية في قسم «التحميل المسبق للعلاقات بدالة With» على رفع جودة الكود وسهولة اختباره آلياً.
صواب؛ الالتزام بالمعايير القياسية في Laravel 12 يجعل الكود واضحاً وسهل الفحص والصيانة.
أي آلية في Laravel 12 تتولى إدارة التحميل المتداخل وتحديد الأعمدة بشكل مباشر ومنظم؟
توفر طبقة إطار العمل وحاوية الخدمات في Laravel 12 الأدوات القياسية لإدارة التحميل المتداخل وتحديد الأعمدة.
لماذا يُعد تطبيق تقييد التحميل المسبق ودالة Load مهماً عند بناء تطبيقات Laravel 12 جاهزة للإنتاج؟
لأنه يمنع الأخطاء البرمجية الخفية ويوحد سلوك التطبيق بين بيئتي التطوير والإنتاج.
في Laravel 12، يُنصح بكتابة مفاتيح الإنتاج السرية مباشرة داخل ملفات الكود المصدري المرفوعة إلى Git بدلاً من ملفات البيئة.
خطأ؛ يجب حفظ المفاتيح والبيانات السرية في متغيرات البيئة وعدم رفعها أبداً إلى مستودع Git.
ما المزايا الهندسية التي يحققها تطبيق منع التحميل الكسول أثناء التطوير في Laravel 12؟ (اختر كل ما ينطبق)
يوفر فصلاً واضحاً للمسؤوليات، وأماناً أعلى أثناء التنفيذ، وتعاوناً أسهل بين أفراد الفريق.
يوظف إطار العمل Laravel 12 ميزات PHP 8 الحديثة مثل تحديد أنواع القيم المرجعة لجعل الكود أكثر وضوحاً وأماناً.
صواب؛ يعتمد Laravel 12 بشكل كامل على الصياغة الحديثة للغة PHP 8.2+ وسلامة الأنواع.
ما الفرق الجوهري بين معيار Laravel 12 الحديث والملفات اليدوية التقليدية في ملخص التحميل المسبق والأداء؟
يوفر Laravel 12 واجهات قياسية موحدة وحماية مدمجة تغني عن الكود اليدوي المعرض للأخطاء.