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

لماذا يتم إنشاء صنف طلب مخصص هنا ولا يتم إستعمال الصنف العام Request مباشرة؟ لارافيل

محمود سامي حسين

السؤال

السلام عليكم ورحمه الله وبركاته،

في  هاته المقالة تم استخدام الدالة request للتاكد او عمل validate للبيانات، وعند تطبيق نفس ما ذكر في المقالة في مشروع خاص يظهر الخطأ التالي :

lluminate\Contracts\Container\BindingResolutionException

Target class [App\Http\Requests\StoreGuestRequest] does not exist.

http://localhost/myotel/public/guests/create

فما هي ما الطريقة المستخدمة هنا ؟ ولماذا لم يستخدم Request $request مباشرة ؟

وايضا هذا السطر المفروض ان يعيد رسالة نجاح لا تظهر لدي أبدا ؟

->withSuccess('User created successfully.');

مرفق ملف المتحكم الذي قمت بانشاءه:

2.PNG

1.PNG

ClientController.php

رابط هذا التعليق
شارك على الشبكات الإجتماعية

Recommended Posts

  • 0

لعلك لم تنتبه إلى أحد الأوامر المهمة في لارافيل أثناء استعراض الأوامر التي يوفرها artisan عن طريق طباعة.

php artrisan

هذا الأمر هو:

php artisan make:request CustomRequest

إذ يتيح هذا الأمر إمكانية إنشاء صنف يرث Request ويحمل صفاته الأساسية ويوفر إماكانية تغيير أشياء من مثل قواعد التحقق Validation أو غيرها. وهو أحد الأمور التي أحب العمل بها في لارافيل. 

يقوم الأمر 

php artisan make:request CustomRequest

بإنشاء ملف CustomRequest.php داخل app\http\requests، يحمل افتراضا:

  • تابعا rules يقوم بإعادة مصفوفة بكامل قواعد التحقق validation بشأن طلبية Http 
/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    return [
       
    ];
}

تابعا authorize يقوم بتحديد ما ان كان من المسموح قبول هاته الطلبية:

/**
 * Determine if the user is authorized to make this request.
 *
 * @return bool
 */
public function authorize()
{
   
   return false;
  
}

نقوم بتضمين هذا الصنف في أحد ملفات المتحكمات كالتالي:

use App\Http\Requests\CustomRequest;

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

POST http://path.to/api/users

يستهدف التابع store من المتحكم UserController بطلبية Http، فإن هذا التابع يستقبل معاملا request من الصنف CustomRequest كالتالي:

public function store(CustomRequest $request){


}

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

public function store(CustomRequest $request){
  
   $data = $request->validated();

}

في حين أن CustomRequest هو من سيضم قواعد التحقق كالتالي:

public function rules(){
   
   return [
       'username' => 'required|max:8',
       'password' => 'required|min:10',
       'extra_data' => 'nullable',
   ];
  
}

أليست الفكرة أفضل من هذا الشكل:

public function store(Request $request){
  
   $data = $request->validate([
       'username' => 'required|max:8',
       'password' => 'required|min:10',
       'extra_data' => 'nullable',
   ]);

}

ثما ماذا لو أردنا إضافة التحقق من صلاحية المستخدم في إنشاء مورد جديد: 

public function store(Request $request){
   if(auth()->user()->is_able_to_store_user) {
       $data = $request->validate([
         'username' => 'required|max:8',
         'password' => 'required|min:10',
         'extra_data' => 'nullable',
       ]);
   }
}

تخيل أن الأمر سيمتد لتصبح حتى قراءته مزعجة.

فيما يلي مجموعة من الميزات التي تجعلك تنشئ أصناف طلببيات خاصة:

  1. كون الطلبيات تختلف فيما بينها يجعل الحاجة إلى معالجتها بشكل منفصل شيء مهم. 
  2. يقتضي فصل الطلبيات عن المتحكمات اثنين من أهم مبادئ REST لتصميم واجهات تطبيق برمجية فعالة ومميزة. مبدأ فصل المهام الذي يقتضي فصل مكونات التطبيق عن بعضها البعض، فكل صنف أو تابع يجب أن يحوي وظيفة واحدة. وفكرة أن تابعا ما يقوم هو بعملية التحقق والتوثيق والإستعلام من قواعد البيانات والرد فكرة غير محببة كثيرة ويتطلب فصل مكوناتها.. هذا وبجانب أنه يحترم أيضا مبدأ نظام الوسطاء بتوسطه بين طلبية العميل وواجهة المتحكم وعدم تركهما يتفاعلان بصفة مباشرة. 
  3. يحقق إستعمال أصناف طلبيات مخصصة الكثير من مبادئ الشيفرة النظيفة التي تجعل الشيفرة الخاصة بك قابلة للقراءة والتعديل والتخصيص على شكل واسع. 
  4. يقوم إنشاء طلبيات مخصصة بإتاحة إمكانية جعل جميع الوظائف المماثلة تستند إلى نفس قواعد التحقق والتوثيق الخاصة بطلب واحد، وذلك بدلا عن إنشاء واحد لكل منها. بمعنى، أنه لو كنا نقوم بإنشاء مستخدم جديد في التابع store الخاص بالمتحكم UserController وأيضا في التابع store للمتحكم AdminController وتابع آخر في متحكم آخر، سيصبح لدينا الكثير من الشيفرة المتشابهة والمكررة في كل منها، فسنحتاج أن نكتب قواعد التحقق لكل تابع في كل متحكم، وأن نتحقق من صلاحية الطلبية في كل تابع من كل متحكم وهكذا.. هذا بجانب أن الأمر يصبح صعب التعديل لاحقا، ماذا لو قمت بإضافة عمود جديد في قواعد البيانات وأردت تعميم قاعدة التحقق الخاصة به على كامل الطلبات؟  بدلا عن كل هذا يتيح إنشاء صنف مخصص توحيد كل تفاصيل هاته الطلبيات. وبدل أن تبدوا متحكماتك كالتالي: 
    public function update(Request $request, User $user){
        
        if(auth()->user()->is_able_to_update_user){
             $validator = Validator::make($request->all(), [
               'username' => 'required|max:8',
               'password' => 'required|min:10',
               'extra_data' => 'nullable',
             ]);
    
             if($validator->fails()) {
                 return back()->withErrors($validator);
             }else{
           
              $data = $validator->validated();
    
              $user->update($data);
            
              return back()->with('success' ,'تم !');
            }
        }else{
            return back()->with('unauthorized' ,'غير مسموح لك !');
        }
      
    }

    ستبدوا كـ:

    public function update(UpdateUserRequest $request, User $user){
        
       $user->update( $request->validated() );
            
       return back()->with('success' ,'تم !');
      
    }

    مقسمة إلى:

    // UpdateUserRequest.php 
    
    
    <?php 
    
    
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return auth()->user()->is_able_to_update_user;
    }
    
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'username' => 'required|max:8',
            'password' => 'required|min:10',
            'extra_data' => 'nullable',
        ];
    }

     

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

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

 كما يمكنك الإطلاع على التوثيق الرسمي لكامل ما يخص التحقق في لارافيل هنا.

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

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

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

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   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.

  • إعلانات

  • تابعنا على



×
×
  • أضف...