....
自 PHP 5.3.0 起,PHP 增加了一个叫做后期静态绑定的功能,用于在继承范围内引用静态调用的类。 当进行静态方法调用时,该类名即为明确指定的那个(通常在 ::
运算符左侧部分);当进行非静态方法调用时,即为该对象所属的类。 “后期绑定”的意思是说,static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的。也可以称之为“静态绑定”,因为它可以用于(但不限于)静态方法的调用。
解释说明 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?php class A { public static function who ( ) { echo __CLASS__ ; } public static function test ( ) { self ::who(); } } class B extends A { public static function who ( ) { echo __CLASS__ ; } } B::test();
以上例程会输出:A, 因为 self 关键词只能取到定义当前方法所在的类, 或者说它只能取到自己所在的那个类, 最终引用的类是A, 而不是B 好吧, 但是如果我们想要运行时最终运行的是B该如何呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?php class A { public static function who ( ) { echo __CLASS__ ; } public static function test ( ) { static ::who(); 以上例程会输出:B} class B extends A { public static function who ( ) { echo __CLASS__ ; } } B::test();
以上例程会输出:B
实际用法 在Laravel框架中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <?php class Model { public static function create (array $attributes = [] ) { $model = new static ($attributes ); $model ->save(); return $model ; } } class Task extends Model { } Task::create([ 'title' =>'学习laravel' , 'author' =>'pilishen' ]);
当执行Task::create()的时候,因为extends了Model,所以就到了Model里的create方法,由于$model = new static($attributes);使用了static关键词,所以此时也就相当于是执行了new Task();,也就是借助static静态绑定,我们在laravel里的自己创建的各个model,就可以共用一系列提前定义好的方法,同时在实际调用的时候,又将结果或过程只作用于自己,从而实现了一个典型的active record design pattern。
其他 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <?php class Father { public static function getSelf ( ) { return new self (); } public static function getStatic ( ) { return new static (); } } class Son extends Father {};echo get_class(Son::getSelf()); echo get_class(Son::getStatic()); echo get_class(Father::getSelf()); echo get_class(Father::getStatic());
http://pilishen.com/posts/php-late-static-bindings-in-laravel http://php.net/manual/zh/language.oop5.late-static-bindings.php