This period of time to see the project behind the PHP code, see similar to the following section of code, I drew it out:
<?PhpClass Dbhandler { function Get() {} } Class Mysqlhandler Extends Dbhandler { Here a Create Public Static functionCreate() {Echo"MySQL"; Return New Self(); } Public function Get() {Echo"MySQL Get ()"; } } Class Memcachedhandler Extends Dbhandler { Here is another create Public Static functionCreate() {Echo"Memcached"; Return New Self(); } Public function Get() {Echo"Memcached get" } } function get (dbhandler $ Handler { $handler - >get (); } $dbHandler = Mysqlhandler::create (); get ( $dbHandler ?>
Did you smell the bad code? As you can see, in the Mysqlhandler and Memcachedhandler classes, there is a CREATE function that removes my output statements and finds them identical, which is code redundancy. Yes, code refactoring is required.
For a simple refactoring
Code refactoring is everywhere, as long as you think that you have improved, you need to start working on the keyboard. Come on, refactor the code above, as follows:
<?PhpClass Dbhandler { Public Static functionCreate() {Echo"Create"; Return New Self(); } function Get() {} } Class Mysqlhandler Extends Dbhandler { Public function Get() {Echo"MySQL Get ()"; } } Class Memcachedhandler Extends Dbhandler { Public function Get() {Echo"Memcached get" } } function get (dbhandler $ Handler { $handler - >get (); } $dbHandler = Mysqlhandler::create (); get ( $dbHandler ?>
Moving the CREATE function to the Dbhandler class looks pretty good, at least a lump of that bad code.
It seems wrong.
Run, but found, and did not print out what we expected MySQL get()
. What's the situation? This means that there is no call to Mysqlhandler's get function, but the code is clearly called, which indicates that new self()
there is a problem with this code. What's wrong with that? This needs to be the focus of today's summary ———— delay static binding.
Lazy static binding
Delayed static bindings were introduced after PHP5.3. Let's look at the following code:
<?PhpClassA{ Public Static functionW.H.O.() {Echo __class__; } Public Static functionTest() { Self::who (); } } classextends A { public< Span class= "PLN" > static function Who () { echo __class__; } } B::< Span class= "PLN" >test (); ?>
The above code outputs a, but I want it to output B, which is where the problem lies. This is self
also __CLASS__
the limit. The use self::
or __CLASS__
static reference to the current class depends on the class in which the current method is defined. So, this is a good explanation of why the above code outputs a. But what if we need to output B? Can do this:
<?PhpClassA{ Public Static functionW.H.O.() {Echo __class__; } Public Static functionTest() { Static::W.H.O. (); //there are changes here, late static bindings starting from here }} class B extends A { public function Who () Span class= "pun" >{ echo __class__;} } B::?>
Late static binding This is to bypass the restriction by introducing a new keyword that represents the class that was originally called by the runtime. Simply put, this keyword allows you to invoke test () in the above example to refer to the class B instead of a. The final decision is not to introduce a new keyword, but instead to use the static keyword that has been reserved.
This is the alternative use of the static keyword at the very end of a late-statically binding ————. For the first example of this article, you can change this:
return new static(); // 改变这里,后期静态绑定
This use of late static binding, when using PHP implementation of 23 design mode, you will feel very easy.
PHP Lazy Static binding (this article belongs to forwarding)