首頁  >  文章  >  後端開發  >  PHP延遲靜態綁定的深入了解

PHP延遲靜態綁定的深入了解

不言
不言原創
2018-04-09 15:24:521304瀏覽

這篇文章主要給大家介紹了關於PHP延遲靜態綁定的相關資料,在這裡分享給大家,有需要的朋友參考一下

前言

所謂延遲靜態綁定,顧名思義,靜態呼叫時::符號左側的部分的綁定是延遲,也就是說不再被解析為定義當前方法所在的類,而是在實際運行時計算的。本文主要介紹了關於PHP延遲靜態綁定的相關內容,下面話不多說了,來一起看看詳細的介紹。

嗅到了不好的味道

#這段時間看專案後台的PHP程式碼,看到了類似以下的一段程式碼,我把它抽出來:

<?php
 class DBHandler {
  function get() {}
 }

 class MySQLHandler extends DBHandler {
  // 这里一个create
  public static function create() {
   echo "MySQL";
   return new self();
  }
  public function get() {
   echo "MySQL get()";
  }
 }

 class MemcachedHandler extends DBHandler {
  // 这里又有一个create
  public static function create() {
   echo "Memcached";
   return new self();
  }
  public function get() {
   echo "Memcached get";
  }
 }

 function get(DBHandler $handler) {
  $handler->get();
 }
 $dbHandler = MySQLHandler::create();
 get($dbHandler);
?>

有沒有嗅到壞程式碼的味道?可以看到,在MySQLHandler和MemcachedHandler類別中,都有一個create函數,除掉我的輸出語句,發現它們一模一樣,這就是程式碼冗餘。是的,需要進行程式碼重構。

進行簡單的重構

#程式碼重構無所不在,只要你想,你覺的有改進,就需要敲起鍵盤開始工作。來吧,對上面的程式碼進行重構,如下:

<?php
 class DBHandler {
  public static function create() {
   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);
?>

#將create函數移到DBHandler類別中,看起來還不錯,至少少了一坨那糟糕的程式碼。

看似是錯的

#運行一下,卻發現,並沒有印出我們所期望的MySQL get( )  。什麼情況?這說明,並沒有呼叫MySQLHandler的get函數,但是程式碼明明呼叫了啊,這說明,new self() 這句程式碼有問題。這有什麼問題?這就需要說到今天總結的重點了————延遲靜態綁定。

延遲靜態綁定

#在PHP5.3以後引入了延遲靜態綁定。再看下面這段程式碼:

<?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,但我希望它輸出B,這就是問題的所在。這也是 self 和 __CLASS__ 的限制。使用 self:: 或 __CLASS__ 對目前類別的靜態引用,取決於定義目前方法所在的類別。所以,這就很好的解釋了為什麼上面的程式碼輸出了A。但是,如果我們需要輸出B呢?可以這麼乾:

<?php
 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();
?>

後期靜態綁定本想透過引入一個新的關鍵字表示執行時間最初呼叫的類別來繞過限制。簡單來說,這個關鍵字能夠讓你在上述範例中呼叫 test() 時所引用的類別是 B 而不是 A。最後決定不引入新的關鍵字,而是使用已經預留的 static 關鍵字。

這就是後期靜態綁定的根本----static關鍵字的另類用法。對於文章一開始的例子,可以這麼改:

return new static(); // 改变这里,后期静态绑定

#這種使用後期靜態綁定,在使用PHP實作23中設計模式的時候,你會感到很輕鬆的。

總結

就是很簡單的知識點,但是卻很有用,總結起來,還是查了一些資料,補充一下知識點。溫故而知新。好了,希望對大家有幫助。如果大家有什麼建議,讓我的文章寫的更好,儘管提出來,我需要大家的幫忙。

相關推薦:

PHP延遲靜態綁定static詳解

php實作後期靜態綁定


#

以上是PHP延遲靜態綁定的深入了解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn