الطلبات HTTP في Laravel

من موسوعة حسوب
مراجعة 13:21، 23 أكتوبر 2018 بواسطة رؤيا-بنعطية (نقاش | مساهمات) (استبدال النص - '\[\[تصنيف:(.*)\]\]' ب'{{SUBPAGENAME}}')
(فرق) → مراجعة أقدم | المراجعة الحالية (فرق) | مراجعة أحدث ← (فرق)

الوصول إلى الطلب

عليك التلميح إلى نوع الصنف Illuminate\Http\Request في وحدة تحكمّك للحصول على نسخة الطلب HTTP الحالي عبر إضافة الاعتماديّة. ستُضاف نسخة الطلب الوارد تلقائيًّا بواسطة حاوي الخدمات:

<?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->input('name');

       //
    }
}

إضافة الاعتماديّات ومعاملات المسار (Dependency Injection & Route Parameters)

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

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

تستطيع أيضًا التلميح إلى نوع الصنف Illuminate\Http\Request في النطاق المغلق Closure للمسار. سيضيف حاوي الخدمات الطلب الوارد تلقائيًا في النطاق المغلق Closure عند تنفيذه:

use Illuminate\Http\Request;

Route::get('/', function (Request $request) {
   //
});

مسار الطلب والتابع

تُوفّر النسخة Illuminate\Http\Request مجموعةً متنوعةً من الدوال لفحص الطلب HTTP لتطبيقك وتوسيع الصنف Symfony\Component\HttpFoundation\Request. سنناقش أدناه بعضًا من أهم تلك الدوال.

استرداد مسار الطلب

يعيد التابع path معلومات مسار الطلب. أي إن استهدف الطلب الوارد http://domain.com/foo/bar، سيرد التابع foo/bar path:

$uri = $request->path();

يسمح لك التابع is بالتحقق من مطابقة مسار الطلب الوارد بنمط محدد. يمكنك استخدام الرمز * كحرف بدل (wildcard) عند استخدام هذا التابع:

if ($request->is('admin/*')) {
   //
}

استرداد عنوان الطلب

تستطيع استخدام التابع url أو fullUrl لاسترداد العنوان URL الكامل للطلب الوارد. سيرد التابع url العنوان URL بدون سلسلة الاستعلام النصيّة (query string)، بينما يحتوي التابع fullUrl سلسلة الاستعلام:

// بدون سلسلة الاستعلام ...
$url = $request->url();

// مع سلسلة الاستعلام ...
$url = $request->fullUrl();

استرداد تابع الطلب

سيُعيد التابع method الطريقة HTTP للطلب. تستطيع استخدام التابع isMethod للتحقق من مطابقة الطريقة HTTP لسلسلة نصيّة معينة:

$method = $request->method();

if ($request->isMethod('post')) {
   //
}

الطلبات PSR-7

يحدّد المعيار PSR-7 واجهات الرسائل HTTP، بما في ذلك الطلبات والردود. إذا رغبت في الحصول على نسخة لطلب PSR-7 بدلاً من طلب Laravel، ستحتاج أولاً لتثبيت بضع مكتبات. يستخدم Laravel المكوّن Symfony HTTP Message Bridge لتحويل طلبات واستجابات Laravel المُعتادة إلى تعاريف استخدام متوافقة مع PSR-7:

composer require symfony/psr-http-message-bridge
composer require zendframework/zend-diactoros

يمكنك الحصول على طلب PSR-7 بمجرد تثبيتك لهذه المكتبات بالتلميح إلى نوع واجهة الطلب على مسارك (Closure) أو تابع وحدة التحكّم:

use Psr\Http\Message\ServerRequestInterface;

Route::get('/', function (ServerRequestInterface $request) {
   //
});

ملاحظة: ستُحوّل نسخة الاستجابة PSR-7 من مسار أو وحدة تحكّم، تلقائيًا إلى نسخة استجابة Laravel وسيتم عرضها بواسطة إطار العمل.

تشذيب الإدخالات والتطبيع (Input Trimming & Normalization)

يحتوي Laravel البرمجيّات الوسيطة TrimStrings و ConvertEmptyStringsToNull في مكدّس (stack) برمجيّتك الوسيطة العامة بتطبيقك افتراضيًّا. تجد قائمة هذه البرمجيّات الوسيطة في المكدّس في الصنف App\Http\Kernel. ستُشذّب هذه البرامج الوسيطة كلّ حقول السلاسل النصيّة الواردة تلقائيًا في الطلب، إضافةً لتحويل أي حقول سلسلة فارغة إلى قيمة خالية null. تريحك هذه الخاصيّة من القلق حول مشاكل التطبيع في مساراتك ووحدات تحكّمك. يمكنك إزالة البرمجيّتين الوسيطتين من مُكدّس برمجيّات تطبيقك الوسيطة عبر إزالتها من الخاصيّة middleware$  بالصنف App\Http\Kernel إذا رغبت في تعطيل هذا السلوك.

