اذهب إلى المحتوى

لارافيل للمبتدئين-الجزء الأول: البدء في إنشاء مدونة بسيطة


Ola Abbas

يُعَد لارافيل Laravel إطار ويب يستخدم لغة PHP، وهو مجاني ومفتوح المصدر ويُستخدَم على نطاق واسع لتطوير تطبيقات الويب، كما أنه معروف بصيغته الأنيقة وأدواته المُستخدَمة للمهام الشائعة مثل التوجيه Routing والاستيثاق Authentication والتخزين المؤقت أو التخبئة Caching وقدرته على التعامل مع حركة الزوار العالية.

يتبع لارافيل معمارية نموذج-عرض-متحكم Model-View-Controller (أو MVC اختصارًا)، ويتضمن دعمًا مُدمجًا لربط الكائنات بالعلاقات Object-Relational Mapping (أو ORM اختصارًا) وباني الاستعلامات، مما يسهّل التفاعل مع قواعد البيانات.

يضم لارافيل مجتمعًا كبيرًا ونشطًا يوفّر مجموعةً كبيرة من البرامج التعليمية والحزم والموارد الأخرى التي يمكن للمطورين استخدامها، إذ يُعَد لارافيل أحد أطر عمل الويب الأكثر شعبية وقوة للغة PHP، وتثق به العديد من الشركات والمؤسسات لبناء تطبيقات ويب قوية وقابلة للتوسّع. سنشرح في هذا المقال الاستخدام الأساسي لإطار عمل لارافيل من خلال بناء نظام تدوين بسيط.

ملاحظة: تعتمد هذه السلسلة من المقالات على الإصدار 11 من لارافيل.

إنشاء مشروع لارافيل جديد

لا يُعَد إعداد بيئة تطوير PHP مهمة سهلة، وخاصة إذا استخدمت أنظمة لينكس Linux، ولكن قدّم لارافيل منذ الإصدار 8.0 أداة جديدة اسمها Sail، والتي توفر حلًا سهلًا لتشغيل تطبيقات لارافيل من خلال استخدام أداة دوكر Docker بغض النظر عن نظام التشغيل الذي تستخدمه، طالما أن هذه الأداة مُثبَّتة لديك.

أنشئ أولًا مجلد عمل جديد بالاسم laravel-tutorial مثلًا، ثم افتحه في محرّر الأكواد الذي تفضله وليكن VS Code، ونفّذ الأمر الآتي لإنشاء مشروع لارافيل جديد، وتأكّد من تشغيل دوكر قبل تنفيذ هذا الأمر، إذ قد تستغرق هذه العملية من 5 إلى 10 دقائق حتى الاكتمال:

curl -s https://laravel.build/<app_name> | bash

ملاحظة: إذا كنت تعمل على نظام ويندوز Windows، فتأكّد من تشغيل هذا الأمر ضمن نظام ويندوز الفرعي لنظام التشغيل لينكس WSL 2 الذي يسمح لك بتشغيل نواة Linux كاملة داخل ويندوز دون الحاجة إلى تثبيت نظام لينكس.

ثانيًا، استخدم الأمر التالي للانتقال إلى مجلد التطبيق وشغّل الخادم:

cd <app_name>

سيؤدي الأمر التالي إلى بدء حاوية دوكر بالإضافة إلى خادم تطوير لارافيل:

./vendor/bin/sail up

يمكنك الوصول إلى تطبيق لارافيل على العنوان http://localhost/‎، وإن لم يعمل هذا العنوان، فحاول الانتقال إلى العنوان http://127.0.0.1/‎ بدلًا من ذلك، ثم يجب أن تشاهد صفحة ترحيب لارافيل التالية:

صفحة-ترحيب-لارافيل

استكشاف بنية تطبيق لارافيل

لنلقِ نظرة على المجلدات والملفات التي تنشأ ضمن مشروعنا قبل أن نبدأ ببرمجته، لذا إليك نظرة عامة على المجلد الجذر للمشروع:

.
├── app
│   ├── Console
│   ├── Exceptions
│   ├── Http
│   │   ├── Controllers
│   │   └── Middleware
│   ├── Models
│   └── Providers
├── bootstrap
├── config
├── database
│   ├── factories
│   ├── migrations
│   └── seeders
├── public
├── resources
│   ├── css
│   ├── js
│   └── views
├── routes
├── storage
│   ├── app
│   ├── framework
│   └── logs
├── tests
│   ├── Feature
│   └── Unit
└── vendor
  • المجلد app: يُعَد هذا المجلد المكون الأساسي لمشروعنا، ويحتوي على مجلدات متعددة من أهمها مجلد المتحكمات controllers والبرمجيات الوسيطة middleware والنماذج models، حيث يعرّف المتحكم الشيفرة البرمجية الأساسية للتطبيق، وتعرّف البرمجيات الوسيطة الإجراءات التي يجب اتخاذها قبل استدعاء المتحكم، ويوفّر النموذج واجهة تسمح لنا بالتعامل مع قواعد البيانات، إذ سنتحدث عن كل منها بالتفصيل لاحقًا.
  • المجلد bootstrap: يحتوي هذا المجلد على الملف app.php الذي يشغّل المشروع بأكمله، ولا حاجة لتعديل أيّ شيء في هذا المجلد.
  • المجلد config: يحتوي على ملفات الضبط Configuration كما يدل اسمه، ولا حاجة للاهتمام بهذا الضبط في هذه السلسلة من المقالات.
  • المجلد database: يحتوي على ملفات التهجير migrations والمصانع factories والبذور seeds، حيث تصف ملفات التهجير بنية قاعدة البيانات، وتُعَد ملفات المصانع والبذور طريقتين مختلفتين يمكننا من خلالهما ملء قاعدة البيانات ببيانات وهمية في لارافيل.
  • المجلد public: يحتوي على الملف index.php الذي يُعَد نقطة الدخول إلى لتطبيق.
  • المجلد resources: يحتوي على ملفات العرض views التي تمثّل جزء الواجهة الأمامية من تطبيق لارافيل.
  • المجلد routes: يحتوي على جميع الموجّهات Routers لعناوين URL للمشروع فعندما ترسل طلب إلى عنوان URL محدد، سيتوجه الطلب إلى المُوجِّه المناسب بناءً على الوجهات التي تحددها الملفات ضمن هذا المجلد.
  • المجلد storage: هو مساحة تخزين المشروع بأكمله، ويحتوي على السجلات logs والعروض المُصرَّفة Compiled Views بالإضافة إلى الملفات التي رفعها المستخدم.
  • المجلد tests: يحتوي على ملفات الاختبار، حيث يُعَد الاختبار مفهومًا أكثر تقدمًا نسبيًا في لارافيل، لذلك لن نوضّحه في هذه السلسلة من المقالات، ولكن يمكنك الاطلاع على مقال كيفية استخدام PHPUnit لاختبار تطبيقات لارافيل لمزيد من التفاصيل حول الاختبارات.
  • المجلد vendor: يتضمن جميع الاعتماديات Dependencies.

متغيرات البيئة

سنلقي نظرة أيضًا على متغيرات البيئة التي تُخزَّن في ملف ‎.env، حيث أُعِدت الكثير من عمليات الضبط افتراضيًا عندما أنشأنا مشروعنا باستخدام أداة Sail في لارافيل، ولكننا سنتحدث عن عملها فيما يلي.

المتغير APP_URL

يحدّد المتغير APP_URL عنوان URL للتطبيق، ويكون هذا العنوان هو http://localhost افتراضيًا، ولكن قد تحتاج إلى تغييره إلى العنوان http://127.0.0.1 عندما يعطي العنوانُ http://127.0.0.1 صفحةَ خادم Apache2 الافتراضية.

APP_URL=http://127.0.0.1

أو:

APP_URL=http://localhost

قاعدة البيانات

ستثبّت أداة Sail من لارافيل نظامَ إدارة قواعد البيانات MySQL بوصفه التطبيق الخاص بقاعدة البيانات، وتُعرَّف اتصالات قاعدة البيانات كما يلي:

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=curl_demo
DB_USERNAME=sail
DB_PASSWORD=password

يمكنك أيضًا تعريف متغيرات بيئة خاصة بك إن احتجت إليها كما يلي، ثم يمكنك الوصول إليها في أي مكان من المشروع:

