فائدة constructor في اللارافيل

Huda_Huda

السلام عليكم

قد يبدو السؤال تافها ، لكنني ما زلت مبتدئة بالبرمجة في اللارافيل

كلنا نعلم أن constructor يتم استدعاؤه عندما نقوم بعمل object من الكلاس

الآن سؤالي في لارافيل يتم استخدام الconstructor بداخل الcontrollrer و يتم فيه إرسال متغيرات و استدعاء دوال و غيرها من الكود ، فما فائدة استدعاء constructor إذا لم نقم بعمل كائن من controller و هل يتم عمل كائن أو لا من controller ، أعلم أن السؤال قد يبدو بسيطا للبعض لكني لم أفهم هذه الجزئية ، و السؤال الآخر متى نكون بحاجة إلى عمل constructor و ما الطريقة الأفضل لاستخدامه، و شكرا لكم

يرجى الدخول لحسابك أو تسجيل حساب لتستطيع إضافة تعليق
حساب جديد دخول

التعليقات

ال Constructor هي أول method يتم الإتصال بها او بمعنى أخر هي دالة البناء في OOP لكن في laravel لا يوجد مصطلح constructor override لذلك يمكنك إنشاء فقط دالة بناء واحدة، ويتم إستخدامه في الغالب ب laravel فقط في حالة إستعمال middlewares أو مثلا Authorizations او initialize لبعض البرامترات كمثال:

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

يمكنك معرفة المزيد عنه من هنا:

شكرا جدا ، الآن على فرض وضعت في costructor

$this->middleware('auth')

متى بالضبط يتم استدعاء هذه الميثود ؟ هل عندما أقوم بعمل Route و أضع به الcontroller الخاص بهذا الconstructor أو في أي وقت بالتحديد ؟

بمجرد ما يتم إنشاء الأوبجكت مباشرة ستتفعل middleware

مرحباً بك،

صراحةً السؤال ليس تافهاً كما ذكرت، لارافيل هو عبارة عن إطار عمل يستخدم لغة php و يعتمد على معمارية mvc في كتابته للكود و لتطبيق هذا النمط نحتاج إلى البرمجة الكائنية لذلك فالمتحكم (controller) هو في الحقيقة عبارة عن صنف (class) و بما أنه صنف يُمكننا تطبيق كافة مبادئ و مفاهيم البرمجة الكائنية عليه و من بينها تعريف دالة بانية (constructor) له. هذا الشيء مفهوم و متفق عليه.

أدري أنك تعلمين هذا و قد فهمت ما ترمين إليه ^بما أننا لا نقوم بإنشاء كائن من صنف المتحكم أي متحكم كان فالconstructor لا يتم إستدعاؤه و بالتالي تعريفنا له لن يُفيدنا في شيء^ هذا ما تُفكرين فيه ، في الحقيقة نعم نحن لا نقوم بإنشاء كائن لكن إطار العمل يقوم بإنشاء نُسخة من هذا المُتحكم في مكان ما و إن صح التعبير نُسخة التطبيق التي يتم إنشاؤها من الcontainer الخاص بلارافيل تقوم بذلك تلقائياً. و لِفهم متى تقوم بذلك علينا فهم دورة حياة الطلب (request) بدايةً من إرسال المستخدم لطلب ما إلى إرجاع رد في الحقيقة هناك أشياء عديدة تحدث في الكواليس و الخفاء و هذه الأشياء متقدمة لا أنصحك بها حالياً

عموماً بعد كتابة المستخدم لرابط ما في المتصفح مثلا : site_name/posts و إرساله سيتم تحويل الطلب مباشرة إلى الملف index.php الموجود في مُجلد public و أي طلب مهما كان يتم تحويله تلقائياً لهذا الملف، أنا لا أريد الغوص في تفاصيل كثيرة لأنه لن يكفي مقال واحد لذلك، لكن سأتحدث عن الموضوع بإختصار لأضعك في الصورة.

بداية في ملف index.php يتم تضمين الautoloader الخاص بالcomposer و بعدها يتم إنشاء نُسخة من الصنف Application الذي يرث من ال Container الخاص بلارافيل ثم يتم إنشاء نُسخة من ال http kernel إنطلاقاً من الكائن app بعدها يتم تنفيذ هذا الكود:

