1

PHPで「静的」なものがどのように機能するかを理解するのに苦労しています。誰かが私にこれに関する良いチュートリアルを教えてもらえますか?トピックを包括的にカバーするものですか?

関数内での静的変数の使用と、クラス内での静的メンバーの使用について理解しています。それを超えると、しかし、それは少しぼんやりします。

例:クラスをインスタンス化せずに静的メソッドを呼び出すことができることがわかりました。$ thisを参照しない限り、まったく同じ方法で非静的メソッドを呼び出すことができるため、これが重要である理由はわかりません。

後期静的バインディングは、スコープ解決演算子をいつどこで使用できるかとともに、もう1つの混乱の領域です。(静的であるかどうかに関係なく、親メソッドを呼び出すために使用できるようです...)

これに苦労しているのは私だけですか?

4

1 に答える 1

5

インスタンスなしで非静的メソッドを呼び出すことはできますが、これによりE_STRICT警告がトリガーされます。静的メソッドの要点は、クラスの静的変数にアクセスすることですが、多くの人は、一連のグローバル関数を定義するのではなく、ユーティリティ関数を論理的にグループ化する方法として使用します。

クラスの名前を使用して静的メソッドを呼び出す場合、たとえばClass::foo()、インスタンスがないため、ポリモーフィズムはありません。fooによって定義されたはClass直接呼び出されます。そのようなメソッドを定義していない場合は、定義しているスーパークラスが見つかるまでそのスーパークラスが検索されます。

class Parent {
    static function foo() {
        echo "Parent::foo";
    }
    static function bar() {
        echo "Parent::bar";
    }
}

class Child extends Parent {
    static function foo() {
        echo "Child::foo";
    }
}

Parent::foo();   // Parent::foo
Parent::bar();   // Parent::bar

Child::foo();    // Child::foo
Child::bar();    // Parent::bar

selfたとえば、クラスメソッドからキーワードを使用して静的メソッドを呼び出すと、呼び出し元のコードを保持しているクラスの名前self::foo()に置き換える場合と同じように機能します。self

class Parent {
    static function foo() {
        echo "Parent::foo";
    }
    static function callFoo() {
        self::foo();    // equivalent to Parent::foo()
    }
}

class Child extends Parent {
    static function foo() {
        echo "Child::foo";
    }
}

Parent::callFoo();   // Parent::foo
Child::callFoo();    // Parent::foo

staticクラスメソッドからキーワードを使用して静的メソッドをstatic::foo()呼び出す場合、たとえば、遅延静的バインディングを呼び出しています。現在のクラスで検索を開始する代わりに、foo最初に静的に参照されたクラスである現在のクラスコンテキストから検索を開始します。

class Parent {
    static function foo() {
        echo "Parent::foo";
    }
    static function callFoo() {
        static::foo();         // late static binding
    }
}

class Child extends Parent {
    static function foo() {
        echo "Child::foo";
    }
    static function callParentCallFoo() {
        Parent::callFoo();    // resets static context to Parent
    }
}

Parent::callFoo();             // Parent::foo
Child::callFoo();              // Child::foo
Child::callParentCallFoo();    // Parent::foo

後期静的バインディングは静的クラスプロパティでも同様に機能しますが、プロパティは子クラス自体で定義する必要があります。クラス(例Child::$foo = 'foo')に新しいプロパティを割り当てても、親からLSBで使用できるようにはなりません。

于 2012-05-15T01:00:20.007 に答える