إطار Laravel

أساسيات التوجيه

18 دقيقة الدرس 3 من 45

مقدمة في التوجيه

التوجيه هو الآلية التي تربط طلبات HTTP بكود محدد يتعامل مع تلك الطلبات. في لارافيل، تُعرَّف المسارات في ملفات موجودة في مجلد routes.

ما هو المسار؟ يحدد المسار كيفية استجابة تطبيقك لطلب HTTP محدد (GET، POST، PUT، DELETE، إلخ) إلى URI محدد. فكر في المسارات كنقاط الدخول إلى تطبيقك.

ملفات المسارات

يوفر لارافيل عدة ملفات مسارات لأغراض مختلفة:

  • routes/web.php - لمسارات واجهة الويب (تشمل الجلسة، حماية CSRF، تشفير الكوكيز)
  • routes/api.php - لمسارات API (بدون حالة، بدون جلسات)
  • routes/console.php - لأوامر وحدة التحكم
  • routes/channels.php - لقنوات البث

في هذا الدرس، سنركز على routes/web.php.

المسارات الأساسية

مسار GET بسيط

أبسط مسار في لارافيل يقبل URI ودالة closure:

// routes/web.php use Illuminate\Support\Facades\Route; Route::get('/', function () { return 'مرحباً بك في لارافيل!'; }); Route::get('/about', function () { return 'صفحة من نحن'; }); Route::get('/contact', function () { return 'اتصل بنا'; });

طرق التوجيه المتاحة

يوفر لارافيل طرقاً لجميع أفعال HTTP الشائعة:

Route::get($uri, $callback); // طلب GET Route::post($uri, $callback); // طلب POST Route::put($uri, $callback); // طلب PUT Route::patch($uri, $callback); // طلب PATCH Route::delete($uri, $callback); // طلب DELETE Route::options($uri, $callback); // طلب OPTIONS

أفعال HTTP متعددة

أحياناً تحتاج إلى تسجيل مسار يستجيب لأفعال HTTP متعددة:

// الاستجابة لكل من GET و POST Route::match(['get', 'post'], '/form', function () { return 'هذا المسار يتعامل مع GET و POST'; }); // الاستجابة لجميع أفعال HTTP Route::any('/any-method', function () { return 'هذا المسار يتعامل مع أي فعل HTTP'; });

إرجاع العروض

بدلاً من إرجاع السلاسل، عادةً ما تُرجع العروض:

Route::get('/home', function () { return view('home'); }); // تمرير البيانات إلى العروض Route::get('/welcome', function () { return view('welcome', [ 'name' => 'أحمد محمد', 'role' => 'مطور' ]); }); // استخدام دالة compact() Route::get('/profile', function () { $name = 'فاطمة علي'; $email = 'fatima@example.com'; return view('profile', compact('name', 'email')); });
اختصار العرض: للمسارات التي تُرجع عرضاً فقط بدون منطق، يمكنك استخدام طريقة Route::view(): Route::view('/about', 'about', ['title' => 'من نحن']);

معاملات المسار

المعاملات المطلوبة

يمكنك التقاط أجزاء من URI باستخدام معاملات المسار:

// معامل واحد Route::get('/users/{id}', function ($id) { return "معرف المستخدم: " . $id; }); // معاملات متعددة Route::get('/posts/{postId}/comments/{commentId}', function ($postId, $commentId) { return "المنشور: $postId, التعليق: $commentId"; }); // استخدام المعاملات مع العروض Route::get('/articles/{id}', function ($id) { return view('articles.show', ['articleId' => $id]); });

المعاملات الاختيارية

اجعل المعاملات اختيارية بوضع ? بعد اسم المعامل وتوفير قيمة افتراضية:

Route::get('/users/{name?}', function ($name = 'ضيف') { return "مرحباً، " . $name; }); // معاملات اختيارية متعددة Route::get('/posts/{category?}/{year?}', function ($category = 'الكل', $year = null) { if ($year) { return "المنشورات في $category من $year"; } return "جميع المنشورات في $category"; });

قيود التعبيرات النمطية

قيّد معاملات المسار باستخدام طريقة where:

// يجب أن يكون المعرف رقمياً Route::get('/users/{id}', function ($id) { return "المستخدم: $id"; })->where('id', '[0-9]+'); // يجب أن يكون الاسم أبجدياً Route::get('/users/{name}', function ($name) { return "المستخدم: $name"; })->where('name', '[a-zA-Z]+'); // قيود متعددة Route::get('/posts/{id}/{slug}', function ($id, $slug) { return "المنشور $id: $slug"; })->where(['id' => '[0-9]+', 'slug' => '[a-z-]+']); // استخدام طرق المساعدة Route::get('/users/{id}', function ($id) { return "المستخدم: $id"; })->whereNumber('id'); Route::get('/users/{name}', function ($name) { return "المستخدم: $name"; })->whereAlpha('name'); Route::get('/posts/{slug}', function ($slug) { return "المنشور: $slug"; })->whereAlphaNumeric('slug'); Route::get('/search/{term}', function ($term) { return "البحث عن: $term"; })->whereIn('term', ['users', 'posts', 'comments']);
مهم: إذا لم يتطابق معامل المسار مع قيده، سيُرجع لارافيل استجابة 404 Not Found تلقائياً.

