التوجيه

قواعد التوجيه الافتراضية

قاعدة التوجيه الافتراضية في Webman هي http://127.0.0.1:8787/{المتحكم}/{الإجراء}.

المتحكم الافتراضي هو app\controller\IndexController، والإجراء الافتراضي هو index.

على سبيل المثال، عند الوصول إلى:

  • http://127.0.0.1:8787 سيؤدي إلى استدعاء دالة index من فئة app\controller\IndexController
  • http://127.0.0.1:8787/foo سيؤدي إلى استدعاء دالة index من فئة app\controller\FooController
  • http://127.0.0.1:8787/foo/test سيؤدي إلى استدعاء دالة test من فئة app\controller\FooController
  • http://127.0.0.1:8787/admin/foo/test سيؤدي إلى استدعاء دالة test من فئة app\admin\controller\FooController (انظر تطبيقات متعددة)

بالإضافة إلى ذلك، بدءًا من الإصدار 1.4، يدعم Webman توجيهًا افتراضيًا أكثر تعقيدًا، على سبيل المثال:

app
├── admin
│   └── v1
│       └── v2
│           └── v3
│               └── controller
│                   └── IndexController.php
└── controller
    ├── v1
    │   └── IndexController.php
    └── v2
        └── v3
            └── IndexController.php

عند رغبتك في تغيير توجيه طلب معين، يرجى تعديل ملف التهيئة config/route.php.

إذا كنت ترغب في تعطيل التوجيه الافتراضي، أضف السطر التالي إلى آخر ملف التهيئة config/route.php:

Route::disableDefaultRoute();

توجيه Closure

أضف كود التوجيه التالي في config/route.php:

use support\Request;
Route::any('/test', function (Request $request) {
    return response('test');
});

ملاحظة
نظرًا لأن دالة الـ Closure لا تتبع أي متحكم، فإن $request->app و $request->controller و $request->action كلها ستكون سلاسل فارغة.

عند الوصول إلى العنوان http://127.0.0.1:8787/test، سيؤدي ذلك إلى إرجاع سلسلة test.

ملاحظة
يجب أن يبدأ مسار التوجيه بـ /، على سبيل المثال:

use support\Request;
// الاستخدام الخاطئ
Route::any('test', function (Request $request) {
    return response('test');
});

// الاستخدام الصحيح
Route::any('/test', function (Request $request) {
    return response('test');
});

توجيه الفئة

أضف كود التوجيه التالي في config/route.php:

Route::any('/testclass', [app\controller\IndexController::class, 'test']);

عند الوصول إلى العنوان http://127.0.0.1:8787/testclass، سيؤدي ذلك إلى إرجاع قيمة دالة test من فئة app\controller\IndexController.

معلمات التوجيه

إذا كان هناك معلمات في التوجيه، يمكن مطابقتها باستخدام {key}، وستمرر نتائج المطابقة إلى معلمات دالة المتحكم المعنية (بدءًا من المعلمة الثانية)، على سبيل المثال:

// مطابقة /user/123 /user/abc
Route::any('/user/{id}', [app\controller\UserController::class, 'get']);
namespace app\controller;
use support\Request;

class UserController
{
    public function get(Request $request, $id)
    {
        return response('تم استلام المعلمة'.$id);
    }
}

أمثلة إضافية:

use support\Request;
// مطابقة /user/123، وعدم المطابقة مع /user/abc
Route::any('/user/{id:\d+}', function (Request $request, $id) {
    return response($id);
});

// مطابقة /user/foobar، وعدم المطابقة مع /user/foo/bar
Route::any('/user/{name}', function (Request $request, $name) {
   return response($name);
});

// مطابقة /user /user/123 و /user/abc   [] تعني اختيارية
Route::any('/user[/{name}]', function (Request $request, $name = null) {
   return response($name ?? 'tom');
});

// مطابقة أي طلب يبدأ بـ /user/
Route::any('/user/[{path:.+}]', function (Request $request) {
    return $request->path();
});

// مطابقة جميع طلبات options   : يلي التعبير العادي، مما يعني قواعد التعبير العادي لهذه المعلمة
Route::options('[{path:.+}]', function () {
    return response('');
});

ملخص الاستخدام المتقدم

يتم استخدام [] في توجيه Webman بشكل أساسي للتعامل مع أجزاء المسار الاختيارية أو لمطابقة التوجيه الديناميكي، مما يتيح لك تعريف هياكل ومسارات أكثر تعقيدًا للتوجيه.

: يُستخدم لتحديد التعبير العادي.

مجموعات التوجيه

في بعض الأحيان تحتوي التوجيهات على نفس البادئات بشكل كبير، لذا يمكننا استخدام مجموعات التوجيه لتبسيط التعريف. على سبيل المثال:

Route::group('/blog', function () {
   Route::any('/create', function (Request $request) {return response('create');});
   Route::any('/edit', function (Request $request) {return response('edit');});
   Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
});

ما يعادل:

Route::any('/blog/create', function (Request $request) {return response('create');});
Route::any('/blog/edit', function (Request $request) {return response('edit');});
Route::any('/blog/view/{id}', function (Request $request, $id) {return response("view $id");});

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

Route::group('/blog', function () {
   Route::group('/v1', function () {
      Route::any('/create', function (Request $request) {return response('create');});
      Route::any('/edit', function (Request $request) {return response('edit');});
      Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
   });  
});

برامج تشغيل التوجيه

يمكننا تعيين برنامج تشغيل على توجيه معين أو مجموعة من التوجيهات.
على سبيل المثال:

Route::any('/admin', [app\admin\controller\IndexController::class, 'index'])->middleware([
    app\middleware\MiddlewareA::class,
    app\middleware\MiddlewareB::class,
]);

Route::group('/blog', function () {
   Route::any('/create', function () {return response('create');});
   Route::any('/edit', function () {return response('edit');});
   Route::any('/view/{id}', function ($request, $id) {response("view $id");});
})->middleware([
    app\middleware\MiddlewareA::class,
    app\middleware\MiddlewareB::class,
]);
# مثال على الاستخدام الخاطئ (هذا الاستخدام صالح عند استخدام webman-framework >= 1.5.7)
Route::group('/blog', function () {
   Route::group('/v1', function () {
      Route::any('/create', function (Request $request) {return response('create');});
      Route::any('/edit', function (Request $request) {return response('edit');});
      Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
   });  
})->middleware([
    app\middleware\MiddlewareA::class,
    app\middleware\MiddlewareB::class,
]);
# مثال على الاستخدام الصحيح
Route::group('/blog', function () {
   Route::group('/v1', function () {
      Route::any('/create', function (Request $request) {return response('create');});
      Route::any('/edit', function (Request $request) {return response('edit');});
      Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
   })->middleware([
        app\middleware\MiddlewareA::class,
        app\middleware\MiddlewareB::class,
    ]);  
});

توجيه مصدر البيانات

Route::resource('/test', app\controller\IndexController::class);

// تحديد توجيه مصدر البيانات
Route::resource('/test', app\controller\IndexController::class, ['index','create']);

// توجيه مصدر البيانات غير التعريفي
// مثل notify عنوان الوصول يمكن أن يكون أي توجيه /test/notify أو /test/notify/{id} كلاهما ممكن routeName هو test.notify
Route::resource('/test', app\controller\IndexController::class, ['index','create','notify']);
الفعل URI الإجراء اسم التوجيه
GET /test index test.index
GET /test/create create test.create
POST /test store test.store
GET /test/{id} show test.show
GET /test/{id}/edit edit test.edit
PUT /test/{id} update test.update
DELETE /test/{id} destroy test.destroy
PUT /test/{id}/recovery recovery test.recovery

إنشاء URL

ملاحظة
حاليًا لا يدعم إنشاء URLs من توجيهات مجموعات متداخلة.

على سبيل المثال، التوجيه:

Route::any('/blog/{id}', [app\controller\BlogController::class, 'view'])->name('blog.view');

يمكننا استخدام الطريقة التالية لإنشاء URL لهذا التوجيه.

route('blog.view', ['id' => 100]); // النتيجة ستكون /blog/100

عند استخدام URL لتوجيه في العرض، يمكنك استخدام هذه الطريقة للتأكد من أنه بغض النظر عن كيفية تغيير قاعدة التوجيه، سيقوم URL بالتوليد تلقائيًا، مما يتجنب الحاجة إلى تعديل ملفات العرض بسبب تغييرات عنوان التوجيه.

الحصول على معلومات التوجيه

من خلال كائن $request->route يمكننا الحصول على معلومات التوجيه للطلب الحالي، على سبيل المثال:

$route = $request->route; // ما يعادل $route = request()->route;
if ($route) {
    var_export($route->getPath());
    var_export($route->getMethods());
    var_export($route->getName());
    var_export($route->getMiddleware());
    var_export($route->getCallback());
    var_export($route->param());
}

ملاحظة
إذا لم يتطابق الطلب الحالي مع أي توجيه تم تكوينه في config/route.php، فإن $request->route ستكون null، مما يعني أنه عند استخدام التوجيه الافتراضي، ستكون $request->route null.

معالجة 404

عند عدم العثور على التوجيه، يتم إرجاع رمز الحالة 404 بشكل افتراضي وإخراج المحتوى المتعلق بـ 404.

إذا أراد المطور التدخل في سير العمل عند عدم العثور على التوجيه، يمكنه استخدام طريقة التوجيه الاحتياطية التي يوفرها Webman Route::fallback($callback). على سبيل المثال، تكون منطق الشيفرة أدناه إعادة التوجيه إلى الصفحة الرئيسية عند عدم العثور على التوجيه.

Route::fallback(function(){
    return redirect('/');
});

على سبيل المثال، يمكن أن تُرجع بيانات JSON عند عدم وجود التوجيه، وهذا مفيد جدًا عندما يستخدم Webman كواجهة برمجة تطبيقات.

Route::fallback(function(){
    return json(['code' => 404, 'msg' => '404 not found']);
});

إضافة برنامج تشغيل إلى 404

طلبات 404 الافتراضية لن تمر عبر أي برنامج تشغيل، إذا كنت بحاجة إلى إضافة برنامج تشغيل إلى طلبات 404، يرجى مراجعة الشيفرة التالية.

Route::fallback(function(){
    return json(['code' => 404, 'msg' => '404 not found']);
})->middleware([
    app\middleware\MiddlewareA::class,
    app\middleware\MiddlewareB::class,
]);

روابط ذات صلة صفحات 404 و 500 المخصصة

تعطيل التوجيه الافتراضي

// تعطيل التوجيه الافتراضي للمشروع الرئيسي، دون التأثير على مكونات التطبيقات
Route::disableDefaultRoute();
// تعطيل توجيه التطبيق الإداري للمشروع الرئيسي، دون التأثير على مكونات التطبيقات
Route::disableDefaultRoute('', 'admin');
// تعطيل التوجيه الافتراضي لمكون foo، دون التأثير على المشروع الرئيسي
Route::disableDefaultRoute('foo');
// تعطيل توجيه التطبيق الإداري لمكون foo، دون التأثير على المشروع الرئيسي
Route::disableDefaultRoute('foo', 'admin');
// تعطيل التوجيه الافتراضي لـ [\app\controller\IndexController::class, 'index']
Route::disableDefaultRoute([\app\controller\IndexController::class, 'index']);

تعطيل التوجيه الافتراضي بواسطة التعليقات التوضيحية

يمكننا تعطيل التوجيه الافتراضي لمتحكم معين باستخدام التعليقات التوضيحية، على سبيل المثال:

namespace app\controller;
use support\annotation\DisableDefaultRoute;

#[DisableDefaultRoute]
class IndexController
{
    public function index()
    {
        return 'index';
    }
}

بنفس الطريقة، يمكننا أيضًا تعطيل التوجيه الافتراضي لدالة معينة في المتحكم باستخدام التعليقات التوضيحية، على سبيل المثال:

namespace app\controller;
use support\annotation\DisableDefaultRoute;

class IndexController
{
    #[DisableDefaultRoute]
    public function index()
    {
        return 'index';
    }
}

واجهة التوجيه

// تعيين توجيه يطلب طريقة أي على $uri
Route::any($uri, $callback);
// تعيين توجيه طلب GET لـ $uri
Route::get($uri, $callback);
// تعيين توجيه طلب POST لـ $uri
Route::post($uri, $callback);
// تعيين توجيه طلب PUT لـ $uri
Route::put($uri, $callback);
// تعيين توجيه طلب PATCH لـ $uri
Route::patch($uri, $callback);
// تعيين توجيه طلب DELETE لـ $uri
Route::delete($uri, $callback);
// تعيين توجيه طلب HEAD لـ $uri
Route::head($uri, $callback);
// تعيين توجيه طلب OPTIONS لـ $uri
Route::options($uri, $callback);
// تعيين توجيهات عدة أنواع من الطلبات
Route::add(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'], $uri, $callback);
// مجموعات التوجيه
Route::group($path, $callback);
// توجيه مصدر البيانات
Route::resource($path, $callback, [$options]);
// تعطيل التوجيه
Route::disableDefaultRoute($plugin = '');
// التوجيه الاحتياطي، تعيين التوجيه الافتراضي كنسخة احتياطية
Route::fallback($callback, $plugin = '');
// الحصول على جميع معلومات التوجيه
Route::getRoutes();

إذا لم يكن هناك توجيه مطابق لـ uri (بما في ذلك التوجيه الافتراضي)، ولم يتم تعيين التوجيه الاحتياطي، فسيتم إرجاع 404.

ملفات تكوين متعددة للتوجيه

إذا كنت ترغب في استخدام ملفات تكوين متعددة لإدارة التوجيه، مثل تطبيقات متعددة حيث يحتوي كل تطبيق على ملف تكوين خاص به، يمكنك استخدام طريقة require لتحميل ملفات التكوين الخارجية.
على سبيل المثال في config/route.php:

<?php

// تحميل إعدادات التوجيه تحت تطبيق admin
require_once app_path('admin/config/route.php');
// تحميل إعدادات التوجيه تحت تطبيق api
require_once app_path('api/config/route.php');