استخدام Eloquent ORM للتعامل مع قاعدة البيانات في Laravel 5


محمد أحمد العيل

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

هذا الدرس جزء من سلسلة تعلم Laravel والتي تنتهج مبدأ "أفضل وسيلة للتعلم هي الممارسة"، حيث ستكون ممارستنا عبارة عن إنشاء تطبيق ويب للتسوق مع ميزة سلة المشتريات. يتكون فهرس السلسلة من التالي:

laravel5-eloquent-orm_(2).thumb.png.cd53

سنغطي في هذا الدرس المواضيع التالية:

  • نماذج Eloquent
    • أعراف التسمية.
    • أسماء الجداول والمفاتيح الخارجية.
    • الأختام الزمنية.
  • إطار العمل Eloquent
    • قراءة البيانات READ.
    • تحديث البيانات UPDATE.
    • حذف البيانات DELETE.
    • إدراج البيانات INSERT.
  • تنفيذ استعلامات SQL في Laravel.
  • نماذج Eloquent لمشروع Larashop.
    • استخدام النماذج في المتحكمات.
    • إظهار بيانات النماذج في العروض.

إطار عمل Eloquent

يأتي Laravel مضمنًّا بإطار عمل Eloquent الذي يُستخدَم للتخاطب مع قاعدة البيانات وتنفيذ عمليات مثل الإدراج Insert، التحديث Update أو الحذف Delete على الجداول. Eloquent هو إطار عمل لربط كائنات التطبيق بعلاقات (جداول) قاعدة البيانات Object Relational Mapper, ORM.

يقوم مبدأ ربط العلاقات بالكائنات على تنفيذ نمط ActiveRecord (التسجيلة النشطة)؛ الذي هو وسيلة للوصول إلى البيانات في قاعدة البيانات، حيث يضمن جدول بيانات (أو علاقة في قاعدة البيانات بصفة عامة) في صنف Class وتُربط كل تسجيلة من جدول البيانات بكائن Object من الصنف. بهذه الطريقة يُصبح التعامل مع الصنف مماثلا للتعامل مع الجدول في قاعدة البيانات. مثلا، لإدراج تسجيلة جديدة في جدول قاعدة البيانات ننشئ - في التطبيق - كائنا جديدا من الصنف المربوط بالجدول. وإذا أردنا أن نحدّث بيانات تسجيلة من الجدول نحدّث خاصيّات الكائن المربوط بها.

نماذج Eloquent

تُستخدَم النماذج في بنية MVC للتفاعل مع مصادر البيانات (قواعد البيانات، ملفات نصية، … إلخ). تُعرَّف النماذج في Laravel بتمديد الصنف Illuminate\Database\Eloquent\Model الذي يوفّر دوال جاهزة للاستخدام من أجل التفاعل مع مصدر البيانات.

أعراف التسمية في Eloquent

توجد بعض الأعراف التي يفترض إطار العمل Eloquent مبدئيا اتّباعها، مع وجود إمكانية لتغييرها حسب الرغبة. في العرف أن اسم النموذج يكون كلمة مفردة تبدأ بحرف كبير Upper case، بينما اسم الجدول في قاعدة البيانات كلمة للجمع بأحرف صغيرة Lower case. يعتمد Laravel هذا العرف فيربط تلقائيا بين النموذج ذي الاسم المفرد والجدول الذي يكون اسمه جمعا لاسم النموذج.

نستخدم أداة Artisan لإنشاء نموذج لجدول التصنيفات categories باسم Category (مفرد categories):

php artisan make:model Category

ينشئ الأمر ملفا للنموذج على المسار app/Category.php. نفتح الملف لرؤية محتواه:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
  //
}
  • نعرف فضاء الأسماء الذي يتبع له النموذج: ;namespace App.
  • نستورد فضاء الأسماء الخاص بـ Eloquent بالتعليمة: use Illuminate\Database\Eloquent\Model;.
  • يمدّد الصنفُ Category صنفَ نماذج Eloquent الذي تحدثنا عنه أعلاه: class Category extends Model.

من المتعارف عليه أيضا أن حقل المفتاح الرئيس للجدول يُسمّى id، ومن الممكن مثل ما هو الحال مع اسم الجدول، تحديدُ اسم مغاير لحقل المفتح الرئيس.

يمكن تحديد اسم الجدول في النموذج بغض النظر عن المتعارف عليه بإعطاء قيمة للمتغير table$، نفس الشيء بالنسبة للمفتاح الرئيس مع المتغير primaryKey$:

protected $primaryKey = 'id';
protected $table = 'categories';

تسجيلات الأختام الزمنية

يفترض Laravel إضافةَ الحقلين created_at وupdated_at إلى جداول قاعدة البيانات. تُدرج قيمتا الحقلين عند إنشاء تسجيلة جديدة في الجدول، وتحدّث قيمة updated_at عند تحديث قيمة التسجيلة. إن لم تضف هذين الحقلين في جداول قاعدة البيانات فيمكن تعطيل الإعداد المبدئي على النحو التالي:

public $timestamps = false;

استخدام Eloquent

نكمل كتابة الشفرة المصدرية للنموذج Category ليصبح كما يلي:

<?php

namespace App;

class Category extends Model {
  protected $primaryKey = 'id';
  protected $table = 'categories';
}
  • عرّفنا حقل المفتاح الرئيس للجدول: ;'$primaryKey = 'id. ليس هذا ضروريا هنا ما دام اسم الحقل يوافق العُرْف (id). نفس الملحوظة تنطبق على تعريف اسم الجدول في التعليمة الموالية.

قراءة محتوى جدول في قاعدة البيانات

سنرى، في هذه الفقرة، كيفية العثور على جميع التصنيفات التي نحتفظ بها في جدول التصنيفات.

ملحوظة: نطبع النتائج في الأمثلة أدناه مباشرة من الشيفرة المصدرية للمسار دون الاستعانة بالمتحكم رغم أن ذلك مخالف لمبدأ MVC، إلا أن الغرض هنا هو رؤية عمل Eloquent. سنعود لترتيب الأمور في ما بعد.

افتح ملف المسارات routes.php وأضف المسار التالي:

Route::get('/read', function() {
  $category = new App\Category();

  $data = $category->all(array('name','id'));

  foreach ($data as $list) {
   echo $list->id . ' ' . $list->name . '</br>';
  }
});
  • ننشئ كائنا جديدا من صنف النموذج:

    $category = new App\Category();
  • التعليمة التالية تستدعي الدالة all في الكائن الذي أنشأناه للتو، وتمرر له مصفوفة تحدد الحقول التي نود الحصول عليها؛ في حالتنا حدّدنا الحقلين id (المعرِّف) وname (اسم التصنيف). إن لم تُحدَّد معطيات للمصفوفة فستُرجع الدالة جميع الحقول.

  • نستخدم حلقة تكرارية foreach لإظهار النتائج التي تحصلنا عليها.

احفظ التعديلات ثم افتح الرابط http://larashop.dev/read في المتصفح. ستحصُل على لائحة شبيهة بالتالي (قد تختلف النتيجة لديك قليلا):

5 CLOTHING
4 FASHION
3 KIDS
1 MEN
2 WOMEN

تحديث تسجيلات

سنحدّث في هذه الفقرة تسجيلة في جدول التصنيفات باستخدام المعرِّف id. نختار معرّف إحدى التصنيفات الظاهرة في نتيجة المثال السابق، مثلا التصنيفKIDS ذو المعرِّف 3.

نعيد فتح ملف المسارات routes.php ونضيف مسارا جديدا كما يلي:

Route::get('/update', function() {
  $category = App\Category::find(4);
  $category->name = 'KIDS 2';
  $category->save();

  $data = $category->all(array('name','id'));

  foreach ($data as $list) {
    echo $list->id . ' ' . $list->name . '</br>';
  }
});
  • نستدعي الدالة find الموجودة في النموذج مع تمرير معرّف التصنيف إليها. ترجع الدالة كائنا من صنف Category يحوي بيانات التصنيف المستقاة من تسجيلة في الجدول categories.
  • نعيّن الاسم الجديد للتصنيف بالتعديل على الخاصية name في الكائن category$.
  • لتُعتمَد التعديلات وتخزَّن في السجل نستدعي الدالة save من الكائن category$.
  • نستخدم حلقة تكرارية foreach لإظهار النتائج التي تحصلنا عليها.

احفظ الملف ثم افتح الرابط http://larashop.dev/update في المتصفح. لاحظ تغيّر اسم التصنيف من KIDS إلى KIDS 2.

حذف تسجيلة من جدول في قاعدة البيانات

نختار أحد التصنيفات لحذفه (مثلا، التصنيف CLOTHING ذو المعرف 5). افتح ملف المسارات routes.php وأضف المسار التالي:

Route::get('/delete', function() {
    $category = App\Category::find(5);
    $category->delete();

    $data = $category->all(array('name','id'));

    foreach ($data as $list) {
        echo $list->id . ' ' . $list->name . '</br>';
    }
});

يوجد شبه كبير بين تحديث تسجيلة وحذفها. الفرق هو أنه بعد إيجاد التصنيف (الدالة find) نستدعي الدالة delete في الكائن category$ لحذف التسجيلة المربوطة به.

افتح الرابط http://larashop.dev/delete ولاحظ أن التصنيف لم يعد موجودا.

إدراج تسجيلة

لإدراج تسجيلة جديدة في جدول قاعدة البيانات ننشئ كائنا جديدا من صنف Category ونعيّن خواصّه ثم نخزنه في الجدول، كما يلي:

Route::get('/insert', function() {
    $category= new App\Category;
    $category->name='Music';
    $category->save();
    return 'category added';
});

بالذهاب إلى الرابط http://larashop.dev/insert تظهر رسالة category added دلالةً على إضافة التصنيف. يمكن أيضا التحقق من إضافة التصنيف من سطر أوامر MySQL أو بالذهاب إلى الرابط http://larashop.dev/read.

توجد طريقة أخرى لاستخدام سطر برمجي واحد لإدراج تصنيف في تسجيلة. نستخدم لهذا الغرض الدالة create من نموذج التصنيف Category؛ ولكن يجب قبل ذلك التعديل على النموذج Category لتمكين الإسناد الشامل Mass assignment (تحديد قيم معطيات عدّة مرة واحدة).

نفتح ملف النموذج لتحريره ثم نضيف السطر التالي:

protected $fillable = array('name', 'created_at_ip', 'updated_at_ip');

يعرف المتغير fillable$ مصفوفة بالحقول التي يمكن تعيين قيمها دفعة واحدة. احفظ ملف النموذج ثم افتح ملف المسارات routes.php وعدل المسار insert/ ليصبح التالي:

Route::get('/insert', function() {
  App\Category::create(array('name' => 'New Music'));
  return 'category added';
});

نستدعي الدالة create من الصنف Category ونمرر لها مصفوفة بحقول التسجيلة الجديدة مع قيمها. ينبغي أن تكون الحقول الممررة قابلة للإسناد الشامل، أي مذكورة في المتغير fillable$. لاحظ أن إنشاء الكائن وتعيين قيم خاصياته ثم تخزين محتوياته في قاعدة البيانات كل هذا تم من خلال استدعاء الدالة create.

ملحوظة 1: عند طلب الرابط http://larashop.dev/insert في المرة الأولى تظهر الرسالة category added ولكن عند طلب نفس الرابط مرة أخرى دون تعديل المسار تظهر صفحة بيضاء دلالة على عدم إدراج التسجيلة. يعود السبب في ذلك إلى أننا أثناء تعريف الجدول categories في الدرس السابق علّمنا الحقل name بالدالة unique أي أنه لا يمكن لتسجيلتين من هذا الجدول أن يكون لهما نفس الاسم.

ملحوظة 2: الإسناد الشامل غير ممكّن مبدئيا لأسباب أمنية ويجب عند تمكينه اختيار حقول fillable$ بعناية حتى لا تمثل خطرا أمنيا. يجب دائما تطهير Sanitize البيانات التي يستقيها التطبيق من المستخدم.

تنفيذ استعلامات SQL مباشرة

قد ترغب، لسبب أو آخر، في التعامل المباشر مع قاعدة البيانات باستخدام استعلامات SQL؛ يوفر Laravel صنف DB لهذا الغرض.

  • استعلامات SELECT

تُستخدَم دالة select لتنفيذ استعلامات القراءة من قاعدة البيانات على النحو التالي:

$category = DB::select('SELECT name FROM categories WHERE id = ?', [1]);

تأخذ الدالة DB::select معطيين: الأول هو استعلام القراءة المراد تنفيذه، والثاني معطيات نود استخدامها في الاستعلام. بالنسبة للمعطيات المراد استخدامها في الاستعلام فتُحدّد أماكنها بعلامة ? وتكون قيمتها في مصفوفة تمرّر في المعطى الثاني للدالة DB::select. ينفذ السطر أعلاه استعلام SQL التالي:

SELECT name FROM categories WHERE id = 1;

نفرض أننا نريد تنفيذ استعلام SQL التالي:

SELECT name FROM categories WHERE id BETWEEN 1 AND 4;

يطلب الاستعلام قيمتين (1 و4). يُترجم الاستعلام في النموذج على النحو التالي:

$category = DB::select('SELECT name FROM categories WHERE id BETWEEN ? AND ?', [1,4]);

تُبدل أول علامة ? في الاستعلام بأول عنصر من المصفوفة في معطى الدالة الثاني، وعلامة ? الثانية بالمعطى الموالي وهكذا.
يمكن أيضا استخدامُ متغيرات بدلا من ? على النحو التالي:

$category = DB::select('SELECT name FROM categories WHERE id BETWEEN :id1 AND :id2', ['id1' => 1, 'id2' => 4]);

لاحظ استخدام : قبل أسماء المتغيرات في استعلام SQL.

  • استعلامات INSERT

تُستخدم دالة DB::insert لإدراج تسجيلات في الجدول بنفس طريقة استخدام DB::select للقراءة منه:

$inserted=DB::insert('INSERT INTO categories (name) VALUES (?)', ['TEST']);

ترجع الدالة DB::insert عدد التسجيلات التي أدرجها الاستعلام.

  • استعلامات UPDATE

لتحديث تسجيلة في جدول بقاعدة البيانات نستخدم الدالة DB::update:

$affected = DB::update('UPDATE categories SET name = 'TEST UPDATE' WHERE name = ?', ['TEST']);

ترجع الدالة DB::update عدد التسجيلات التي حدثها الاستعلام.

  • استعلامات DELETE

توفر الدالة DB::delete إمكانية تنفيذ استعلامات DELETE على النحو التالي:

$deleted = DB::delete('DELETE FROM categories WHERE id = ?', [13]);

ترجع الدالة DB::delete عدد التسجيلات التي حذفها الاستعلام.

  • استعلامات عامة

بالنسبة للاستعلامات التي لا ترجع أية قيمة فيمكن استخدام الدالة DB::statement:

DB::statement('drop tables drinks');

نماذج Eloquent لمشروع Larashop

نشرع الآن بعد أن رأينا آلية عمل Eloquent ببناء بقية نماذج مشروع Larashop.

نفذ الأوامر التالية لإنشاء نماذج للعلامات التجارية، المنتجات ومنشورات المدونة على التوالي:

php artisan make:model Brand
php artisan make:model Product
php artisan make:model Post

نعرّف في كل ملف نموذج حقل المفتاح الرئيس، اسم الجدول وأسماء الحقول المسموح بإسنادها fillable.

  • ملف Brand.php:

    <?php
    
    namespace App;
    
    class Brand extends Model {
      protected $primaryKey = 'id';
      protected $table = 'brands';
      protected $fillable = array('name', 'created_at_ip', 'updated_at_ip');
    }
    
  • ملف Product.php:

    <?php
    
    namespace App;
    
    class Product extends Model {
        protected $primaryKey = 'id';
        protected $table = 'products';
        protected $fillable = array('name', 'title',    'description','price','category_id','brand_id','created_at_ip', 'updated_at_ip');
    }
    
    
  • ملف Post.php: 

<?php

namespace App;

class Post extends Model {
    protected $primaryKey = 'id';
    protected $table = 'posts';
    protected $fillable = array('url', 'title', 'description','content','blog','created_at_ip', 'updated_at_ip');
}

استخدام النماذج في المتحكمات

تقضي بنية MVC وعادات البرمجة الصحيحة أن تكون المتحكمات هي من يتعامل مع النماذج. سنعدّ متحكم المشروع Front.php للعثور على البيانات من النماذج وتمريرها إلى العروض لتظهر لدى المتصفح.

عدّل ملف Front.php كالتالي:

<?php

namespace App\Http\Controllers;

use App\Brand;
use App\Category;
use App\Product;
use App\Http\Controllers\Controller;

class Front extends Controller {

