ホームページ  >  記事  >  バックエンド開発  >  新しいメソッドを使用せずにクラス操作をインスタンス化するための PHP リフレクション学習を直接見てみる

新しいメソッドを使用せずにクラス操作をインスタンス化するための PHP リフレクション学習を直接見てみる

coldplay.xixi
coldplay.xixi転載
2020-07-23 16:54:212598ブラウズ

新しいメソッドを使用せずにクラス操作をインスタンス化するための PHP リフレクション学習を直接見てみる

この記事の例では、PHP リフレクション学習を使用して、新しいメソッドを使用せずにクラス操作をインスタンス化する方法について説明します。

PHP リフレクションの入門例に関する前の記事では、PHP リフレクションのいくつかの一般的なクラスの使用方法を簡単に紹介しましたが、まだ使用できない場合があります。リフレクションで何ができるか想像してください。さあ、

次に、リフレクション クラスを使用して何かを実行します。クラスをインスタンス化するには new キーワードを使用する必要があることは誰もが知っています。## を使用しなくても大丈夫ですか? #新しい###?答えは「はい」です。リフレクションを使用して実現できます。

関連する学習の推奨事項:
PHP プログラミングの入門から熟練度まで

最初にファイルを作成しますStudent .php:
<?php
class Student
{
  public $id;
  public $name;
  public function __construct($id,$name)
  {
    $this->id = $id;
    $this->name = $name;
  }
  public function study()
  {
    echo $this->name.&#39; is learning.....&#39;.PHP_EOL;
  }
  public function showBag(){
    echo "My bag have ".$this->bag->all();
  }
}

新しいファイル run.php

<?php
require &#39;student.php&#39;;
function make($class, $vars = []) {
  $ref = new ReflectionClass($class);
  if(!$ref->isInstantiable()) {
    throw new Exception("类{$class} 不存在");
  }
  $constructor = $ref->getConstructor();
  if(is_null($constructor)) {
    return new $class;
  }
  $params = $constructor->getParameters();
  $resolveParams = [];
  foreach ($params as $key=>$value) {
    $name = $value->getName();
    if(isset($vars[$name])) {
      $resolveParams[] = $vars[$name];
    } else {
      $default = $value->isDefaultValueAvailable() ? $value->getDefaultValue() : null;
      if(is_null($default)) {
        if($value->getClass()) {
          $resolveParams[] = make($value->getClass()->getName(), $vars);
        } else {
          throw new Exception("{$name} 没有传值且没有默认值。");
        }
      } else {
        $resolveParams[] = $default;
      }
    }
  }
  return $ref->newInstanceArgs($resolveParams);
}

run.php を作成します。make 関数は、クラスをインスタンス化するために作成する関数です。最初のパラメータはクラスに渡されます。 name. の 2 番目のパラメーターは、クラスのコンストラクターに渡す必要があるパラメーター データです。

Student のコンストラクターのパラメーターに応じて、いくつかの状況があります: (次のコードは、さまざまな状況に応じて run.php に追加してください)

ケース 1: $ が存在しない指定された name の値

try {
  $stu = make(&#39;Student&#39;, [&#39;id&#39; => 1]);
  print_r($stu);
  $stu->study();
} catch (Exception $e) {
  echo $e->getMessage();
}
$name がコンストラクターにデフォルト値を持たない場合、エラーが報告されます。$name のデフォルト値を提供するように Student クラスを少し変更することができます。エラーが報告されました。

ケース 2 は $name

try {
  $stu = make(&#39;Student&#39;, [&#39;id&#39; => 1, &#39;name&#39; => &#39;li&#39;]);
  print_r($stu);
  $stu->study();
} catch (Exception $e) {
  echo $e->getMessage();
}

の値を提供します。ケース 3 では、student.php

<?php
class Bag{
  public function name(){
    return "学生包".PHP_EOL;
  }
}
class Student
{
  public $id;
  public $name;
  public function __construct($id, $name="xxx", Bag $bag)
  {
    $this->id = $id;
    $this->name = $name;
    $this->bag = $bag;
  }
  public function study()
  {
    echo $this->name.&#39; is learning.....&#39;.PHP_EOL;
  }
  public function showBag(){
    echo "My bag is ".$this->bag->name();
  }
}
を変更しましょう。パラメータ $bag が Student クラスに追加され、型は Bag であることがわかります。

今すぐ実行してください

<?php
try {
  $stu = make(&#39;Student&#39;, [&#39;id&#39; => 1, &#39;name&#39; => &#39;li&#39;]);
  print_r($stu);
  $stu->study();
  $stu->showBag();
} catch (Exception $e) {
  echo $e->getMessage();
}

コンストラクターの 3 番目のパラメータ $bag が自動的にインスタンス化されることがわかります。を作成し、Student クラスのコンストラクターに渡します。この部分は非常に重要です。この部分は、依存関係の注入を実装するために使用できます。オブジェクトを手動でインスタンス化する必要はありません。対応するクラスに従ってオブジェクトを自動的にインスタンス化できます。これにより、クラス間の分離が実現します。 Laravel を学習したことがある場合は、これに精通しているはずです。

以上が新しいメソッドを使用せずにクラス操作をインスタンス化するための PHP リフレクション学習を直接見てみるの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjb51.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。