CUSTOM_VARIABLE=true

ويمكن الوصول إلى هذا المتغير كما يلي:

env('CUSTOM_VARIABLE', true)

يمثّل المعامل الثاني القيمة الافتراضية لهذا المتغير، حيث إن لم يكن المتغير CUSTOM_VARIABLE موجودًا، فسيُعاد المعامل الثاني.

أساسيات التوجيه Routing في لارافيل

سنلقي نظرة في هذا القسم على وِجهات Route لارافيل وبرمجياتها الوسيطة، حيث تُعرَّف الوِجهات في المجلد routes. لاحظ وجود أربعة ملفات مختلفة في المجلد routes افتراضيًا، ولكن ما يهمنا الملفان api.php و web.php بالنسبة لمعظم المشاريع.

إذا أردت استخدام لارافيل بطريقة صارمة مع الواجهة الخلفية (بدون العرض)، فيجب أن تحدّد الوِجهات في الملف api.php، ولكننا سنستخدم في هذا المقال لارافيل بوصفه إطار عمل متكامل full-stack، لذلك سنستخدم الملف web.php بدلًا من ذلك.

الفرق بين هذين الملفين هو أن الملف api.php تغلِّفه مجموعة برمجيات api الوسيطة وأن الملف web.php موجود ضمن مجموعة برمجيات web الوسيطة، ويوفر هذان الملفان دوالًا مختلفة، وسيكون للوِجهات المحددة في الملف api.php بادئة عنوان URL التي هي /api/، وبالتالي يجب أن يكون عنوان URL مثل العنوان: http://example.com/api/somthing-else للوصول إلى وِجهة api.

تقبل الوِجهة الأساسية في لارافيل عنوان URL ثم تعيد قيمة، حيث يمكن أن تكون هذه القيمة سلسلة نصية أو عرضًا أو متحكمًا. انتقل إلى الملف routes/web.php، وسترى أن هناك وِجهة مُعرَّفة مسبقًا هي: routes/web.php. يخبرنا الجزء التالي من الشيفرة البرمجية أنه إذا استقبل لارافيل الوِجهة "/"، فسيعيد عرضًا بالاسم "welcome"، والذي يقع في resources/views/welcome.blade.php:

use Illuminate\Support\Facades\Route;

Route::get('/', function () {
   return view('welcome');
});

افتح المتصفح، وانتقل إلى العنوان http://127.0.0.1:8000، وستحصل على الصفحة التالية:

صفحة-ترحيب-لارافيل

يمكن التحقق من أن welcome.blade.php هو العرض الظاهر من خلال إجراء بعض التغييرات على الملف، ثم تحديث متصفحك للتأكد من تغيير الصفحة.

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

لنلقِ الآن نظرة على الموجِّه التالي في routes/web.php ونفهم كيفية عمله:

use Illuminate\Support\Facades\Route;

Route::get('/', function () {
   return view('welcome');
});

نستورد أولًا الصنف Route ونستدعي التابع get()‎، حيث يتطابق هذا التابع مع تابع HTTP الذي هو GET، وهناك توابع أخرى مُضمَّنة في الصنف Route، حيث تتطابق هذه التوابع مع توابع طلبات HTTP الأخرى كما يلي:

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);

إذا أردتَ أن تطابق الوِجهة بين توابع HTTP متعددة، فيمكنك استخدام تابع match أو any بدلًا من ذلك، حيث يتطلب التابع match()‎ تحديد مصفوفة توابع HTTP التي ترغب في مطابقتها، ويطابق التابع any()‎ ببساطة بين جميع طلبات HTTP.

Route::match(['get', 'post'], '/', function () {
   . . .
});

Route::any('/', function () {
   . . .
});

تمرير البيانات إلى العرض

يحتوي التابع get()‎ على معاملَين هما: المعامل الأول هو عنوان URL الذي يُفترَض أن يطابقه الموجِّه، والمعامل الثاني هو دالة رد النداء Callback التي تُنفَّذ عند نجاح المطابقة. تُعاد الدالة view()‎ المُضمَّنة ضمن دالة رد النداء، حيث ستبحث هذه الدالة عن ملف العرض المقابل بناءً على المعامل المُمرَّر إليها.