في هذا الكود سيتم إلتقاط الطلب و مُعالجته و إسترجاع الرد لكن سيتم تنفيذ العديد من الشيفرات البرمجية حتى نصل إلى إختيار التوجيه(route) المُناسب أو رمي إستثناء في حالة عدم الوجود

في حالة وجود توجيه مُناسب للطلب فسيتم تنفيذه و ذلك من خلال:

و من خلال التوجيه سيتم معرفة الaction المُناسبة فهناك action خاصة ب متحكم و هناك call back function ما يهمنا هنا هو الحالة الأولى أي أن الaction خاصة بمتحكم و بالتالي سيتم تنفيذ الميثود runController و إرجاع النتيجة التي تُعطيها و إذا ألقينا نظرة على مُحتوى الميثود نجد:

ما يهما هنا هو جزء this->getController و هو عبارة عن ميثود ثانية هذه الميثود هي التي تقوم بإنشاء نُسخة من المتحكم المطلوب في حالة عدم وجودها أما في حالة وجودها فستقوم بإرجاعها فقط و هذا هو مُحتواها:

و عند إنشاء نُسخة من المُتحكم المطلوب سيتم تنفيذ الدالة البانية (constructor) الخاصة به ، عموماً هذه الأشياء متقدمة والغوص فيها لن يُفيدك في تسريع إنشاء مشاريعك و إنما سيُفيدك في كيفية عمل الفريمورك نفسه و كيف تم بناؤه و لمعلومات أكثر يُمكنك قراءة و فهم هذه السلسلة من المقالات لأني لم أشرح كل شيء بالتفصيل و قد تجاوزت عدة أمور:

بالتوفيق.

حقيقة أشكرك على هذا الرد الرائع و هذا بالتحديد ما كنت أرغب بمعرفته ، لكن ما زال لدي بعض اللبس ، الآن على سبيل المثال : عندما يكون لدي في ملف web.php الكود الآتي Route::get('/anything', 'FirstController@firstmethod' ); هل بهذا السطر يتم استدعاء الcontroller و بالتالي يتم عمل object هنا أم ماذا ، و بالنسبة لما ذكرت أنه عند طلب رابط معين فإنه يتم استدعاء ملف index.php فمتى إذن يتم تنفيذ الراوت الموجود بملف web.php ، عذرا لكثرة أسئلتي

بهذا السطر نحن نقوم فقط بتعريف الموجهات هذه الموجهات سيتم ملؤها لاحقا في قائمة أو مصفوفة عناصرها عبارة عن كائنات من الصنف Route. هذه المصفوفة هي إحدى خصائص (properties) من نُسخة التطبيق التي يتم إنشاؤها و بالتالي عند إرسال طلب سيتم البحث في المصفوفة عن التوجيه الموافق و المناسب للطلب المُرسل و إذا وُجد توجيه موافق سيتم تنفيذه، التوافق يكون على أساس الرابط و الميثود و إذا كان الaction الخاص بالتوجيه الموافق نوعه متحكم (isControllerAction) فبالتالي سيتم البحث عن المتحكم الموافق وإنشاء نسخة منه في حالة عدم وجودها و هنا سيتم تنفيذ الconstructor الخاص بالمتحكم.

هناك عدة أشياء تحدث في الخفاء و نحن سنجدها جاهزة فقط سنستخدمها فمثلا عملية الربط بقاعدة البيانات نحن لا نقوم بها و لا نقوم بالإتصال بقاعدة البيانات فنحن فقط نُعرف إعدادات الإتصال في ملف .env لكن آلية الإتصال تحدث في الخفاء . عملية تحميل الإعدادات المختلفة التي نضعها في مجلد config و إتاحة إستخدامها أيضا مخفية . ال responses، ال middlewares، الrequests، معالجة الأخطاء و الإستثناءات ... بتعمقنا في إطار العمل سنفهم كيف تتم هذه الأشياء، لكن لن تفيدك في شيء فالأحسن التركيز على كيفية إستخدام الفريموورك و ليس كيف تم بناؤه و كيفية معالجته للأمور.

