Skip to content

后期静态绑定 #10

@DanceSmile

Description

@DanceSmile

该功能从语言内部角度考虑被命名为“后期静态绑定”。“后期绑定”的意思是说,static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的。也可以称之为“静态绑定”,因为它可以用于(但不限于)静态方法的调用。

static:: 简单用法

class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        static::who(); // 后期静态绑定从这里开始
    }
}

class B extends A {
    public static function who() {
        echo __CLASS__;
    }
}

B::test();

非静态环境下使用 static

class A {
    private function foo() {
        echo "success!\n";
    }
    public function test() {
        $this->foo();
        static::foo();
    }
}

class B extends A {
   /* foo() will be copied to B, hence its scope will still be A and
    * the call be successful */
}

class C extends A {
    private function foo() {
        /* original method is replaced; the scope of the new one is C */
    }
}

$b = new B();
$b->test();
$c = new C();
$c->test();   //fails

转发和非转发调用

class A {
    public static function foo() {
        static::who();
    }

    public static function who() {
        echo __CLASS__."\n";
    }
}

class B extends A {
    public static function test() {
        A::foo();
        parent::foo();
        self::foo();
    }

    public static function who() {
        echo __CLASS__."\n";
    }
}
class C extends B {
    public static function who() {
        echo __CLASS__."\n";
    }
}

C::test();

应用案列

获取数据库名称

class Model 
{ 
    public static function getName() 
    { 
        echo static::$name; 
    } 
} 

class Product extends Model 
{ 
    protected static $name = 'Product'; 
} 

class User extends Model 
{ 
    protected static $name = 'User'; 
} 


Product::getName(); 
User::getName(); 

通过超类创建实例对象

abstract class A{
    
    static function create(){

        //return new self();  //Fatal error: Cannot instantiate abstract class A

        return new static(); //this is the correct way

    }
    
}

class B extends A{
}

$obj=B::create();
var_dump($obj);
static::class and self::class can be used to get current class name, 
work under 5.5 and 5.6
failed in 5.3.

<?php
class a{ 
    function d() {
        echo "=== self::class ===\n";
        var_dump(self::class);
        echo "=== static::class ===\n";
        var_dump(static::class);
    }
}
class b extends a{}
class c extends b{}

a::d(); 
b::d();
c::d();

/*
Output: 

=== self::class ===
string(1) "a"
=== static::class ===
string(1) "a"
=== self::class ===
string(1) "a"
=== static::class ===
string(1) "b"
=== self::class ===
string(1) "a"
=== static::class ===
string(1) "c"

*/
    class Singleton {
        
        public static $objInstance;
    
        public static function &getInstance() {
            if (self::$objInstance == null) {
                $strClass = static::getClass();
                self::$objInstance = new $strClass;
            }
            return self::$objInstance;
        }
        
        public static function getClass() {
            return __CLASS__;
        }
    
    }

    class Foo extends Singleton {
        
        public $intBar;
        
        public function __construct() {
            $this->intBar = 1;
        }
        
        public static function getClass() {
            return __CLASS__;
        }
        
    }
    
    
    $objFooTwo = Foo::getInstance();
    $objFooTwo->intBar = 2;
    
    $objFooOne = Foo::getInstance();
    
    if ($objFooOne->intBar == $objFooTwo->intBar) {
        echo 'it is a singleton';
    } else {
        echo 'it is not a singleton';
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions