ホームページ  >  記事  >  バックエンド開発  >  PHP の遅延静的バインディングの詳細

PHP の遅延静的バインディングの詳細

不言
不言オリジナル
2018-04-09 15:24:521247ブラウズ

この記事では主に PHP の遅延静的バインディングに関する情報を紹介します。必要な方は参考にしてください。

いわゆる遅延静的バインディング。名前が示すとおり、静的呼び出し :: 記号の左側のバインディングは遅延します。つまり、現在のメソッドが定義されているクラスに解析されず、実際の実行時に計算されます。この記事では主に PHP の遅延静的バインディングに関する内容を紹介します。以下では多くを述べませんが、詳細を見てみましょう。

何か嫌な匂いがします

この間、プロジェクトのバックグラウンドで PHP コードを見ていて、次のようなコードを見つけて取り出しました。
悪いコードの匂いを嗅ぎましたか?ご覧のとおり、MySQLHandler クラスと MemcachedHandler クラスには create 関数があり、出力ステートメントを削除したところ、これらはまったく同じであることがわかりました。はい、コードのリファクタリングが必要です。

簡単なリファクタリングを実行する

コードのリファクタリングはどこにでもあり、考えて改善があると感じたら、キーボードを叩いて作業を開始する必要があります。さあ、上記のコードを次のようにリファクタリングしてください:

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

create 関数を DBHandler クラスに移動します。見た目は良くなり、悪いコードが少なくとも 1 つ減り、削除されます。

それは間違っているようです

実行してみましたが、期待した内容が出力されないことがわかりました

このコードには問題があります。これの何が問題なのでしょうか?ここで、今日の要約の焦点である遅延静的バインディングに焦点を当てます。 遅延静的バインディング

MySQL get()  。什么情况?这说明,并没有调用MySQLHandler的get函数,但是代码明明调用了啊,这说明, new self()

遅延静的バインディングは、PHP5.3 以降に導入されました。もう一度次のコードを見てください:

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

上記のコードは A を出力しますが、B を出力したいのです。これが問題です。これは、self と __CLASS__ の制限でもあります。現在のメソッドが定義されているクラスに応じて、self:: または __CLASS__ を使用した現在のクラスへの静的参照。したがって、これは、上記のコードが A を出力する理由を非常によく説明しています。しかし、B を出力する必要がある場合はどうすればよいでしょうか?これを行うことができます:

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

遅延静的バインディングは元々、実行時に最初に呼び出されるクラスを表す新しいキーワードを導入することで制限を回避しようとしていました。簡単に言うと、このキーワードを使用すると、上記の例で test() を呼び出すときに、クラス A の代わりにクラス B を参照できるようになります。最終的には、新しいキーワードを導入せず、すでに予約されている静的キーワードを使用することが決定されました。

これは、後期静的バインディングの根本であり、static キーワードの代替使用です。記事の冒頭の例では、次のように変更できます:

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

遅延静的バインディングを使用すると、PHP を使用して 23 のデザイン パターンを実装するときに非常にリラックスした気分になります。

まとめ

非常に簡単な知識ですが、まとめると、いくつかの情報を確認し、知識を補足しました。過去を振り返り、新しいことを学びましょう。わかりました、皆さんのお役に立てば幸いです。私の記事をより良くするための提案があれば、お気軽に質問してください。あなたの助けが必要です。

関連する推奨事項: PHP 遅延静的バインディング静的詳細説明

php は遅延静的バインディングを実装します


以上がPHP の遅延静的バインディングの詳細の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。