اتمنى لك التوفيق

Constructor هي دالة البناء في البرمجة كائنية التوجه في أي لغة برمجة ليس لها علاقة مباشرة ب larval

مثال

public class Computer {

// Set Properties - تحديد الخواص

private int id;

private String name;

private String ramModel;

private String motherBoardModel;

// Set Default Constructor - تحديد الإفتراضي :

public Computer() {}

// Set Parametrized Constructor - تحديد النوع الثاني :

public Computer(int id, String name, String ramModel, String motherBoardModel){

this.id = id;

this.name = name;

this.ramModel = ramModel;

this.motherboardModel = motherBoardModel;

}

// Set Actions - تحديد الأفعال

public void turnOn() {

System.out.Println("Computer is turned on");

}

public void turnOff(){ System.out.Println("Computer is turned off"); } }

مثال php

<?php class BaseClass { function __construct() { print "In BaseClass constructor\n"; } }

class SubClass extends BaseClass { function __construct() { parent::__construct(); print "In SubClass constructor\n"; } }

class OtherSubClass extends BaseClass { // inherits BaseClass's constructor

}

// In BaseClass constructor

$obj = new BaseClass();

// In BaseClass constructor

// In SubClass constructor

$obj = new SubClass();

// In BaseClass constructor

$obj = new OtherSubClass();

?>

صحيح و أنا أعرف هذا الكلام جيدا ، سؤالي يتعلق باللارافيل لماذا نحتاج لعمل constructor في controller يعني على سبيل المثال لم أرَ في أي كود أننا قمنا بعمل object من هذا الcontroller فما فائدة ذلك ، أو هل يتم عمل object من controller في أماكن أخرى

يمكن الاستفادة من ال constructor في اللارفيل بعدة أمور :

1- استدعاء ال middlewares التي نحتاجها .

public function __construct()
{
    $this->middleware("can:superAdmin");
}

2- استخدام توابع ال Authorization مثل authorize , authorizeResource و غيرها ....

public function __construct()
{
    $this->authorizeResource(Category::class, "category");
}

3- كما يمكن تجهيز متحول أو عملية حسابية معينة لتكون متوفرة بكل التوابع (( حتى لا نكرر الكود )) .

private $index_route;

public function __construct()
{
    $this->index_route = route("admin.roles.index");
}

في المثال هذا لا يمكننا استخدام توابع مثل ال route أو غيره في تهيئة المتحول index_route فبالتالي الحل الوحيد هو باستخدام ال constructor .

بمعنى آخر .... يمكن اعتبار ال constructor أنه تابع يستدعى قبل أي تابع ضمن ال controller , ولا يجب اعتباره كشيء يقوم بتجهيز ال object بقيم معينة لأنه كما ذكرت , أساساً ليس عندنا Object ضمن الكود المقروء معنا .

طبعاً يمكنن التعرف على التوابع الجاهزة التي تقدمها لنا ال laravel إذا نظرنا إلى الملف App\Http\Controllers\Controller.php

و كمعلومة متقدمة , يمكنك الاطلاع على مفهوم dependency injection

شكرا لك ، هل هناك مصادر أكثر لتوضيح فكرة dependency injection ؟

ممكن إلقاء نظرة على هذا الرابط لرؤية المفهوم بشكل أدق من وجهة نظر اللارفيل :

أو ممكن مشاهدة المفهوم بشكل أعم بالنسبة ل php :

أو قراءة الموضوع بشكل علمي من ويكيبيديا :

هذا ليس له علاقة بلارفال

هذه دالة مخصصة لتهيئة انشاء الاوبجكت الجديد

يمكنك تكرار نفس الدالة عدة مرات مع متغيرات مختلفة لتتمكن من تهيئة الكائن بطرق مختلفة ان احببت

يمكنك ان تجعلها بدون اي متغير، وعند استدعاءها تقوم بجعل متغيرات الكائن فارغة Null

يمكنك من خلالها انشاء كائن وجعل كل متغيراته فارغة

او انشاء كائن مع قيم افتراضية يبدأ بها

وهكذا