سؤال

هل هناك أي ميزة استخدام __construct() بدلا من الدرجة اسم منشئ في PHP?

على سبيل المثال (__construct):

class Foo {
    function __construct(){
        //do stuff
    }
}

مثال (اسمه):

class Foo {
    function Foo(){
        //do stuff
    }
}

وجود __construct طريقة (المثال الأول) من الممكن منذ PHP 5.

بعد أن الأسلوب مع نفس اسم الفئة منشئ (المثال الثاني) من نسخة PHP 4 حتى الإصدار 7.

هل كانت مفيدة؟

المحلول

وأنا أتفق مع الأداة، وميزة لذلك لم يكن لديك لتسميته إذا قمت بإعادة تسمية صفك. DRY.

وبالمثل، إذا كان لديك فئة الأطفال يمكنك الاتصال

parent::__construct()

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

ويبدو وكأنه شيء صغير، ولكن في عداد المفقودين تغيير اسم مكالمة المنشئ للوالدين الفصول الدراسية يمكن أن يخلق خفية (وليس خفية ذلك) البق.

وعلى سبيل المثال، إذا قمت بإدراجه فئة إلى heirachy، ولكن نسيت أن تغيير المكالمات منشئ، كنت قد بدأت الدعوة الصانعين الأجداد بدلا من الآباء والأمهات. وهذا يمكن أن يؤدي في كثير من الأحيان نتائج غير مرغوب فيها والتي قد يكون من الصعب أن تلاحظ.

وأيضا لاحظ أن

<اقتباس فقرة>   

واعتبارا من PHP 5.3.3، لن يتم التعامل مع الطرق مع نفس اسم العنصر الأخير من اسم فئة namespaced كما المنشئ. هذا التغيير لا يؤثر على الطبقات غير namespaced.

المصدر: http://php.net/manual/en/language. oop5.decon.php

نصائح أخرى

وقدم __construct في PHP5. وهذه هي الطريقة التي من المفترض لك أن تفعل ذلك الآن. أنا لست على علم بأي <م> مزايا في حد ذاته، وإن كان.

ومن دليل PHP:

<اقتباس فقرة> للالتوافق، إذا PHP 5 لا يمكن العثور على وظيفة __construct () لفئة معينة، فإنه سيتم البحث عن وظيفة البناء على الطراز القديم، من قبل اسم الفئة. على نحو فعال، وهو ما يعني أن الحالة الوحيدة التي سيكون لها مشاكل التوافق هو إذا كانت الطبقة أسلوب المسمى __construct () والذي تم استخدامه لدلالات مختلفة

إذا كنت على PHP5 أود أن أوصي باستخدام __construct لتجنب الوقوع في PHP نظرة في أماكن أخرى.

والميزة الرئيسية لأرى __construct، أن لم يكن لديك لإعادة تسمية منشئ إذا قمت بتغيير اسم صفك.

اليوم, الجواب المقبول هو عفا عليها الزمن.

إعادة تسمية الطبقات الممارسة السيئة:عليك أن تتذكر ماذا وأين إعادة تسمية كل مرة يمكنك الترقية إلى الإصدار الأحدث.في بعض الأحيان (مثل استخدام انعكاس أو معقدة الاعتماد هيكل) يمكن أن يكون من المستحيل دون جذرية إعادة بيع ديون.و هذا هو عرضي تعقيد كنت ترغب في تجنب.هذا هو السبب مساحات أدخلت إلى PHP.Java, C++ أو C# لا تستخدم __construct, إنهم يستخدمون اسمه منشئ وليس هناك أي مشكلة معهم.

كما PHP 5.3.3 وأساليب مع نفس اسم العنصر الأخير من namespaced اسم الفئة لم يعد يعامل منشئ.هذا التغيير لا يؤثر عدم namespaced الطبقات.

على سبيل المثال

namespace Foo;
class Test {
  var $a = 3;

  function Test($a) {
    $this->a = $a;
  }

  function getA() {
    return $this->a;
  }
}

$test = new Test(4);
echo $test->getA(); // 3, Test is not a constructor, just ordinary function

لاحظ أن اسمه منشئات غير مستنكر (PHP 5.5 اليوم).ومع ذلك لا يمكنك أن تتوقع أن الفئة الخاصة بك لن تستخدم في مساحة الاسم ، لذلك __construct يجب أن يكون أعطيت الأولوية.

توضيح حول سوء الممارسة المذكورة أعلاه (دينيس)

في مكان ما في التعليمات البرمجية الخاصة بك يمكنك استخدام ReflectionClass::getName();عند إعادة تسمية فئة تحتاج إلى تذكر حيث يمكنك استخدام انعكاس وإذا تحقق getName() النتيجة لا تزال متسقة في التطبيق الخاص بك.كلما كنت بحاجة إلى أن نتذكر شيء محدد ، على الأرجح نسيت شيئا مما يؤدي إلى أخطاء في التطبيق.

الآباء والأمهات لا يمكن أن يكون التحكم عن جميع الطبقات في العالم التي يعتمد عليها.إذا allow_url_include تمكين بعض الدول الأخرى على شبكة الإنترنت قد يكون استخدام فئة من الخادم الخاص بك, التي قد يتلف إذا قمت بإعادة تسمية بعض الصف.بل هو أسوأ من ذلك في ترجمة اللغات المذكورة أعلاه:المكتبة يمكن نسخ المجمعة في التعليمات البرمجية الأخرى.

لا يوجد سبب لإعادة تسمية الطبقة:

  • إذا كان اسم الفئة الصراعات استخدام مساحات
  • إذا كانت فئة المسؤولية التحولات ، تستمد بعض فئة أخرى بدلا من ذلك

في PHP الفئات في مساحة الاسم, طريقة بنفس الاسم يجب تجنبها على أي حال:حدسي كان يجب أن ينتج كائن خلق الطبقة ؛ إذا كان لا شيء آخر, لماذا تعطيه نفس الاسم ؟ فإنه ينبغي أن يكون منشئ أي شيء آخر.القضية الرئيسية هي أن سلوك مثل هذا الأسلوب يعتمد على مساحة الاستخدام.

ليس هناك مشكلة مع __بناء المنشئات في PHP.لكنه لم يكن أذكى فكرة تغيير اسمه المنشئات.

وأفضل ميزة استخدام __contruct() بدلا من ClassName() هي عندما تمتد الطبقات. انه من الاسهل بكثير للاتصال parent::__construct() بدلا من parent::ClassName()، كما هو قابل لإعادة الاستخدام بين الطبقات والوالد يمكن تغييرها بسهولة.

في المثال Foo::Foo بك يسمى أحيانا PHP 4 أو على الطراز القديم منشئ لأنها تأتي من أيام PHP 4:

class Foo {
    // PHP 4 constructor
    function Foo(){
        //do stuff
    }
}

PHP سيتم إهمال 4 الصانعين ولكن لم تتم إزالة في PHP 7. وسوف تكون لم تعد تعتبر الصانعين في أي حالة في PHP 8. التوافق المستقبل هو بالتأكيد سبب كبير لعدم استخدام هذه الميزة.

في PHP 5 ان ميزة يكون من شأنه أن يكون الأداء أفضل. وسوف نبحث عن منشئ من قبل باسم __construct أولا وإذا لم يجد ذلك، فإنه سوف تبحث عن الصانعين من قبل باسم className. حتى اذا وجدت منشئ من قبل __construct اسم فإنه لا حاجة للبحث عن منشئ من قبل className الاسم.

حسنا لقد مرت عدة سنوات منذ أن طرح هذا السؤال ، ولكن أعتقد أن الإجابة على هذا واحد لا يزال ، لأن الأمور قد تغيرت و للقراء في المستقبل أريد للحفاظ على المعلومات حتى الآن!


حتى في php-7 وسوف إزالة خيار إنشاء منشئ بوصفها وظيفة مع نفس اسم الفئة.إذا كنت لا تزال تفعل ذلك سوف تحصل على E_DEPRECATED.

يمكنك قراءة المزيد حول هذا الاقتراح (تم قبول المقترح) هنا: https://wiki.php.net/rfc/remove_php4_constructors

و اقتبس من هناك:

PHP 7 سوف تنبعث منها E_DEPRECATED كلما PHP 4 منشئ هو تعريف.عندما الأسلوب الاسم يطابق اسم الفئة, فئة ليست في مساحة الاسم و PHP 5 منشئ (__بناء) غير موجود ثم E_DEPRECATED سوف تنبعث. PHP 8 سوف تتوقف انبعاث E_DEPRECATED وأساليب لن يتم الاعتراف بها المنشئات.

كما أنك لن تحصل على E_STRICT في php-7 إذا كنت تعرف الطريقة مع نفس اسم الصف ، __construct().

يمكنك أن ترى هذا أيضا هنا:

PHP 7 أيضا وقف انبعاث E_STRICT عندما الأسلوب مع نفس اسم الفئة موجودة وكذلك __بناء.


لذلك أنصح لك استخدام __construct(), منذ سيكون لديك أقل مشاكل مع هذا في المستقبل.

والتوافق إلى الأمام. هناك دائما فرصة أن التعليمات البرمجية القديمة التي تبقى في اللغة من أجل التوافق سيتم إزالة في إصدار مستقبلي.

وإذا كان هناك طرق __construct وطريقة SameAsClassName ثم سيتم تنفيذها __construct، سيتم تخطي طريقة SameAsClassName.

وأعتقد أن السبب الرئيسي هو أن الاتفاقية اللغة. أنت لا تحتاج إلى قوة اللغة أن يتصرف مثل شخص آخر.

وأعني، في الهدف-C كنت بادئة الصانعين مع -init، على سبيل المثال. يمكنك جعل منشئ الخاص بك باستخدام اسم صفك ولكن لماذا؟ هل ذر سبب لاستخدام هذا المخطط بدلا من اتفاقية لغة؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top