المسارات المسماة

تتيح لك المسارات المسماة إنشاء عناوين URL أو عمليات إعادة توجيه لمسارات محددة دون تضمين URI بشكل ثابت:

تعريف المسارات المسماة

Route::get('/dashboard', function () { return view('dashboard'); })->name('dashboard'); Route::get('/user/profile', function () { return view('profile'); })->name('profile'); Route::get('/posts/{id}', function ($id) { return view('posts.show', compact('id')); })->name('posts.show');

إنشاء عناوين URL للمسارات المسماة

// في المتحكمات أو العروض $url = route('dashboard'); // تُرجع: http://yourapp.com/dashboard $url = route('posts.show', ['id' => 5]); // تُرجع: http://yourapp.com/posts/5 // مع معاملات الاستعلام $url = route('posts.show', ['id' => 5, 'highlight' => 'comment-42']); // تُرجع: http://yourapp.com/posts/5?highlight=comment-42

إعادة التوجيه إلى المسارات المسماة

// إعادة التوجيه إلى مسار مسمى return redirect()->route('dashboard'); // مع المعاملات return redirect()->route('posts.show', ['id' => 5]); // مع بيانات flash return redirect() ->route('dashboard') ->with('status', 'تم تحديث الملف الشخصي!');

استخدام المسارات المسماة في قوالب Blade

<!-- رابط بسيط --> <a href="{{ route('dashboard') }}">لوحة التحكم</a> <!-- مع المعاملات --> <a href="{{ route('posts.show', ['id' => $post->id]) }}"> عرض المنشور </a> <!-- إجراء النموذج --> <form action="{{ route('posts.store') }}" method="POST"> @csrf <!-- حقول النموذج --> </form>
أفضل ممارسة: استخدم دائماً المسارات المسماة بدلاً من تضمين عناوين URL بشكل ثابت. هذا يجعل تطبيقك أكثر قابلية للصيانة ويسمح لك بتغيير URIs دون كسر الروابط في تطبيقك.

مجموعات المسارات

تسمح لك مجموعات المسارات بمشاركة السمات عبر عدة مسارات:

مجموعات البادئة

// جميع المسارات ستحتوي على بادئة /admin Route::prefix('admin')->group(function () { Route::get('/users', function () { // يطابق: /admin/users }); Route::get('/posts', function () { // يطابق: /admin/posts }); });

بادئة الاسم