استرداد الإدخالات

استرداد جميع بيانات الإدخالات

تستطيع أيضًا استرداد جميع بيانات الإدخال كمصفوفة باستخدام التابع all:

$input = $request->all();

استرداد قيمة إدخال

باستخدام بعض الدوال البسيطة، يمكنك الوصول لكافّة إدخالات المستخدم من نسختك Illuminate\Http\Request دون القلق بشأن هويّة الطريقة HTTP المستخدمة في الطلب. يمكن استخدام التابع input لاسترداد إدخال المستخدم بغض النظر عن الطريقة HTTP:

$name = $request->input('name');

يمكنك تمرير قيمة افتراضية كمتغيّر وسيط ثاني للتابع input. ستُردُّ هذه القيمة إن لم تكن قيمة الإدخال المطلوبة موجودة في الطلب:

$name = $request->input('name', 'Sally');

استخدم التدوين "نقطة" للوصول إلى المصفوفات عند استخدام استمارات تحتوي على إدخالات مصفوفة:

$name = $request->input('products.0.name');

$names = $request->input('products.*.name');

استرداد الإدخالات من سلسلة الاستعلام النصيّة (Query string)

بينما يقوم التابع input باسترداد القيم من كامل حمولة الطلب بالكامل (بما في ذلك سلسلة الاستعلام)، يقوم التابع query باسترداد القيم من سلسلة الاستعلام فقط:

$name = $request->query('name');

سيُرد المتغيّر الوسيط الثاني لهذا التابع إن لم تكن بيانات قيمة سلسلة الاستعلام المطلوبة موجودة:

$name = $request->query('name', 'Helen');

تستطيع استدعاء التابع query دون أي متغيّرات وسيطة لاسترداد جميع قيم سلسلة الاستعلام كمصفوفة ترابطية:

$query = $request->query();

استرداد الإدخالات عبر الخاصيّات الديناميكية

تستطيع أيضًا الوصول إلى إدخال المستخدم باستخدام الخصائص الديناميكية في النسخة Illuminate\Http\Request. على سبيل المثال، إن احتوى أحد نماذج تطبيقك على حقل name، يمكنك الوصول إلى قيمة الحقل بهذه الطريقة:

$name = $request->name;

سيبحث Laravel أولاً عن قيمة المُعامل في حمولة للطلب عند استخدام الخصائص الديناميكية. إن لم يوجد، سيبحث Laravel عن الحقل في معامل المسار.

استرداد قيم إدخال JSON

عند إرسال طلبات JSON إلى تطبيقك، يمكنك الوصول إلى بيانات JSON عبر التابع input ما دامت ترويسة الطلب Content-Type معيّنة بشكل صحيح إلى application/json.

يمكنك حتى استخدام التدوين "نقطة" للتنقيب في مصفوفات JSON:

$name = $request->input('user.name');

استرداد جزء من بيانات الإدخال

إن احتجت لاسترداد مجموعة فرعية من بيانات الإدخال، يمكنك استخدام التابعين only و except. يقبل كلاهما مصفوفة واحدة أو قائمة ديناميكية من الوسائط:

$input = $request->only(['username', 'password']);

$input = $request->only('username', 'password');

$input = $request->except(['credit_card']);

$input = $request->except('credit_card');

ملاحظة: يُعيد التابع only كل أزواج المفاتيح/القيم التي تطلبها لكنها لن ترد أزواج المفاتيح/القيمة غير الموجودة في الطلب.

التأكد من وجود قيمة الإدخال

عليك استخدام التابع has على الطلب للتأكد من وجود قيمة ما. يرد التابع has القيمة true إذا كانت القيمة موجودة في الطلب:

if ($request->has('name')) {
   //
}

سيحّدد التابع has إذا كانت جميع القيم المحددة موجودة عند إعطائه مصفوفة معيّنة:

if ($request->has(['name', 'email'])) {
   //
}

إذا رغبت في تحديد ما إذا كانت القيمة غير فارغة وموجودة في الطلب، تستطيع استخدام التابع filled:

if ($request->filled('name')) {
   //
}

الإدخالات القديمة

يتيح لك Laravel الاحتفاظ بالإدخال من طلب واحد أثناء الطلب التالي. هذه الميزة مفيدة بشكل خاص في إعادة ملء الاستمارات بعد اكتشاف أخطاء عند التحقق من الصحة. لكن إن كنت تستخدم ميزات التحقق (validation features) المضمنة في Laravel فمن غير الرّاجح أن تحتاج لاستخدام هذه الأساليب يدويًا نظرًا لأن بعض وحدات التحقق المضمنة في Laravel تُناديها تلقائيًا.

