هل الطريقة الثابتة في PHP لديك أي فرق مع طريقة غير ثابتة؟

StackOverflow https://stackoverflow.com/questions/2439036

  •  19-09-2019
  •  | 
  •  

سؤال

class t {
    public function tt()
    {
        echo 1;
    }
}
t::tt();

انظر؟ يمكن أيضا استدعاء الوظيفة غير الثابتة على مستوى الفصل. لذلك ما يختلف إذا أضفت static الكلمة الرئيسية قبل public?

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

المحلول

باستثناء ذلك، إذا حاولت استخدام $this في طريقتك، مثل هذا:

class t {
    protected $a = 10;
    public function tt() {
        echo $this->a;
        echo 1;
    }
}
t::tt();

ستحصل على خطأ فادح عند استدعاء الطريقة غير الثابتة بشكل ثابت:

Fatal error: Using $this when not in object context in ...\temp.php on line 11

أي مثالك قليلا بسيط جدا, ولا تتوافق حقا مع حالة حقيقية ؛-)


لاحظ أيضا أن مثالك يجب أن تحصل على تحذير صارم (نقلا عن) :

استدعاء الطرق غير الثابتة ينشئ القانون E_STRICT تحذير المستوى.

وهو فعلا يفعل (على الأقل، مع PHP 5.3) :

Strict Standards: Non-static method t::tt() should not be called statically in ...\temp.php on line 12
1

لذلك: ليس هذا جيد ؛-)


ومع ذلك، فإن الاتصال بشكل ثابت طريقة غير ثابتة لا تبدو مثل أي نوع من الممارسات الجيدة (وهو ربما لماذا يثير تحذير صارم), ، نظرا لأن الطرق الثابتة لا تملك نفس المعنى من تلك غير الثابتة: لا تشير الأساليب الثابتة إلى أي كائن، في حين أن الطرق غير الثابتة تعمل على مثيل الفئة التي دعا فيها.


مرة أخرى: حتى لو كان PHP يسمح لك بفعل شيء ما (ربما لأسباب تاريخية - مثل التوافق مع الإصدارات القديمة), ، هذا لا يعني أنك يجب أن تفعل ذلك!

نصائح أخرى

ال كلمة رئيسية ثابتة

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

لا يمكن الوصول إلى خصائص ثابتة من خلال الكائن باستخدام مشغل السهم ->.

إن استدعاء الطرق غير الثابتة يولد تحذيرا إلى مستوى E_Strict.

فقط لأنه يمكنك الاتصال بطرق غير ثابتة لا يعني أنه يجب عليك. انها شكل سيء.

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

الفرق بين طريقة الفصل وطريقة كائن هي تلك الطرق الفئة يمكن فقط الوصول إلى خصائص الفئة (خصائص ثابتة) أثناء استخدام طرق الكائنات للوصول إلى خصائص الكائنات (خصائص مثيل الطبقة نفسها).

يتم استخدام الأساليب والخصائص الثابتة لتبادل البيانات الشائعة أو لجميع مثيلات ذلك الفئة المحددة.

يمكنك، على سبيل المثال، استخدام خاصية ثابتة لتتبع عدد الحالات:

class A {
    private static $counter = 0;

    public function __construct() {
        self::counter = self::counter + 1;
    }

    public function __destruct() {
        self::counter = self::counter - 1;
    }

    public static function printCounter() {
        echo "There are currently ".self::counter." instances of ".__CLASS__;
    }
}

$a1 = new A();
$a2 = new A();
A::printCounter();
unset($a2);
A::printCounter();

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

الفرق الرئيسي الذي لم يتم ذكره يتعلق السلوك متعدد الأشكال.

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


PHP 5.3 قدم مفهوم التجليد الثابت المتأخر والتي يمكن استخدامها للإشارة إلى الفئة المسمى في سياق الميراث الثابتة.

نعم، الفرق الحرج هو أن الطرق المعلنة static لا تملك الوصول إلى متغير السياق الكائن، $this.

بالإضافة إلى ذلك، فإن الاحتجاج بطريقة غير ثابتة عند عدم تشغيل سياق الكائن سيؤدي إلى E_STRICT حدث خطأ. عند تمكينه، هو أن السلوك الافتراضي للحدث هو إخراج رسالة إلى سجل الخطأ (أو Stderr)، ولكن سيسمح للبرنامج بالمتابعة.

أيضا، أي محاولة للإشارة $this عندما لا تكون في سياق كائن سيؤدي إلى E_ERROR حدث. هو سلوك هذا الحدث هو إخراج رسالة إلى سجل الخطأ (أو Stderr) والخروج من البرنامج باستخدام الحالة 255.

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

<?php
error_reporting(-1);
//error_reporting(E_ALL);

class DualNature {
  public static function fnStatic() {
    if ( isset( $this ) ) {
      // never ever gets here
      $myValue = $this->_instanceValue;
    } else {
      // always gets here
      $myValue = self::$_staticValue;
    }
    return $myValue;
  }

  public function fnInstance() {
    if ( isset( $this ) ) {
      // gets here on instance (->) reference only
      $myValue = $this->_instanceValue;
    } else {
      // gets here in all other situations
      $myValue = self::$_staticValue;
    }
    return $myValue;
  }

  public static function fnStaticDeath() {
    return $this->_instanceValue;
  }

  private static $_staticValue = 'no access to $this';
  private $_instanceValue = '$this is available';

}

$thing = new DualNature();
echo "==========\n";
printf("DualNature::fnStatic(): \"%s\"\n", DualNature::fnStatic() );
echo "==========\n";
printf("\$thing::fnStatic(): \"%s\"\n", $thing::fnStatic() );
echo "==========\n";
printf("\$thing->fnStatic(): \"%s\"\n", $thing->fnStatic() );
echo "==========\n";
printf("DualNature::fnInstance(): \"%s\"\n", DualNature::fnInstance() );
echo "==========\n";
printf("\$thing::fnInstance(): \"%s\"\n", $thing::fnInstance() );
echo "==========\n";
printf("\$thing->fnInstance(): \"%s\"\n", $thing->fnInstance() );
echo "==========\n";
printf("\$thing->fnStaticDeath(): \"%s\"\n", $thing->fnStaticDeath() );
echo "==========\n";
echo "I'M ALIVE!!!\n";

إخراج ما ورد أعلاه هو:

==========
PHP Strict Standards:  Non-static method DualNature::fnInstance() should not be called statically in example.php on line 45
DualNature::fnStatic(): "no access to $this"
==========
$thing::fnStatic(): "no access to $this"
==========
$thing->fnStatic(): "no access to $this"
PHP Strict Standards:  Non-static method DualNature::fnInstance() should not be called statically in example.php on line 47
==========
DualNature::fnInstance(): "no access to $this"
==========
$thing::fnInstance(): "no access to $this"
==========
$thing->fnInstance(): "$this is available"
==========
PHP Fatal error:  Using $this when not in object context in example.php on line 29

تغيير مستوى الإبلاغ عن الخطأ إلى E_ALL سوف قمع الافتراضي E_STRICT رسائل تحذير (لن يتم نشر الحدث)، ولكن الإشارة غير صالحة إلى $this سوف لا تزال تسبب خطأ فادح وسوف يخرج من البرنامج.

إلى جانب بناء الجملة والاختلافات الوظيفية هناك أيضا فرق الأداء الذي يهم.

يمكنك الرجوع إلى هذا أكثر أو أقل تفصيلا مقارنة الأساليب الثابتة وغير الثابتة في PHP.

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