Route::name('admin.')->group(function () { Route::get('/admin/users', function () { // المسار المسمى: admin.users })->name('users'); Route::get('/admin/posts', function () { // المسار المسمى: admin.posts })->name('posts'); });

مجموعات الوسيطات

Route::middleware(['auth', 'verified'])->group(function () { Route::get('/dashboard', function () { // يمكن الوصول إليه فقط للمستخدمين المصادق عليهم والمتحققين }); Route::get('/profile', function () { // يتطلب أيضاً auth و verified }); });

دمج سمات المجموعة

Route::prefix('admin') ->name('admin.') ->middleware('auth') ->group(function () { Route::get('/dashboard', function () { // URI: /admin/dashboard // الاسم: admin.dashboard // الوسيطة: auth })->name('dashboard'); Route::get('/users', function () { // URI: /admin/users // الاسم: admin.users // الوسيطة: auth })->name('users'); });

ربط نموذج المسار

يوفر ربط نموذج المسار حقناً تلقائياً لنسخ النموذج في مساراتك:

الربط الضمني

يحل لارافيل تلقائياً نماذج Eloquent المحددة في المسارات أو المتحكمات:

use App\Models\Post; // حقن النموذج التلقائي Route::get('/posts/{post}', function (Post $post) { // يتم تحميل $post تلقائياً بناءً على المعرف في URL return view('posts.show', compact('post')); }); // إذا لم يكن المنشور بالمعرف المعطى موجوداً، يُرجع لارافيل 404

مفتاح مخصص للربط

افتراضياً، يستخدم لارافيل عمود id. يمكنك استخدام عمود مختلف:

// في نموذج Post الخاص بك (app/Models/Post.php) public function getRouteKeyName() { return 'slug'; // استخدم slug بدلاً من id } // الآن يستخدم هذا المسار slug Route::get('/posts/{post}', function (Post $post) { // يحل بواسطة slug: /posts/my-first-post return view('posts.show', compact('post')); }); // أو حدد لكل مسار Route::get('/posts/{post:slug}', function (Post $post) { return view('posts.show', compact('post')); });

الربط الصريح

حدد منطق الحل المخصص في RouteServiceProvider:

// app/Providers/RouteServiceProvider.php use App\Models\Post; use Illuminate\Support\Facades\Route; public function boot() { Route::bind('post', function ($value) { return Post::where('slug', $value) ->where('published', true) ->firstOrFail(); }); }

مسارات الموارد

تعيّن مسارات الموارد مسارات CRUD إلى متحكم بسطر واحد:

use App\Http\Controllers\PostController; // ينشئ 7 مسارات لعمليات CRUD النموذجية Route::resource('posts', PostController::class);

المسارات التي تم إنشاؤها بواسطة Resource

GET /posts index posts.index GET /posts/create create posts.create POST /posts store posts.store GET /posts/{post} show posts.show GET /posts/{post}/edit edit posts.edit PUT/PATCH /posts/{post} update posts.update DELETE /posts/{post} destroy posts.destroy

مسارات موارد جزئية

// إنشاء المسارات المحددة فقط Route::resource('posts', PostController::class)->only([ 'index', 'show' ]); // إنشاء جميع المسارات باستثناء المحددة Route::resource('posts', PostController::class)->except([ 'create', 'store', 'destroy' ]);

مسارات موارد API

موارد API تستثني مسارات create وedit (التي تعرض نماذج HTML):

Route::apiResource('posts', PostController::class); // ينشئ: index, store, show, update, destroy

الموارد المتداخلة

// المنشورات لديها العديد من التعليقات Route::resource('posts.comments', CommentController::class); // ينشئ مسارات مثل: // GET /posts/{post}/comments // POST /posts/{post}/comments // GET /posts/{post}/comments/{comment} // إلخ

تمرين عملي 1: المسارات الأساسية

أنشئ المسارات التالية في ملف routes/web.php الخاص بك:

  1. مسار GET لـ /services يُرجع عرضاً يسمى 'services'
  2. مسار GET لـ /pricing يُرجع النص "صفحة التسعير"
  3. مسار GET لـ /blog يُرجع عرضاً مع البيانات: ['posts' => 25]
  4. اختبر جميع المسارات بزيارتها في متصفحك

تمرين عملي 2: معاملات المسار

أنشئ هذه المسارات مع المعاملات:

  1. مسار /products/{id} حيث يجب أن يكون id رقمياً
  2. مسار /categories/{name?} مع معامل اختياري (افتراضي: 'الكل')
  3. مسار /search/{term}/{category?} مع معامل مطلوب واحد وآخر اختياري
  4. أضف قيوداً مناسبة لضمان أنواع البيانات

تمرين عملي 3: المسارات المسماة والمجموعات

تدرب على مجموعات المسارات:

  1. أنشئ مجموعة مسارات مع بادئة 'admin' تحتوي على 3 مسارات (dashboard، users، settings)
  2. امنح كل مسار اسماً مع بادئة 'admin.'
  3. أنشئ عناوين URL لهذه المسارات المسماة باستخدام دالة route()
  4. أنشئ قالب Blade مع روابط باستخدام المسارات المسماة

عرض جميع المسارات

يوفر لارافيل أمراً مفيداً لعرض جميع المسارات المسجلة:

# عرض جميع المسارات php artisan route:list # عرض المسارات مع الوسيطات php artisan route:list -v # تصفية حسب الاسم php artisan route:list --name=admin # تصفية حسب URI php artisan route:list --path=posts # إظهار المسارات بتنسيق مضغوط php artisan route:list --compact

التخزين المؤقت للمسارات

لأداء الإنتاج، قم بتخزين مساراتك مؤقتاً:

# تخزين المسارات مؤقتاً (تسجيل مسار أسرع) php artisan route:cache # مسح ذاكرة التخزين المؤقت للمسارات php artisan route:clear
قيد التخزين المؤقت: لا يعمل التخزين المؤقت للمسارات مع المسارات القائمة على closure. إذا كنت تستخدم التخزين المؤقت للمسارات، يجب عليك تحويل جميع مسارات closure إلى طرق متحكم.

الملخص

في هذا الدرس، تعلمت:

  • كيفية تعريف المسارات الأساسية مع أفعال HTTP المختلفة
  • العمل مع معاملات المسار (مطلوبة، اختيارية، مع قيود)
  • إنشاء واستخدام المسارات المسماة لعناوين URL قابلة للصيانة
  • تنظيم المسارات مع مجموعات المسارات والبادئات
  • تطبيق ربط نموذج المسار للحقن التلقائي للنموذج
  • استخدام مسارات الموارد لعمليات CRUD RESTful
  • عرض المسارات وتخزينها مؤقتاً لأداء أفضل

التوجيه هو أساس تطبيق لارافيل الخاص بك. في الدرس التالي، سنتعلم كيفية إنشاء متحكمات للتعامل مع منطق هذه المسارات!