يقدم لارافيل اختصارًا بسيطًا هو Route::view()‎ إذا أردتَ إعادة عرض فقط، حيث يسمح لك هذا التابع بتجنب كتابة وِجهة كاملة كما يلي:

Route::view('/welcome', 'welcome');

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

Route::view('/welcome', 'welcome', ['name' => 'Taylor']);

سنتحدث عن كيفية الوصول إلى البيانات عندما نصل إلى قوالب Blade.

من الموجه إلى المتحكم

يمكن أن نجعل الموجّه يؤشّر إلى المتحكم الذي يؤشّر بدوره إلى العرض، فالمتحكم هو أساسًا نسخة موسعة من دالة رد النداء، حيث سنتحدث عن المتحكمات بالتفصيل في المقال التالي. يخبرنا سطر الشيفرة البرمجية التالي أنه إذا استقبل الموجّه الوِجهة "‎/user"، فسيذهب لارافيل إلى الصنف UserController، ويستدعي التابع index:

Route::get('/user', [UserController::class, 'index']);

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

تحتاج في بعض الأحيان إلى استخدام أجزاء من عنوان URL بوصفها معاملات، فمثلًا لنفترض أن لدينا مدونة مطورة بالكامل، ويوجد مستخدم يبحث عن منشور في المدونة له الاسم Slug الموجود في الرابط this-is-a-post، ويحاول العثور على هذا المنشور من خلال كتابة http://www.example.com/posts/this-is-a-post في متصفحه.

يمكن التأكد من أن المستخدم قد عثر على المنشور الصحيح من خلال أخذ الجزء الموجود بعد posts/‎ كمعامل وإرساله إلى الواجهة الخلفية، ثم يمكن للمتحكم استخدام هذا المعامل للعثور على المنشور الصحيح وإعادته إلى المستخدم، حيث يمكنك تطبيق ذلك من خلال كتابة الشيفرة البرمجية التالية:

Route::get('post/{slug}', [PostController::class, 'show']);

سيتأكد السطر السابق من أن موجّه لارافيل يطابق الكلمة الموجودة بعد post/‎ كمعامل، ويسندها إلى المتغير slug عندما يرسلها لارافيل إلى الواجهة الخلفية. تُضمَّن معاملات الصنف Route دائمًا بين قوسين {} ويجب أن تتكون من أحرف أبجدية، ولا يجوز أن تحتوي على المحرف -.

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

Route::get('/post/{slug}', function ($slug) {
   return $slug;
});

افتح الآن متصفحك وانتقل إلى العنوان http://127.0.0.1:8000/posts/this-is-a-slug، وستظهر الصفحة التالية:

02_router-parameters.png

يمكن أيضًا مطابقة معاملات متعددة في عنوان URL كما يلي:

Route::get('category/{category}/post/{slug}', [PostController::class, 'show']);

سيُسنَد الجزء الموجود بعد category/‎ إلى المتغير category في هذه الحالة، وسيُسنَد الجزء الموجود بعد post/‎ إلى المتغير slug.

لا تعرف في بعض الأحيان ما إذا كان المعامل موجودًا في عنوان URL، وبالتالي يمكنك جعل هذا المعامل اختياريًا من خلال إلحاقه بإشارة استفهام (?) كما يلي:

Route::get('post/{slug?}', [PostController::class, 'show']);

وأخيرًا، يمكنك التحقق من صحة المعاملات باستخدام التعابير النمطية Regular Expressions، فمثلًا يمكنك التأكد من أن معرّف المستخدم هو عدد دائمًا كما يلي:

Route::get('user/{id}', [UserController::class, 'show'])->where('id', '[0-9]+');

الموجهات المسماة

تسمح الوِجهات المُسماة بإنشاء عناوين URL أو إعادة التوجيه بصورة مناسبة إلى وِجهات محددة، حيث يمكنك تحديد اسمٍ لوِجهة من خلال إضافة التابع name إلى سلسلة تعريف الوِجهة كما يلي:

Route::get('user/profile', [UserController::class, 'show'])->name('profile');