 var $brands;
 var $categories;
 var $products;
 var $title;
 var $description;

public function __construct() {
  $this->brands = Brand::all(array('name'));
  $this->categories = Category::all(array('name'));
  $this->products = Product::all(array('id','name','price'));
}

public function index() {
  return view('home', array('title' => 'Welcome','description' => '','page' => 'home', 'brands' => $this->brands, 'categories' => $this->categories, 'products' => $this->products));
}

public function products() {
  return view('products', array('title' => 'Products Listing','description' => '','page' => 'products', 'brands' => $this->brands, 'categories' => $this->categories, 'products' => $this->products));
}

public function product_details($id) {
  $product = Product::find($id);
  return view('product_details', array('product' => $product, 'title' => $product->name,'description' => '','page' => 'products', 'brands' => $this->brands, 'categories' => $this->categories, 'products' => $this->products));
}

public function product_categories($name) {
  return view('products', array('title' => 'Welcome','description' => '','page' => 'products', 'brands' => $this->brands, 'categories' => $this->categories, 'products' => $this->products));
}

public function product_brands($name, $category = null) {
  return view('products', array('title' => 'Welcome','description' => '','page' => 'products', 'brands' => $this->brands, 'categories' => $this->categories, 'products' => $this->products));
}

public function blog() {
  return view('blog', array('title' => 'Welcome','description' => '','page' => 'blog', 'brands' => $this->brands, 'categories' => $this->categories, 'products' => $this->products));
}

public function blog_post($id) {
  return view('blog_post', array('title' => 'Welcome','description' => '','page' => 'blog', 'brands' => $this->brands, 'categories' => $this->categories, 'products' => $this->products));
}

public function contact_us() {
  return view('contact_us', array('title' => 'Welcome','description' => '','page' => 'contact_us'));
}

public function login() {
  return view('login', array('title' => 'Welcome','description' => '','page' => 'home'));
}

public function logout() {
  return view('login', array('title' => 'Welcome','description' => '','page' => 'home'));
}

public function cart() {
  return view('cart', array('title' => 'Welcome','description' => '','page' => 'home'));
}

public function checkout() {
  return view('checkout', array('title' => 'Welcome','description' => '','page' => 'home'));
}

public function search($query) {
  return view('products', array('title' => 'Welcome','description' => '','page' => 'products'));
}
}

في المتحكم:

  • نستورد النماذج:

    use App\Brand;
    use App\Category;
    use App\Product;
    
  • نعرف متغيرات لتحميل بيانات النماذج:

    var $brands;
    var $categories;
    var $products;
    
  • يعرف المتغيران title$ وdescription$ على التوالي عنوانا ووصفا لأغراض التحسين لمحركات البحث.

  • نُعرّف باني Constructor صنف المتحكم:

    public function __construct(){…}

    تحمّل هذه الدالة البيانات من النماذج إلى المتغيرات المعرّفة سابقا.

  • نحمّل في الدالة index العرض home مع تمرير مصفوفة معطيات تمثل بيانات النماذج مع بيانات أخرى لغرض التحسين لمحركات البحث.

عرض بيانات النماذج في العروض

نستخدم الحلقات التكرارية في قوالب Blade من أجل عرض بيانات النماذج التي مررها المتحكم إلى العروض. على سبيل المثال:

@foreach ($brands as $brand)
  <li><a href='{{url("products/brands/$brand->name")}}'> <span class="pull-right">(50)</span>{{$brand->name}}</a></li>
@endforeach

توجد عروض المشروع في الملف المرفق.

خاتمة

من السهل إنشاء نماذج Eloquent واستخدامها؛ كل ما عليك فعله هو تمديد صنف Model والبدء باستخدام النموذج. يوفر Laravel أيضا إمكانية تخصيص استعلامات SQL دون المرور بـEloquent لمن يرغب في ذلك.

ملف مرفق: عروض المشروع.

ترجمة -وبتصرف- لمقال Laravel 5 Eloquent ORM لصاحبه Rodrick Kazembe.





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


لدي مشكلة في هذا الدرس

Whoops, looks like something went wrong.