توميض الإدخالات للجلسة

سيومض التابع flash في الصنف Illuminate\Http\Request الإدخال الحالي في الجلسة كي تكون متاحة أثناء طلب المستخدم التالي للتطبيق:

$request->flash();

يمكنك أيضًا استخدام التابعين flashOnly و flashExcept لتوميض مجموعة فرعية من بيانات الطلب للجلسة. هذه التوابع مفيدة في الاحتفاظ بالمعلومات الحساسة مثل كلمات المرور خارج الجلسة:

$request->flashOnly(['username', 'email']);

$request->flashExcept('password');

توميض الإدخالات ثم إعادة التوجيه

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

return redirect('form')->withInput();

return redirect('form')->withInput(
    $request->except('password')
);

استرداد المدخلات القديمة

لاسترداد الإدخال المموّض (flashed) من الطلب السابق، استخدم التابع old على النسخة Request . سيسحب التابع old بيانات الإدخال التي مُوّضت سابقًا من الجلسة:

$username = $request->old('username');

كما يوفّر Laravel مساعد old عام. من الأفضل استخدام المساعد old إن كنت تعرض المدخلات القديمة في قالب Blade. في حالة عدم وجود إدخال قديم للحقل المحدد ستُردّ قيمة null:

<input type="text" name="username" value="{{ old('username') }}">

ملفات تعريف الارتباط (Cookies)

استرداد ملفات تعريف الارتباط من الطلبات

تُشفّر جميع ملفات تعريف الارتباط التي ينشئها إطار العمل Laravel وتُوّقع بشفرة استيثاق، مما يعني اعتبارها غير صالحة إن غيّرها العميل. لاسترداد قيمة ملف تعريف الارتباط من الطلب، استخدم التابع cookie  على النسخة Illuminate\Http\Request instance:

$value = $request->cookie('name');

يمكنك استخدام الواجهة الساكنة Cookie للوصول إلى قيم ملفات تعريف الارتباط:

$value = Cookie::get('name');

إرفاق ملفات تعريف الارتباط بالردود

تستطيع إرفاق ملفات تعريف الارتباط بالنسخة Illuminate\Http\Response الصادرة باستخدام التابع cookie. يجب أن تُمرّر الاسم والقيمة وعدد الدقائق التي تُعتبر ملفات تعريف الارتباط فيها صالحة لهذا التابع:

return response('Hello World')->cookie(
    'name', 'value', $minutes
);

يقبل التابع cookie أيضًا بضع متغيّرات وسيطة أخرى تُستخدم بشكل أندر. عمومًا، لهذه المتغيّرات الوسيطة نفس الغرض والمعنى التي يُعطى للتابع setcookie المحليّة في PHP:

return response('Hello World')->cookie(
    'name', 'value', $minutes, $path, $domain, $secure, $httpOnly
);

كبديل، تستطيع استخدام الواجهة الساكنة Cookie لوضع ملفات تعريف الارتباط المعدّة ل Laravel بالاستجابة الصادرة من تطبيقك في "طابور". يقبل التابع queue نسخة Cookie أو المتغيّرات الوسيطة اللازمة لإنشاء نسخة Cookie. ستُرفق هذه الملفات بالاستجابة الصادرة قبل إرسالها إلى المتصفح:

Cookie::queue(Cookie::make('name', 'value', $minutes));

Cookie::queue('name', 'value', $minutes);

توليد نُسخ ملفات تعريف الارتباط

إن رغبت في إنشاء نسخة Symfony\Component\HttpFoundation\Cookie يمكن إعطاؤها لنسخة استجابة في وقت لاحق، تستطيع استخدام المساعد العام cookie. لن يُرسل هذا الملف للعميل ما لم تُلحق بنسخة استجابة:

$cookie = cookie('name', 'value', $minutes);

return response('Hello World')->cookie($cookie);

الملفات

استرجاع الملفات المُحمّلة

يمكنك الوصول إلى الملفات المُحمّلة عبر النسخة Illuminate\Http\Request باستخدام التابع file أو باستخدام الخصائص الديناميكية. يعيد التابع file نسخة من الصنف Illuminate\Http\UploadedFile الذي يمتد إلى الصنف PHP SplFileInfo ويوفّر مجموعة متنوعة من التوابع للتفاعل مع الملف:

$file = $request->file('photo');

$file = $request->photo;

تستطيع تحديد ما إذا كان الملف موجودًا على الطلب باستخدام التابع hasFile:

if ($request->hasFile('photo')) {
   //
}

التحقق من عمليات التحميل الناجحة