وبالتالي إذا احتجت إلى الوصول إلى عنوان URL هذا، فيجب أن تستدعي الدالة route('profile')‎ فقط.

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

إذا أردت إنشاء موقع ويب كبير، فيجب أن يكون لديك عشرات أو حتى مئات من الموجّهات، وبالتالي من المنطقي أن تجمّعها مع بعضها بعضًا، فمثلًا يمكنك تجميعها بناءً على البرمجيات الوسيطة middleware كما يلي:

Route::middleware(['auth'])->group(function () {
   Route::get('/user/profile', [UserController::class, 'show']);
   Route::get('/user/setting', [UserController::class, 'setting']);
});

وستُسنَد الآن البرمجية الوسيطة auth إلى الموجّهَين.

يمكنك أيضًا إسناد بادئات Prefixes إلى مجموعة من الموجّهات كما يلي:

Route::prefix('admin')->group(function () {
   Route::get('/users', [UserController::class, 'show']);
   . . .
});

سيكون لجميع الموجّهات المحدّدة في هذه المجموعة البادئة /admin/.

البرمجيات الوسيطة Middleware

البرمجية الوسيطة هي شيء يمكنه فحص وترشيح طلبات HTTP الواردة قبل أن تصل إلى تطبيقك، ويحدث بعد أن تطابق الوِجهة عنوان URL دون تنفيذ دالة رد النداء، وبالتالي هي شيء موجود في منطقة وسطى، ومن هنا جاءت تسميتها بالبرمجيات الوسيطة. يُعَد استيثاق المستخدم User Authentication من أمثلة البرمجيات الوسيطة، حيث إذا كان المستخدم مُستوثَقًا، فستأخذ الوِجهة هذا المستخدم إلى الهدف المفترض، وإن لم يكن الأمر كذلك، فستأخذ المستخدم إلى صفحة تسجيل الدخول أولًا.

لن نكتب أيّ برمجيات وسيطة في هذه السلسلة من المقالات، ولكن البرمجية الوسيطة الوحيدة التي نحتاج إلى استخدامها هي البرمجية الوسيطة auth المُضمَّنة لأغراض الاستيثاق، والتي سنشرح أساسياتها. ننشئ برمجية وسيطة من خلال تشغيل الأمر التالي:

php artisan make:middleware EnsureTokenIsValid

مما سيؤدي إلى إنشاء صنف EnsureTokenIsValid جديد ضمن المجلد app/Http/Middleware.

<?php

namespace App\Http\Middleware;

use Closure;

class EnsureTokenIsValid
{
   /**
    * معالجة الطلب الوارد
    *
    * @param  \Illuminate\Http\Request  $request
    * @param  \Closure  $next
    * @return mixed
    */
   public function handle($request, Closure $next)
   {
       if ($request->input('token') !== 'my-secret-token') {
           return redirect('home');
       }

       return $next($request);
   }
}

ستحصل هذه البرمجيات الوسيطة على قيمة المفتاح Token من الطلب، وتقارنها مع المفتاح السري المُخزَّن على موقعنا، حيث إذا كان مطابقًا، فانتقل إلى الخطوة التالية، وإذا لم يكن كذلك، فأعِد التوجيه إلى الصفحة الرئيسية. يمكنك استخدام هذه البرمجية الوسيطة من خلال تسجيلها في لارافيل، لذا انتقل إلى الملف app/Http/Kernel.php، وابحث عن الخاصية ‎$routeMiddleware، وأدرِج البرمجية الوسيطة التي أنشأناها.

/**
 * البرمجيات الوسيطة لوِجهات التطبيق
 *
 * يمكن إسناد هذه البرمجيات الوسيطة إلى مجموعات أو استخدامها بصورة فردية
 *
 * @var array<string, class-string|string>
**/
 protected $routeMiddleware = [
   'auth' => \App\Http\Middleware\Authenticate::class,
   'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
   'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
   'can' => \Illuminate\Auth\Middleware\Authorize::class,
   'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
   'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
   'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
   'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
   'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
 ];

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

Route::get('/profile', function () {. . .})->middleware('auth');

ترجمة -وبتصرُّف- للمقال Laravel for Beginners #1 - Getting Started لصاحبه Eric Hu.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...