2/2QueryException in Connection.php line 669:SQLSTATE[42S02]: Base table or view not found: 1146 Table 'larashop.categories' doesn't exist (SQL: select `name`, `id` from `categories`)

  1. in Connection.php line 669
  2. at Connection->runQueryCallback('select `name`, `id` from `categories`', array(), object(Closure)) in Connection.php line 629
  3. at Connection->run('select `name`, `id` from `categories`', array(), object(Closure)) in Connection.php line 342
  4. at Connection->select('select `name`, `id` from `categories`', array(), true) in Builder.php line 1495
  5. at Builder->runSelect() in Builder.php line 1481
  6. at Builder->get(array('name', 'id')) in Builder.php line 596
  7. at Builder->getModels(array('name', 'id')) in Builder.php line 303
  8. at Builder->get(array('name', 'id')) in Model.php line 646
  9. at Model::all(array('name', 'id')) in routes.php line 36
  10. at RouteServiceProvider->{closure}()
  11. at call_user_func_array(object(Closure), array()) in Route.php line 158
  12. at Route->runCallable(object(Request)) in Route.php line 137
  13. at Route->run(object(Request)) in Router.php line 724
  14. at Router->Illuminate\Routing\{closure}(object(Request))
  15. at call_user_func(object(Closure), object(Request)) in Pipeline.php line 52
  16. at Pipeline->Illuminate\Routing\{closure}(object(Request))
  17. at call_user_func(object(Closure), object(Request)) in Pipeline.php line 103
  18. at Pipeline->then(object(Closure)) in Router.php line 726
  19. at Router->runRouteWithinStack(object(Route), object(Request)) in Router.php line 699
  20. at Router->dispatchToRoute(object(Request)) in Router.php line 675
  21. at Router->dispatch(object(Request)) in Kernel.php line 246
  22. at Kernel->Illuminate\Foundation\Http\{closure}(object(Request))
  23. at call_user_func(object(Closure), object(Request)) in Pipeline.php line 52
  24. at Pipeline->Illuminate\Routing\{closure}(object(Request)) in CheckForMaintenanceMode.php line 44
  25. at CheckForMaintenanceMode->handle(object(Request), object(Closure))
  26. at call_user_func_array(array(object(CheckForMaintenanceMode), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 124
  27. at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
  28. at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
  29. at Pipeline->Illuminate\Routing\{closure}(object(Request))
  30. at call_user_func(object(Closure), object(Request)) in Pipeline.php line 103
  31. at Pipeline->then(object(Closure)) in Kernel.php line 132
  32. at Kernel->sendRequestThroughRouter(object(Request)) in Kernel.php line 99
  33. at Kernel->handle(object(Request)) in index.php line 54

1/2PDOException in Connection.php line 333:SQLSTATE[42S02]: Base table or view not found: 1146 Table 'larashop.categories' doesn't exist

  1. in Connection.php line 333
  2. at PDO->prepare('select `name`, `id` from `categories`') in Connection.php line 333
  3. at Connection->Illuminate\Database\{closure}(object(MySqlConnection), 'select `name`, `id` from `categories`', array()) in Connection.php line 662
  4. at Connection->runQueryCallback('select `name`, `id` from `categories`', array(), object(Closure)) in Connection.php line 629
  5. at Connection->run('select `name`, `id` from `categories`', array(), object(Closure)) in Connection.php line 342
  6. at Connection->select('select `name`, `id` from `categories`', array(), true) in Builder.php line 1495
  7. at Builder->runSelect() in Builder.php line 1481
  8. at Builder->get(array('name', 'id')) in Builder.php line 596
  9. at Builder->getModels(array('name', 'id')) in Builder.php line 303
  10. at Builder->get(array('name', 'id')) in Model.php line 646
  11. at Model::all(array('name', 'id')) in routes.php line 36
  12. at RouteServiceProvider->{closure}()
  13. at call_user_func_array(object(Closure), array()) in Route.php line 158
  14. at Route->runCallable(object(Request)) in Route.php line 137
  15. at Route->run(object(Request)) in Router.php line 724
  16. at Router->Illuminate\Routing\{closure}(object(Request))
  17. at call_user_func(object(Closure), object(Request)) in Pipeline.php line 52
  18. at Pipeline->Illuminate\Routing\{closure}(object(Request))
  19. at call_user_func(object(Closure), object(Request)) in Pipeline.php line 103
  20. at Pipeline->then(object(Closure)) in Router.php line 726
  21. at Router->runRouteWithinStack(object(Route), object(Request)) in Router.php line 699
  22. at Router->dispatchToRoute(object(Request)) in Router.php line 675
  23. at Router->dispatch(object(Request)) in Kernel.php line 246
  24. at Kernel->Illuminate\Foundation\Http\{closure}(object(Request))
  25. at call_user_func(object(Closure), object(Request)) in Pipeline.php line 52
  26. at Pipeline->Illuminate\Routing\{closure}(object(Request)) in CheckForMaintenanceMode.php line 44
  27. at CheckForMaintenanceMode->handle(object(Request), object(Closure))
  28. at call_user_func_array(array(object(CheckForMaintenanceMode), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 124
  29. at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
  30. at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
  31. at Pipeline->Illuminate\Routing\{closure}(object(Request))
  32. at call_user_func(object(Closure), object(Request)) in Pipeline.php line 103
  33. at Pipeline->then(object(Closure)) in Kernel.php line 132
  34. at Kernel->sendRequestThroughRouter(object(Request)) in Kernel.php line 99
  35. at Kernel->handle(object(Request)) in index.php line 54

شارك هذا التعليق


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


يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن