質問

何遅静的バインディングPHP?

役に立ちましたか?

解決

あなたは間違いなく読む必要が遅延静的束縛する PHPマニュアルインチしかし、私はあなたに簡単な要約を与えることをしようとするでしょう。

基本的には、selfキーワードは継承の同じ規則に従わないという事実に帰着します。 selfは常にそれが使用されているクラスに解決されます。これは、親クラスのメソッドを作成し、子クラスからそれを呼び出す場合はご想像のとおり、selfが子供を参照しないことを意味します。

バインディング遅延静的は、この特定の欠点に対処しstaticキーワード、のための新たな用途を紹介しています。あなたがstaticを使用する場合、それはつまり、あなたが最初にそれを使用するクラスを表します。それランタイムクラスに「バインド」ます。

これらは、その背後にある二つの基本的な概念です。 selfがプレイしているときparentstaticstaticが動作方法が微妙なことが、そうではなく、より詳細に行くことができ、私は強くあなたがマニュアルページの例を検討することをお勧めします。あなたは、各キーワードの基本を理解すれば、例は、あなたが取得するつもりだ結果の種類を見ることがかなり必要です。

他のヒント

は、PHP 5.3.0のように、PHPは静的継承のコンテキストで呼び出されたクラスを参照するために使用することができる後半スタティックバインディングと呼ばれる機能を実装します。

最初に、実行時に呼び出されたクラスを参照してキーワードを導入することにより、その制限を解決する

後期静的バインディング試みます。それは、新しいキーワードを紹介するのではなく、すでに予約されたstaticを使用しないことを決めた。

の例を見てみましょう。

<?php
    class Car
    {
        public static function run()
        {
            return static::getName();
        }

        private static function getName()
        {
            return 'Car';
        }
    }

    class Toyota extends Car
    {
        public static function getName()
        {
            return 'Toyota';
        }
    }

    echo Car::run(); // Output: Car
    echo Toyota::run(); // Output: Toyota
?>

最後の「非転送コール」で指定されたクラスを格納することによりlate static bindings作品。静的メソッド呼び出しの場合、これは明示的に指定されたクラス(::演算子の左側にある通常1)です。非静的メソッド呼び出しの場合には、オブジェクトのクラスである。

A "転送電話" はself::parent::static::によって導入された静的なものであるか、クラス階層に上がる場合、forward_static_call()ます。

関数get_called_class()は、その範囲を紹介するというクラスの名前とstatic::の文字列を取得するために使用することができます。

ではない非常に明白な振る舞いがあります:

次のコードは、 'alphabeta' を生成ます。

class alpha {

    function classname(){
        return __CLASS__;
    }

    function selfname(){
        return self::classname();
    }

    function staticname(){
        return static::classname();
    }
}

class beta extends alpha {

    function classname(){
        return __CLASS__;
    }
}

$beta = new beta();
echo $beta->selfname(); // Output: alpha
echo $beta->staticname(); // Output: beta
我々はベータクラスからクラス名関数の宣言を削除する場合は、

しかし、私たちは、結果として「alphaalpha」を取得しています。

私は引用から:"PHPマスターを書く最先端することが可能になっている。

下旬に静的に結合した機能が導入されたphp5.3.可能で を継承における静的メソッドからの親クラスを参照 子のクラスが呼び出されます。

この意味での抽象クラスのstaticメソッドは、 参照の子供クラスのコンクリート実装を使用 静::法) 表記の代わりにして、自分で設定する方法().

お気軽にぜひ、公式のphpの文書などのhttp://php.net/manual/en/language.oop5.late-static-bindings.php


の明確な説明を下旬に静的に結合する簡単な例です。の二つのクラス定義は、以下を読みます。

class Vehicle {
    public static function invokeDriveByStatic() {
        return static::drive(); // Late Static Binding
    }
    public static function invokeStopBySelf() {
        return self::stop(); // NOT Late Static Binding
    }
    private static function drive(){
        return "I'm driving a vehicle";
    }
    private static function stop(){
        return "I'm stopping a vehicle";
    }
}

class Car extends Vehicle  {
    protected static function drive(){
        return "I'm driving a CAR";
    }
    private static function stop(){
        return "I'm stopping a CAR";
    }
}

れた親クラス(車両)、子供クラス(車)です。の親クラスは、2つのpublicメソッド:

  • invokeDriveByStatic
  • invokeStopBySelf

の親クラスまたは2個の方法:

  • drive
  • stop

児童クラスオーバーライドの2つの方法:

  • drive
  • stop

プラグインのインストールを行公開方法

  • invokeDriveByStatic
  • invokeStopBySelf

自分自身に尋ね:クラスを呼び出し invokeDriveByStatic / invokeStopBySelf?親会社又は子どものですか。

しくは以下:

// This is NOT Late Static Binding
// Parent class invokes from Parent. In this case Vehicle.
echo Vehicle::invokeDriveByStatic(); // I'm driving a vehicle
echo Vehicle::invokeStopBySelf(); // I'm stopping a vehicle

// This is Late Static Binding.
// Child class invokes an inherited method from Parent.
// Child class = Car, Inherited method = invokeDriveByStatic().
// ...
// The inherited method invokes a method that is overridden by the Child class.
// Overridden method = drive()
echo Car::invokeDriveByStatic(); // I'm driving a CAR

// This is NOT Late Static Binding
// Child class invokes an inherited method from Parent.
// The inherited method invokes a method inside the Vehicle context.
echo Car::invokeStopBySelf(); // I'm stopping a vehicle

static キーワードに使用されるシングルトンデザインパターンです。参照リンク: https://refactoring.guru/design-patterns/singleton/php/example

最も簡単な例を示します。
注意 自::$c

class A
{
    static $c = 7;

    public static function getVal()
    {
        return self::$c;
    }
}

class B extends A
{
    static $c = 8;
}

B::getVal(); // 7

遅めの静的結合の注意 静::$c

class A
{
    static $c = 7;

    public static function getVal()
    {
        return static::$c;
    }
}

class B extends A
{
    static $c = 8;
}

B::getVal(); // 8

abstract class Builder {
    public static function build() {
        return new static;
    }
}

class Member extends Builder {
    public function who_am_i() {
         echo 'Member';
    }
}

Member::build()->who_am_i();

からそれを見て「なぜ私はこれを使用するのでしょうか?」視点は、それは基本的に静的メソッドは/ラン解釈されているからコンテキストを変更する方法です。

selfでは、コンテキストは、最初にメソッドを定義したものです。 staticと、それはあなたがからそれを呼び出している一つだ。

あなたは子クラスに静的変数を更新する場合にも、見て。私はこの(やや)予期しない結果を見つけた子Bの更新の子C:

class A{
    protected static $things;
}

class B extends A {
    public static function things(){
        static::$things[1] = 'Thing B';
        return static::$things; 
    }
}

class C extends A{
    public static function things(){
        static::$things[2] = 'Thing C';
        return static::$things;        
    }
}

print_r(C::things());
// Array (
//   [2] => Thing C
// )

B::things();

print_r(C::things()); 
// Array (
//    [2] => Thing C
//    [1] => Thing B
// )

あなたは、たとえば、それぞれの子クラスで同じ変数を宣言することによって、それを修正することができます:

class C extends A{
    protected static $things; // add this and B will not interfere!

    public static function things(){
        static::$things[2] = 'Thing C';
        return static::$things;        
    }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top