何遅静的バインディングPHP?
-
19-09-2019 - |
質問
何遅静的バインディングPHP?
解決
あなたは間違いなく読む必要が遅延静的束縛する PHPマニュアルインチしかし、私はあなたに簡単な要約を与えることをしようとするでしょう。
基本的には、self
キーワードは継承の同じ規則に従わないという事実に帰着します。 self
は常にそれが使用されているクラスに解決されます。これは、親クラスのメソッドを作成し、子クラスからそれを呼び出す場合はご想像のとおり、self
が子供を参照しないことを意味します。
バインディング遅延静的は、この特定の欠点に対処しstatic
キーワード、のための新たな用途を紹介しています。あなたがstatic
を使用する場合、それはつまり、あなたが最初にそれを使用するクラスを表します。それランタイムクラスに「バインド」ます。
これらは、その背後にある二つの基本的な概念です。 self
がプレイしているときparent
、static
とstatic
が動作方法が微妙なことが、そうではなく、より詳細に行くことができ、私は強くあなたがマニュアルページの例を検討することをお勧めします。あなたは、各キーワードの基本を理解すれば、例は、あなたが取得するつもりだ結果の種類を見ることがかなり必要です。
他のヒント
は、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;
}
}