首页 PHP 正文
176

PHP类的后期静态绑定

  • yiqingpeng
  • 2018-09-18
  • 0
  •  
主要对比self关键字与static关键字的区别,self永远指向定义它的类,是静态值,static指向调用它的类,是动态值。特别是在单例模式下,在没有彻底理解self与static的情况下,很容易坠入逻辑陷阱。
<?php
class A{
	protected static $instance;
	protected static $instance_p;
	
	public static function singleton(){
		if (!static::$instance) {
			$instance = new static();
			static::$instance = $instance;
		}
		return static::$instance;
	}
	
	public static function singleton_p(){
		if (!self::$instance_p) {
			$instance = new self();//所有继承A的子类调用singleton_p实例化的都是A.
			self::$instance_p = $instance;
		}
		return self::$instance_p;//instance class is A.
	}
	
	public static function who(){
		echo 'Called A who, ', __CLASS__, ' ', self::class, ' ', static::class, "</br>";
	}
	
	public static function callWho(){
		self::who();
		static::who();
	}
}

class B extends A{
	protected static $instance;
	protected static $instance_p;
	
	public static function who(){
		echo 'Called B who, ', __CLASS__, ' ', self::class, ' ', static::class, "</br>";
	}
	
	public static function callWho(){
		parent::callWho();
		self::who();
		static::who();
	}
}

class C extends A{
	protected static $instance;
	protected static $instance_p;
	
}
B::callWho();
//output, format  messages, _CLASS_ self::class static::class
//Called A's who, A A B
//Called B's who, B B B
//Called B's who, B B B
//Called B's who, B B B
echo "</br>";
$b = B::singleton();
echo get_class($b), "<br>";//B
$c = C::singleton();
echo get_class($c), "</br>";//C

$b2 = B::singleton_p();
echo get_class($b2), "</br>";//A
$c2 = C::singleton_p();
echo get_class($c2), "</br>";//A
?>
另外我们要考虑到,B和C中的属性$instance是必须的,这样才能保证彼此互不干扰。
如果B和C都去掉$instance的话,那么它们将同时继承父类A的$instance属性,
这样一来,B和C将只能持有一个共同的$instance,这个$instance到底是谁的实例,
取决于哪个类最先被实例化。比如B最先调用了singleton方法,那么C再调用singleton方法时,
是无法重新创建实例的,它只能沿用B的那个实例。

正在加载评论...