بالإضافة للتحقّق من موجود الملف، يمكنك التحقق من عدم وجود مشاكل عند تحميل الملف باستخدام التابع isValid:

if ($request->file('photo')->isValid()) {
   //
}

مسارات الملفات والإضافات

يحتوي الصنف UploadedFile أيضًا على توابع للوصول إلى مسار الملف المؤهل بالكامل (fully-qualified) وإضافته (extension). سيحاول التابع extension تخمين امتداد الملف استنادًا إلى محتوياته. قد تختلف هذه الإضافة عن الإضافة التي قدمها العميل:

$path = $request->photo->path();

$extension = $request->photo->extension();

دوال ملفات أخرى

توجد مجموعة متنوعة من التوابع الأخرى المتوفرة في النُسخ UploadedFile. ألقِ نظرةً على توثيق الواجهة البرمجية API للصنف لمزيد من المعلومات حول هذه الدوال.

تخزين الملفات المُحمّلة

لتخزين محمّل، ستستخدم عادةً أحد أنظمة الملفات التي أعددتها. يحتوي الصنف UploadedFile على تابع store ينقل الملف المُحمّل لأحد أقراصك والذي قد يكون موقعًا على نظام ملفاتك المحلي أو حتى موقع تخزين سحابي مثل Amazon S3.

يقبل التابع store المسار الذي يجب تخزين الملف فيه بالنسبة لمجلّد الجذر (root) المُعد لنظام الملفات. يجب ألّا يحتوي هذا المسار على اسم ملف، نظرًا لأن معرّفًّا فريدًا سيولّد تلقائيًا ليكون بمثابة اسم الملف.

يقبل التابع store أيضًا متغيّرًّا وسيطًا ثانيًا اختياريًّا لاسم القرص الذي يجب تخزين الملف فيه. سيُعيدّ التابع مسار الملف نسبة إلى جذر القرص:

$path = $request->photo->store('images');

$path = $request->photo->store('images', 's3');

إن لم ترغب بإنشاء اسم الملف تلقائيًا تستطيع استخدام التابع storeAs الذي يقبل المسار واسم الملف واسم القرص كوسائطه:

$path = $request->photo->storeAs('images', 'filename.jpg');

$path = $request->photo->storeAs('images', 'filename.jpg', 's3');

إعداد الخوادم الوسيطة الموثوقة

قد تلاحظ أن تطبيقك لا يقوم أحيانًا بإنشاء روابط HTTPS عند تشغيل تطبيقاتك مع مُوازن تحميل يحتوي الشهادات TLS / SSL.سبب ذلك عادة هو تلقّي تطبيقك لإعادة توجيه حركة (traffic) من موازن التحميل على المنفذ 80 دون أن يعرف أن عليه (أي تطبيقك) إنشاء ارتباطات آمنة.

لحل هذه المشكلة، تستطيع استخدام البرمجيّة الوسيطة للتطبيق App\Http\Middleware\TrustProxies المُضمّنة في تطبيق Laravel ممّا يسمح لك بتخصيص مُوازنات الحمل أو الوُكلاء التي على تطبيقك الثقة بها بسرعة. يجب إدراج وكلائك الموثوقين كمصفوفة في الخاصيّة proxies$ لهذه البرمجيّة الوسيطة. إضافةً لتهيئة بروكسيات الوُكلاء الموثوقين، تستطيع إعداد الوكيل headers$ الذي ينبغي الوثوق به:

<?php

namespace App\Http\Middleware;

use Illuminate\Http\Request;
use Fideloper\Proxy\TrustProxies as Middleware;

class TrustProxies extends Middleware
{
    /**
     * الوكلاء الموثوق بهم لهذا التطبيق.
     *
     * @var array
     */
    protected $proxies = [
        '192.168.1.1',
        '192.168.1.2',
    ];

    /**
     * الترويسات التي يجب استخدامها لاكتشاف الوكلاء.
     *
     * @var string
     */
    protected $headers = Request::HEADER_X_FORWARDED_ALL;
}

ملاحظة: إذا كنت تستخدم AWS Load Balancing، فيجب أن تكون قيمة المتغير ‎$headers هي Request::HEADER_X_FORWARDED_AWS_ELB. لمزيد من المعلومات حول الثوابت التي يمكن استخدامها في الخاصيّة ‎$headers، تحقق من توثيق Symfony حول الثقة بالوكلاء.

الوثوق بجميع الوكلاء

إذا كنت تستخدم Amazon AWS أو موفّر آخر لموازنة الحمل "cloud"، فقد لا تعرف العناوين IP لمُوَازناتك الفعلية. تستطيع في هذه الحالة استخدام * للثقة بجميع الوكلاء:

/**
 * الوكلاء الموثقين للتطبيق
 *
 * @var array
 */
protected $proxies = '*';

مصادر