الفرق بين المراجعتين لصفحة: «Laravel/controllers»
تسنيم-ولهازي (نقاش | مساهمات) |
رؤيا-بنعطية (نقاش | مساهمات) لا ملخص تعديل |
||
(12 مراجعة متوسطة بواسطة مستخدمين اثنين آخرين غير معروضة) | |||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE:وحدات التحكّم (Controllers) في Laravel}}</noinclude> | |||
== | == مقدمة == | ||
بدلًا من تعريف كامل منطق معالجة طلباتك (request handling logic) على أنّها نطاقات مغلقة (Closures | بدلًا من تعريف كامل منطق معالجة طلباتك (request handling logic) على أنّها نطاقات مغلقة ((Closures في ملفّات المسارات، قد ترغب في تنظيم هذا السلوك (behavior) باستخدام أصناف ووحدات التحكّم. تستطيع وحدات التحكّم جمع منطق معالجة الطلبات ذي الصلة في صنف واحد. تخزّن وحدات التحكّم في المجلّد <code>app/Http/Controllers</code>. | ||
== وحدات التحكّم الأساسية == | == وحدات التحكّم الأساسية == | ||
=== تعريف وحدات التحكّم === | === تعريف وحدات التحكّم === | ||
تجد أدناه مثالًا عن وحدة تحكّم بسيطة. لاحظ أن وحدة التحكّم تُوسّع صنف وحدة التحكّم الأساسية المُحتواة في Laravel. يوفّر الصنف الأساسي عددًا من التوابع المفيدة مثل التابع middleware الذي يُستخدم لإرفاق برمجيّة وسيطة بأفعال وحدة التحكّم:<syntaxhighlight lang="php"> | تجد أدناه مثالًا عن وحدة تحكّم بسيطة. لاحظ أن وحدة التحكّم تُوسّع صنف وحدة التحكّم الأساسية المُحتواة في [[Laravel]]. يوفّر الصنف الأساسي عددًا من التوابع المفيدة مثل التابع <code>middleware</code> الذي يُستخدم لإرفاق برمجيّة وسيطة بأفعال وحدة التحكّم:<syntaxhighlight lang="php"> | ||
<?php | <?php | ||
سطر 31: | سطر 31: | ||
Route::get('user/{id}', 'UserController@show'); | Route::get('user/{id}', 'UserController@show'); | ||
</syntaxhighlight>والآن عندما يطابق طلب ما رابط URI المسار المُحدّد، سيُنفّذ التابع show على الصنف UserController. ستُمرّر طبعا معاملات المسار لهذا التابع. | </syntaxhighlight>والآن عندما يطابق طلب ما رابط URI المسار المُحدّد، سيُنفّذ التابع <code>show</code> على الصنف <code>UserController</code>. ستُمرّر طبعا معاملات المسار لهذا التابع. | ||
ملاحظة: توسيع وحدات التحكّم لصنف أساسي ليس اجباريًّا. لكن في الحالة العكس، لن تتوفر لك القدرة على استخدام خاصيّات مفيدة مثل التوابع | ملاحظة: توسيع وحدات التحكّم لصنف أساسي ليس اجباريًّا. لكن في الحالة العكس، لن تتوفر لك القدرة على استخدام خاصيّات مفيدة مثل التوابع <code>middleware</code>، و <code>validate</code>، و <code>dispatch</code>. | ||
=== وحدات التحكّم ومجالات الأسماء (Controllers & Namespaces) === | |||
من المهم جدًّا ملاحظة أننا لم نحتاج لتحديد مجال اسم وحدة التحكّم (controller namespace) الكامل عندما عرّفنا مسار وحدة التحكّم. بما أن RouteServiceProvider يُحمّل ملفّات مساراتك داخل مجموعة مسارات تحتوي على مجال الاسم، لم نحدّد إلا جزء اسم الصنف الذي يأتي بعد جزء App\Http\Controllers من مجال الاسم. | من المهم جدًّا ملاحظة أننا لم نحتاج لتحديد مجال اسم وحدة التحكّم (controller namespace) الكامل عندما عرّفنا مسار وحدة التحكّم. بما أن <code>RouteServiceProvider</code> يُحمّل ملفّات مساراتك داخل مجموعة مسارات تحتوي على مجال الاسم، لم نحدّد إلا جزء اسم الصنف الذي يأتي بعد جزء <code>App\Http\Controllers</code> من مجال الاسم. | ||
إن اخترت أن تضع وحدة تحكّمك في موضع أعمق من المُجلّد App\Http\ | إن اخترت أن تضع وحدة تحكّمك في موضع أعمق من المُجلّد <code>App\Http\Controllers</code>،استخدم اسم الصنف المخصّص لمجال الاسم الجذر <code>App\Http\Controllers</code>. أي إن كان صنف وحدة تحكّمك كاملا هو <code>App\Http\Controllers\Photos\AdminController</code>، عليك أن تُسجّل المسارات المؤدّية لوحدة التحكّم كما يلي:<syntaxhighlight lang="php"> | ||
Route::get('foo', 'Photos\AdminController@method'); | Route::get('foo', 'Photos\AdminController@method'); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== وحدات التحكّم ذات الفعل الواحد (Single Action Controllers) === | === وحدات التحكّم ذات الفعل الواحد (Single Action Controllers) === | ||
في حال رغبت في تعريف وحدة تحكّم تعالج فعلًا واحدًا، تستطيع وضع تابع invoke__ وحيد عليها:<syntaxhighlight lang="php"> | في حال رغبت في تعريف وحدة تحكّم تعالج فعلًا واحدًا، تستطيع وضع تابع <code>invoke__</code> وحيد عليها:<syntaxhighlight lang="php"> | ||
<?php | <?php | ||
سطر 66: | سطر 66: | ||
Route::get('user/{id}', 'ShowProfile'); | Route::get('user/{id}', 'ShowProfile'); | ||
</syntaxhighlight>تستطيع توليد وحدة تحكّم قابلة للاستدعاء (invokable) باستخدام الخيار invokable-- من أمر Artisan make:controller:<syntaxhighlight lang="php"> | </syntaxhighlight>تستطيع توليد وحدة تحكّم قابلة للاستدعاء (invokable) باستخدام الخيار <code>invokable--</code> من أمر <code>Artisan make:controller</code>:<syntaxhighlight lang="php"> | ||
php artisan make:controller ShowProfile --invokable | php artisan make:controller ShowProfile --invokable | ||
سطر 74: | سطر 74: | ||
يمكن تعيين برمجيّة وسيطة على مسارات وحدة التحكّم في ملف مساراتك:<syntaxhighlight lang="php"> | يمكن تعيين برمجيّة وسيطة على مسارات وحدة التحكّم في ملف مساراتك:<syntaxhighlight lang="php"> | ||
Route::get('profile', 'UserController@show')->middleware('auth'); | Route::get('profile', 'UserController@show')->middleware('auth'); | ||
</syntaxhighlight>بالرغم من ذلك، يظل من المناسب أكثر تحديد البرمجيّات الوسيطة داخل التابع الباني | </syntaxhighlight>بالرغم من ذلك، يظل من المناسب أكثر تحديد البرمجيّات الوسيطة داخل التابع الباني (constructor). تستطيع تعيين البرمجيّات الوسيطة على أفعال وحدة التحكّم بسهولة باستخدام التابع <code>middleware</code> من تابع وحدة التحكّم الباني (constructor). يمكنك حتى حصر البرمجيّة الوسيطة لتوابع معيّنة من صنف وحدة التحكّم:<syntaxhighlight lang="php"> | ||
class UserController extends Controller | class UserController extends Controller | ||
{ | { | ||
سطر 92: | سطر 92: | ||
} | } | ||
</syntaxhighlight>تسمح لك وحدات التحكّم أيضًا بتسجيل البرمجيّات الوسيطة باستخدام نطاق مغلق | </syntaxhighlight>تسمح لك وحدات التحكّم أيضًا بتسجيل البرمجيّات الوسيطة باستخدام نطاق مغلق (Closure) طريقة ملائمة لتعريف برمجيّة وسيطة لوحدة تحكّم واحدة دون تعريف صنف برمجيّة وسيطة كامل:<syntaxhighlight lang="php"> | ||
$this->middleware(function ($request, $next) { | $this->middleware(function ($request, $next) { | ||
// ... | // ... | ||
سطر 102: | سطر 102: | ||
== وحدات تحكّم الموارد == | == وحدات تحكّم الموارد == | ||
يعيّن توجيه (routing) الموارد في Laravel المسارات "CRUD" المعتادة على وحدة التحكّم بسطر برمجي واحد. على سبيل المثال، قد ترغب بإنشاء وحدة تحكّم تعالج كل الطلبات HTTP للصور "photos" المخزونة بتطبيقك. نستطيع إنشاء وحدة تحكّم من هذا النوع بسرعة باستخدام أمر | يعيّن توجيه (routing) الموارد في Laravel المسارات "CRUD" المعتادة على وحدة التحكّم بسطر برمجي واحد. على سبيل المثال، قد ترغب بإنشاء وحدة تحكّم تعالج كل الطلبات HTTP للصور "photos" المخزونة بتطبيقك. نستطيع إنشاء وحدة تحكّم من هذا النوع بسرعة باستخدام أمر <code>make:controller Artisan</code>:<syntaxhighlight lang="php"> | ||
php artisan make:controller PhotoController --resource | php artisan make:controller PhotoController --resource | ||
</syntaxhighlight>يُولّد هذا الأمر وحدة تحكّم في app/Http/Controllers/PhotoController.php. ستحتوي وحدة التحكّم على تابع لكل عمليّة (operation) موارد متوفّرة. | </syntaxhighlight>يُولّد هذا الأمر وحدة تحكّم في <code>app/Http/Controllers/PhotoController.php</code>. ستحتوي وحدة التحكّم على تابع لكل عمليّة (operation) موارد متوفّرة. | ||
قد تريد في الخطوة التالية تسجيل مسار كثير الموارد | قد تريد في الخطوة التالية تسجيل مسار كثير الموارد (resourceful) لوحدة التحكّم:<syntaxhighlight lang="php"> | ||
Route::resource('photos', 'PhotoController'); | Route::resource('photos', 'PhotoController'); | ||
سطر 117: | سطر 117: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== الطرق التي تعالجها وحدة تحكّم الموارد === | |||
{| class="wikitable" | {| class="wikitable" | ||
! | !اسم المسار | ||
! | !الفعل | ||
!URI | !العنوان URI | ||
! | !الطريقة | ||
|- | |- | ||
|photos.index | |photos.index | ||
|index | |<code>index</code> | ||
|<code>/photos</code> | |<code>/photos</code> | ||
|GET | |GET | ||
|- | |- | ||
|photos.create | |photos.create | ||
|create | |<code>create</code> | ||
|<code>/photos/create</code> | |<code>/photos/create</code> | ||
|GET | |GET | ||
|- | |- | ||
|photos.store | |photos.store | ||
|store | |<code>store</code> | ||
|<code>/photos</code> | |<code>/photos</code> | ||
|POST | |POST | ||
|- | |- | ||
|photos.show | |photos.show | ||
|show | |<code>show</code> | ||
|<code>/photos/{photo | |{<code>/photos/{photo</code> | ||
|GET | |GET | ||
|- | |- | ||
|photos.edit | |photos.edit | ||
|edit | |<code>edit</code> | ||
|<code>/photos/{photo}/edit</code> | |<code>/photos/{photo}/edit</code> | ||
|GET | |GET | ||
|- | |- | ||
|photos.update | |photos.update | ||
|update | |<code>update</code> | ||
|<code>/photos/{photo | |{<code>/photos/{photo</code> | ||
|PUT/PATCH | |PUT/PATCH | ||
|- | |- | ||
|photos.destroy | |photos.destroy | ||
|destroy | |<code>destroy</code> | ||
|<code>/photos/{photo | |{<code>/photos/{photo</code> | ||
|DELETE | |DELETE | ||
|} | |} | ||
=== تحديد نموذج المورد === | |||
إذا كنت تستخدم ارتباط نموذج المسارات وترغب في جعل توابع وحدة التحكّم تُلمّح على نسخة من النموذج، تستطيع استخدام الخيار model-- عند توليد وحدة التحكّم:<syntaxhighlight lang="php"> | إذا كنت تستخدم ارتباط نموذج المسارات وترغب في جعل توابع وحدة التحكّم تُلمّح على نسخة من النموذج، تستطيع استخدام الخيار <code>model--</code> عند توليد وحدة التحكّم:<syntaxhighlight lang="php"> | ||
php artisan make:controller PhotoController --resource --model=Photo | php artisan make:controller PhotoController --resource --model=Photo | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== انتحال توابع الاستمارات (Spoofing Form Methods) === | |||
نظرًا لأن استمارات HTML لا تقدر على تقديم طلبات PUT أو PATCH أو DELETE، ستحتاج إلى إضافة حقل method_ مخفي لانتحال طرق HTTP. يمكن للتوجيه method Blade@ إنشاء هذا الحقل لك:<syntaxhighlight lang="html"> | نظرًا لأن استمارات HTML لا تقدر على تقديم طلبات PUT أو PATCH أو DELETE، ستحتاج إلى إضافة حقل <code>method_</code> مخفي لانتحال طرق HTTP. يمكن للتوجيه method Blade@ إنشاء هذا الحقل لك:<syntaxhighlight lang="html"> | ||
<form action="/foo/bar" method="POST"> | <form action="/foo/bar" method="POST"> | ||
@method('PUT') | @method('PUT') | ||
سطر 186: | سطر 186: | ||
==== مسارات موارد الواجهة البرمجيّة ==== | ==== مسارات موارد الواجهة البرمجيّة ==== | ||
نحتاج عادة عند التصريح بمسارات الموارد التي ستستهلكها الواجهات البرمجيّة إلى المسارات التي تقدم قوالب HTML مثل create و edit. لتسهيل العمليّة ، يمكنك استخدام التابع apiResource لاستبعاد هذين المسارين تلقائيًا:<syntaxhighlight lang="php"> | نحتاج عادة عند التصريح بمسارات الموارد التي ستستهلكها الواجهات البرمجيّة إلى المسارات التي تقدم قوالب HTML مثل create و edit. لتسهيل العمليّة ، يمكنك استخدام التابع <code>apiResource</code> لاستبعاد هذين المسارين تلقائيًا:<syntaxhighlight lang="php"> | ||
Route::apiResource('photos', 'PhotoController'); | Route::apiResource('photos', 'PhotoController'); | ||
</syntaxhighlight>يمكنك تسجيل العديد من وحدات تحكّم موارد الواجهة البرمجيّة مرّة واحدة من خلال تمرير مصفوفة للتابع apiResources:<syntaxhighlight lang="php"> | </syntaxhighlight>يمكنك تسجيل العديد من وحدات تحكّم موارد الواجهة البرمجيّة مرّة واحدة من خلال تمرير مصفوفة للتابع <code>apiResources</code>:<syntaxhighlight lang="php"> | ||
Route::apiResources([ | Route::apiResources([ | ||
'photos' => 'PhotoController', | 'photos' => 'PhotoController', | ||
'posts' => 'PostController' | 'posts' => 'PostController' | ||
]); | ]); | ||
</syntaxhighlight>لإنشاء وحدة تحكّم مورد واجهة برمجيّة بسرعة ولا تتضمن التابعين create أو | </syntaxhighlight>لإنشاء وحدة تحكّم مورد واجهة برمجيّة بسرعة ولا تتضمن التابعين <code>create</code> أو <code>edit</code>، استخدم المفتاح <code>api--</code> (بمعنى switch) عند تنفيذ الأمر <code>make:controller</code>:<syntaxhighlight lang="php"> | ||
php artisan make:controller API/PhotoController --api | php artisan make:controller API/PhotoController --api | ||
سطر 207: | سطر 207: | ||
=== تسمية معاملات مسارات الموارد === | === تسمية معاملات مسارات الموارد === | ||
سينشئ Route::resource معاملات (parameters) المسار لمسارات مواردك استنادًا إلى الإصدار (version) "المُفرَّد" (singularized) من اسم المورد. يمكنك إعادة تعريف هذا بسهولة لكل مورد على انفراد باستخدام التابع parameters. يجب أن تكون المصفوفة المُمرّرة للتابع parameters مصفوفةً ترابطيّةً (associative array) لأسماء المصادر وأسماء المعاملات:<syntaxhighlight lang="php"> | سينشئ <code>Route::resource</code> معاملات (parameters) المسار لمسارات مواردك استنادًا إلى الإصدار (version) "المُفرَّد" (singularized) من اسم المورد. يمكنك إعادة تعريف هذا بسهولة لكل مورد على انفراد باستخدام التابع parameters. يجب أن تكون المصفوفة المُمرّرة للتابع <code>parameters</code> مصفوفةً ترابطيّةً (associative array) لأسماء المصادر وأسماء المعاملات:<syntaxhighlight lang="php"> | ||
Route::resource('users', 'AdminUserController')->parameters([ | Route::resource('users', 'AdminUserController')->parameters([ | ||
'users' => 'admin_user' | 'users' => 'admin_user' | ||
]) | ]) | ||
</syntaxhighlight>ينشئ المثال أعلاه عناوين روابط URI التالية لمسار المورد show:<syntaxhighlight lang="php"> | </syntaxhighlight>ينشئ المثال أعلاه عناوين روابط URI التالية لمسار المورد <code>show</code>:<syntaxhighlight lang="php"> | ||
/users/{admin_user} | /users/{admin_user} | ||
سطر 217: | سطر 217: | ||
=== توطين روابط URIs الموارد === | === توطين روابط URIs الموارد === | ||
سيُنشئ Route::resource افتراضيًّا روابط URIs للموارد باستخدام أفعال (verbs) انجليزية. إذا احتجت لترجمة أفعال الإجراء | سيُنشئ <code>Route::resource</code> افتراضيًّا روابط URIs للموارد باستخدام أفعال (verbs) انجليزية. إذا احتجت لترجمة أفعال الإجراء <code>create</code> و <code>edit</code>، يمكنك استخدام التابع <code>Route::resourceVerbs</code>. يمكن القيام بذلك في التابع <code>boot</code> من <code>AppServiceProvider</code>:<syntaxhighlight lang="php"> | ||
use Illuminate\Support\Facades\Route; | use Illuminate\Support\Facades\Route; | ||
سطر 234: | سطر 234: | ||
} | } | ||
</syntaxhighlight>بمجرد أن تُخصّص الأفعال، سيُنتج تسجيل مسار مورد مثل Route::resource('fotos', 'PhotoController') العناوين URI التالية:<syntaxhighlight lang="php"> | </syntaxhighlight>بمجرد أن تُخصّص الأفعال، سيُنتج تسجيل مسار مورد مثل <code>Route::resource('fotos', 'PhotoController')</code> العناوين URI التالية:<syntaxhighlight lang="php"> | ||
/fotos/crear | /fotos/crear | ||
سطر 241: | سطر 241: | ||
=== تكملة وحدات تحكّم الموارد === | === تكملة وحدات تحكّم الموارد === | ||
إذا كنت بحاجة لإضافة مسارات لوحدة تحكّم مورد تتعدى مجموعة مسارات الموارد الافتراضية، عليك تعريف هذه المسارات قبل مناداتك Route:: | إذا كنت بحاجة لإضافة مسارات لوحدة تحكّم مورد تتعدى مجموعة مسارات الموارد الافتراضية، عليك تعريف هذه المسارات قبل مناداتك <code>Route::resource</code>؛ وإلا قد تملك المسارات المُعرّفة من طرف تابع الموارد الأولويّة على المسارات التكميليّة من غير قصد:<syntaxhighlight lang="php"> | ||
Route::get('photos/popular', 'PhotoController@method'); | Route::get('photos/popular', 'PhotoController@method'); | ||
سطر 249: | سطر 249: | ||
== إضافة الاعتماديّات ووحدات التحكّم (Dependency Injection & Controllers) == | == إضافة الاعتماديّات ووحدات التحكّم (Dependency Injection & Controllers) == | ||
=== إضافة التابع الباني Constructor === | |||
يُستخدم حاوي خدمات Laravel لاستبيان كافة وحدات تحكّم Laravel. كنتيجة، يمكنك كتابة أية اعتماديّات قد تحتاجها وحدة تحكّمك في تابعها الباني. ستُستبين الاعتماديّات المُصرّح عنها تلقائيًّا ثم تضاف لنسخة وحدة التحكّم:<syntaxhighlight lang="php"> | يُستخدم حاوي خدمات [[Laravel]] لاستبيان كافة وحدات تحكّم Laravel. كنتيجة، يمكنك كتابة أية اعتماديّات قد تحتاجها وحدة تحكّمك في تابعها الباني. ستُستبين الاعتماديّات المُصرّح عنها تلقائيًّا ثم تضاف لنسخة وحدة التحكّم:<syntaxhighlight lang="php"> | ||
<?php | <?php | ||
سطر 276: | سطر 276: | ||
} | } | ||
</syntaxhighlight>يمكنك طبعا التلميح | </syntaxhighlight>يمكنك طبعا التلميح إلى نوع (type-hint) أي [[Laravel/contracts|عقد Laravel]] إذا أمكن للحاوي استبيانه (resolve) .قد تُوفّر إضافة اعتماديّاتك لوحدة تحكّمك قدرة اختبار أفضل. | ||
=== إضافة التوابع === | |||
إضافة للتابع الباني (constructor)، تستطيع التلميح أايضا على نوع الإعتماديّات في توابع وحدة تحكّمك. إضافة النسخة Illuminate\Http\Request لتوابع وحدة تحكّمك هي حالة استخدام شائعة لإضافة التوابع:<syntaxhighlight lang="php"> | إضافة للتابع الباني (constructor)، تستطيع التلميح أايضا على نوع الإعتماديّات في توابع وحدة تحكّمك. إضافة النسخة <code>Illuminate\Http\Request</code> لتوابع وحدة تحكّمك هي حالة استخدام شائعة لإضافة التوابع:<syntaxhighlight lang="php"> | ||
<?php | <?php | ||
سطر 305: | سطر 305: | ||
Route::put('user/{id}', 'UserController@update'); | Route::put('user/{id}', 'UserController@update'); | ||
</syntaxhighlight>تظل قادرًا على التلميح | </syntaxhighlight>تظل قادرًا على التلميح إلى نوع <code>Illuminate\Http\Request</code> وعلى الوصول لمعاملتك <code>id</code> عبر تعريف وحدة تحكّمك كما يلي:<syntaxhighlight lang="php"> | ||
<?php | <?php | ||
سطر 327: | سطر 327: | ||
} | } | ||
</syntaxhighlight>'''ملاحظة''': لا يمكن تخزين المسارات المُستندة على نطاق مغلق | </syntaxhighlight>'''ملاحظة''': لا يمكن تخزين المسارات المُستندة على نطاق مغلق (Closure) مؤقتًا. لاستخدام تخزين المسار المؤقّت، عليك تحويل أي مسارات نطاق مغلق لأصناف وحدات تحكّم. | ||
إن استخدم تطبيقك المسارات المعتمدة على وحدات التحكّم حصرًا، عليك الاستفادة من ذاكرة تخزين المسار المؤقتة في Laravel. يُقلّص استخدام ذاكرة تخزين المسار المؤقتة الوقت اللازم لتسجيل جميع مسارات التطبيق بشكل جذري. قد ترتفع سرعة تسجيل مساراتك أكثر من 100 مرة في بعض الحالات. لتوليد ذاكرة تخزين مؤقتة للمسار، ما عليك إلا تنفيذ أمر Artisan route:cache:<syntaxhighlight lang="php"> | إن استخدم تطبيقك المسارات المعتمدة على وحدات التحكّم حصرًا، عليك الاستفادة من ذاكرة تخزين المسار المؤقتة في [[Laravel]]. يُقلّص استخدام ذاكرة تخزين المسار المؤقتة الوقت اللازم لتسجيل جميع مسارات التطبيق بشكل جذري. قد ترتفع سرعة تسجيل مساراتك أكثر من 100 مرة في بعض الحالات. لتوليد ذاكرة تخزين مؤقتة للمسار، ما عليك إلا تنفيذ أمر <code>Artisan route:cache</code>:<syntaxhighlight lang="php"> | ||
php artisan route:cache | php artisan route:cache | ||
</syntaxhighlight>سيُحمّل ملف مساراتك المُخزّنة بعد تنفيذ هذا الأمر مع كل طلب. تذكّر إن أضفت أي مسارات جديدة ستحتاج إلى إنشاء ذاكرة تخزين مسارات مؤقتة جديدة. لهذا السبب، يجب فقط تنفيذ الأمر route:cache عند نشر (deployment) مشروعك. | </syntaxhighlight>سيُحمّل ملف مساراتك المُخزّنة بعد تنفيذ هذا الأمر مع كل طلب. تذكّر إن أضفت أي مسارات جديدة ستحتاج إلى إنشاء ذاكرة تخزين مسارات مؤقتة جديدة. لهذا السبب، يجب فقط تنفيذ الأمر <code>route:cache</code> عند نشر (deployment) مشروعك. | ||
يُمكنك استخدام الأمر route:clear لتفريغ ذاكرة تخزين المسار المؤقّتة:<syntaxhighlight lang="php"> | يُمكنك استخدام الأمر <code>route:clear</code> لتفريغ ذاكرة تخزين المسار المؤقّتة:<syntaxhighlight lang="php"> | ||
php artisan route:clear | php artisan route:clear | ||
</syntaxhighlight> | </syntaxhighlight> | ||
= | == مصادر == | ||
* [https://laravel.com/docs/5.6/controllers صفحة Controllers في توثيق laravel الرسمي.] | * [https://laravel.com/docs/5.6/controllers صفحة Controllers في توثيق laravel الرسمي.] | ||
[[تصنيف:Laravel|{{SUBPAGENAME}}]] | |||
[[تصنيف:Laravel Basics|{{SUBPAGENAME}}]] |
المراجعة الحالية بتاريخ 14:14، 24 أكتوبر 2018
مقدمة
بدلًا من تعريف كامل منطق معالجة طلباتك (request handling logic) على أنّها نطاقات مغلقة ((Closures في ملفّات المسارات، قد ترغب في تنظيم هذا السلوك (behavior) باستخدام أصناف ووحدات التحكّم. تستطيع وحدات التحكّم جمع منطق معالجة الطلبات ذي الصلة في صنف واحد. تخزّن وحدات التحكّم في المجلّد app/Http/Controllers
.
وحدات التحكّم الأساسية
تعريف وحدات التحكّم
تجد أدناه مثالًا عن وحدة تحكّم بسيطة. لاحظ أن وحدة التحكّم تُوسّع صنف وحدة التحكّم الأساسية المُحتواة في Laravel. يوفّر الصنف الأساسي عددًا من التوابع المفيدة مثل التابع middleware
الذي يُستخدم لإرفاق برمجيّة وسيطة بأفعال وحدة التحكّم:
<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* المستخدم المعطى profile عرض
*
* @param int $id
* @return Response
*/
public function show($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
يمكنك تعريف مسار لهذه الوحدة كما يلي:
Route::get('user/{id}', 'UserController@show');
والآن عندما يطابق طلب ما رابط URI المسار المُحدّد، سيُنفّذ التابع show
على الصنف UserController
. ستُمرّر طبعا معاملات المسار لهذا التابع.
ملاحظة: توسيع وحدات التحكّم لصنف أساسي ليس اجباريًّا. لكن في الحالة العكس، لن تتوفر لك القدرة على استخدام خاصيّات مفيدة مثل التوابع middleware
، و validate
، و dispatch
.
وحدات التحكّم ومجالات الأسماء (Controllers & Namespaces)
من المهم جدًّا ملاحظة أننا لم نحتاج لتحديد مجال اسم وحدة التحكّم (controller namespace) الكامل عندما عرّفنا مسار وحدة التحكّم. بما أن RouteServiceProvider
يُحمّل ملفّات مساراتك داخل مجموعة مسارات تحتوي على مجال الاسم، لم نحدّد إلا جزء اسم الصنف الذي يأتي بعد جزء App\Http\Controllers
من مجال الاسم.
إن اخترت أن تضع وحدة تحكّمك في موضع أعمق من المُجلّد App\Http\Controllers
،استخدم اسم الصنف المخصّص لمجال الاسم الجذر App\Http\Controllers
. أي إن كان صنف وحدة تحكّمك كاملا هو App\Http\Controllers\Photos\AdminController
، عليك أن تُسجّل المسارات المؤدّية لوحدة التحكّم كما يلي:
Route::get('foo', 'Photos\AdminController@method');
وحدات التحكّم ذات الفعل الواحد (Single Action Controllers)
في حال رغبت في تعريف وحدة تحكّم تعالج فعلًا واحدًا، تستطيع وضع تابع invoke__
وحيد عليها:
<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
class ShowProfile extends Controller
{
/**
* المستخدم المعطى profile عرض *
* @param int $id
* @return Response
*/
public function __invoke($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
لا تحتاج لتحديد تابع عند تسجيل المسارات لوحدات التحكّم ذات الفعل الواحد:
Route::get('user/{id}', 'ShowProfile');
تستطيع توليد وحدة تحكّم قابلة للاستدعاء (invokable) باستخدام الخيار invokable--
من أمر Artisan make:controller
:
php artisan make:controller ShowProfile --invokable
برمجيّة وحدة تحكّم الوسيطة
يمكن تعيين برمجيّة وسيطة على مسارات وحدة التحكّم في ملف مساراتك:
Route::get('profile', 'UserController@show')->middleware('auth');
بالرغم من ذلك، يظل من المناسب أكثر تحديد البرمجيّات الوسيطة داخل التابع الباني (constructor). تستطيع تعيين البرمجيّات الوسيطة على أفعال وحدة التحكّم بسهولة باستخدام التابع middleware
من تابع وحدة التحكّم الباني (constructor). يمكنك حتى حصر البرمجيّة الوسيطة لتوابع معيّنة من صنف وحدة التحكّم:
class UserController extends Controller
{
/**
* إنشاء نسخة وحدة تحكّم جديدة
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
$this->middleware('log')->only('index');
$this->middleware('subscribed')->except('store');
}
}
تسمح لك وحدات التحكّم أيضًا بتسجيل البرمجيّات الوسيطة باستخدام نطاق مغلق (Closure) طريقة ملائمة لتعريف برمجيّة وسيطة لوحدة تحكّم واحدة دون تعريف صنف برمجيّة وسيطة كامل:
$this->middleware(function ($request, $next) {
// ...
return $next($request);
});
ملاحظة: يمكنك تعيين برمجيّة وسيطة على أجزاء من أفعال لوحدة التحكّم لكن قد ينجرّ عن ذلك تضخّم لها. خذ تقسيم وحدة تحكّمك لعدّة أجزاء أصغر بالحسبان.
وحدات تحكّم الموارد
يعيّن توجيه (routing) الموارد في Laravel المسارات "CRUD" المعتادة على وحدة التحكّم بسطر برمجي واحد. على سبيل المثال، قد ترغب بإنشاء وحدة تحكّم تعالج كل الطلبات HTTP للصور "photos" المخزونة بتطبيقك. نستطيع إنشاء وحدة تحكّم من هذا النوع بسرعة باستخدام أمر make:controller Artisan
:
php artisan make:controller PhotoController --resource
يُولّد هذا الأمر وحدة تحكّم في app/Http/Controllers/PhotoController.php
. ستحتوي وحدة التحكّم على تابع لكل عمليّة (operation) موارد متوفّرة.
قد تريد في الخطوة التالية تسجيل مسار كثير الموارد (resourceful) لوحدة التحكّم:
Route::resource('photos', 'PhotoController');
يُنشئ تصريح المسار الوحيد هذا عدّة مسارات لمعالجة أفعال متنوّعة على المورد. ستحتوي وحدة التحكّم المُولّدة على بذار (stubs) توابع لكل فعل من هذه الأفعال مع ملاحظات تعلمك بطرق HTTP (بمعنى HTTP verbs) والروابط (URIs) التي يعالجونها. قد تُسجّل عدّة وحدات تحكّم موارد مرّة واحدة بتمرير مصفوفة للتابع resources:
Route::resources([
'photos' => 'PhotoController',
'posts' => 'PostController'
]);
الطرق التي تعالجها وحدة تحكّم الموارد
اسم المسار | الفعل | العنوان URI | الطريقة |
---|---|---|---|
photos.index | index
|
/photos
|
GET |
photos.create | create
|
/photos/create
|
GET |
photos.store | store
|
/photos
|
POST |
photos.show | show
|
{/photos/{photo
|
GET |
photos.edit | edit
|
/photos/{photo}/edit
|
GET |
photos.update | update
|
{/photos/{photo
|
PUT/PATCH |
photos.destroy | destroy
|
{/photos/{photo
|
DELETE |
تحديد نموذج المورد
إذا كنت تستخدم ارتباط نموذج المسارات وترغب في جعل توابع وحدة التحكّم تُلمّح على نسخة من النموذج، تستطيع استخدام الخيار model--
عند توليد وحدة التحكّم:
php artisan make:controller PhotoController --resource --model=Photo
انتحال توابع الاستمارات (Spoofing Form Methods)
نظرًا لأن استمارات HTML لا تقدر على تقديم طلبات PUT أو PATCH أو DELETE، ستحتاج إلى إضافة حقل method_
مخفي لانتحال طرق HTTP. يمكن للتوجيه method Blade@ إنشاء هذا الحقل لك:
<form action="/foo/bar" method="POST">
@method('PUT')
</form>
مسارات الموارد الجزئية
يمكنك تحديد مجموعة فرعية من الأفعال (actions) التي يجب أن تُعالجها وحدة التحكّم بدلاً من معالجة المجموعة الكاملة من الأفعال الافتراضية عند التصريح بمسار مورد:
Route::resource('photos', 'PhotoController')->only([
'index', 'show'
]);
Route::resource('photos', 'PhotoController')->except([
'create', 'store', 'update', 'destroy'
]);
مسارات موارد الواجهة البرمجيّة
نحتاج عادة عند التصريح بمسارات الموارد التي ستستهلكها الواجهات البرمجيّة إلى المسارات التي تقدم قوالب HTML مثل create و edit. لتسهيل العمليّة ، يمكنك استخدام التابع apiResource
لاستبعاد هذين المسارين تلقائيًا:
Route::apiResource('photos', 'PhotoController');
يمكنك تسجيل العديد من وحدات تحكّم موارد الواجهة البرمجيّة مرّة واحدة من خلال تمرير مصفوفة للتابع apiResources
:
Route::apiResources([
'photos' => 'PhotoController',
'posts' => 'PostController'
]);
لإنشاء وحدة تحكّم مورد واجهة برمجيّة بسرعة ولا تتضمن التابعين create
أو edit
، استخدم المفتاح api--
(بمعنى switch) عند تنفيذ الأمر make:controller
:
php artisan make:controller API/PhotoController --api
تسمية مسارات الموارد
لكل أفعال وحدة تحكّم الموارد اسم مسار افتراضيًّا. ولكن يمكنك إعادة تعريف (override) هذه الأسماء بتمرير مصفوفة names تحتوي اختياراتك:
Route::resource('photos', 'PhotoController')->names([
'create' => 'photos.build'
]);
تسمية معاملات مسارات الموارد
سينشئ Route::resource
معاملات (parameters) المسار لمسارات مواردك استنادًا إلى الإصدار (version) "المُفرَّد" (singularized) من اسم المورد. يمكنك إعادة تعريف هذا بسهولة لكل مورد على انفراد باستخدام التابع parameters. يجب أن تكون المصفوفة المُمرّرة للتابع parameters
مصفوفةً ترابطيّةً (associative array) لأسماء المصادر وأسماء المعاملات:
Route::resource('users', 'AdminUserController')->parameters([
'users' => 'admin_user'
])
ينشئ المثال أعلاه عناوين روابط URI التالية لمسار المورد show
:
/users/{admin_user}
توطين روابط URIs الموارد
سيُنشئ Route::resource
افتراضيًّا روابط URIs للموارد باستخدام أفعال (verbs) انجليزية. إذا احتجت لترجمة أفعال الإجراء create
و edit
، يمكنك استخدام التابع Route::resourceVerbs
. يمكن القيام بذلك في التابع boot
من AppServiceProvider
:
use Illuminate\Support\Facades\Route;
/**
* مهّد أي خدمة من التطبيق (Bootstrap)
*
* @return void
*/
public function boot()
{
Route::resourceVerbs([
'create' => 'crear',
'edit' => 'editar',
]);
}
بمجرد أن تُخصّص الأفعال، سيُنتج تسجيل مسار مورد مثل Route::resource('fotos', 'PhotoController')
العناوين URI التالية:
/fotos/crear
/fotos/{foto}/editar
تكملة وحدات تحكّم الموارد
إذا كنت بحاجة لإضافة مسارات لوحدة تحكّم مورد تتعدى مجموعة مسارات الموارد الافتراضية، عليك تعريف هذه المسارات قبل مناداتك Route::resource
؛ وإلا قد تملك المسارات المُعرّفة من طرف تابع الموارد الأولويّة على المسارات التكميليّة من غير قصد:
Route::get('photos/popular', 'PhotoController@method');
Route::resource('photos', 'PhotoController');
ملاحظة: تذكّر أن تُبقي وحدات تحكّمك مُركزّة. إن وجدت نفسك في حاجة لتوابع من خارج مجموعة أفعال الموارد الاعتيادية بشكل روتيني، ضع تقسيم وحدة تحكّمك لوحدتين أصغر بالحسبان.
إضافة الاعتماديّات ووحدات التحكّم (Dependency Injection & Controllers)
إضافة التابع الباني Constructor
يُستخدم حاوي خدمات Laravel لاستبيان كافة وحدات تحكّم Laravel. كنتيجة، يمكنك كتابة أية اعتماديّات قد تحتاجها وحدة تحكّمك في تابعها الباني. ستُستبين الاعتماديّات المُصرّح عنها تلقائيًّا ثم تضاف لنسخة وحدة التحكّم:
<?php
namespace App\Http\Controllers;
use App\Repositories\UserRepository;
class UserController extends Controller
{
/**
* نسخة مستودع المُستخدم
*/
protected $users;
/**
* إنشاء نسخة وحدة تحكّم جديدة
*
* @param UserRepository $users
* @return void
*/
public function __construct(UserRepository $users)
{
$this->users = $users;
}
}
يمكنك طبعا التلميح إلى نوع (type-hint) أي عقد Laravel إذا أمكن للحاوي استبيانه (resolve) .قد تُوفّر إضافة اعتماديّاتك لوحدة تحكّمك قدرة اختبار أفضل.
إضافة التوابع
إضافة للتابع الباني (constructor)، تستطيع التلميح أايضا على نوع الإعتماديّات في توابع وحدة تحكّمك. إضافة النسخة Illuminate\Http\Request
لتوابع وحدة تحكّمك هي حالة استخدام شائعة لإضافة التوابع:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* خزّن مستخدمًا جديدًا
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
$name = $request->name;
//
}
}
إن اشترط تابع وحدة تحكّمك أيضًا إدخالًا من معاملة مسار، أورد متغيّرات مسارك الوسيطة بعد اعتماديّاتك الأخرى. على سبيل المثال، إن عُرّف مسارك بهذا الشكل:
Route::put('user/{id}', 'UserController@update');
تظل قادرًا على التلميح إلى نوع Illuminate\Http\Request
وعلى الوصول لمعاملتك id
عبر تعريف وحدة تحكّمك كما يلي:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* تحديث المُستخدم المُحدّد
*
* @param Request $request
* @param string $id
* @return Response
*/
public function update(Request $request, $id)
{
//
}
}
ملاحظة: لا يمكن تخزين المسارات المُستندة على نطاق مغلق (Closure) مؤقتًا. لاستخدام تخزين المسار المؤقّت، عليك تحويل أي مسارات نطاق مغلق لأصناف وحدات تحكّم.
إن استخدم تطبيقك المسارات المعتمدة على وحدات التحكّم حصرًا، عليك الاستفادة من ذاكرة تخزين المسار المؤقتة في Laravel. يُقلّص استخدام ذاكرة تخزين المسار المؤقتة الوقت اللازم لتسجيل جميع مسارات التطبيق بشكل جذري. قد ترتفع سرعة تسجيل مساراتك أكثر من 100 مرة في بعض الحالات. لتوليد ذاكرة تخزين مؤقتة للمسار، ما عليك إلا تنفيذ أمر Artisan route:cache
:
php artisan route:cache
سيُحمّل ملف مساراتك المُخزّنة بعد تنفيذ هذا الأمر مع كل طلب. تذكّر إن أضفت أي مسارات جديدة ستحتاج إلى إنشاء ذاكرة تخزين مسارات مؤقتة جديدة. لهذا السبب، يجب فقط تنفيذ الأمر route:cache
عند نشر (deployment) مشروعك.
يُمكنك استخدام الأمر route:clear
لتفريغ ذاكرة تخزين المسار المؤقّتة:
php artisan route:clear