Home  >  Article  >  Backend Development  >  A direct look at PHP reflection learning to instantiate class operations without using the new method

A direct look at PHP reflection learning to instantiate class operations without using the new method

coldplay.xixi
coldplay.xixiforward
2020-07-23 16:54:212598browse

A direct look at PHP reflection learning to instantiate class operations without using the new method

The example in this article describes the use of PHP reflection learning to instantiate class operations without the new method. I share it with you for your reference. The details are as follows:

The previous article on PHP Reflection Getting Started Example briefly introduced how to use several common classes of PHP reflection, but you may still not be able to imagine what you can do with reflection. Come on,

Next I will use the reflection class to do something. Everyone knows that you need to use the new keyword to instantiate a class. Is it okay without using new? The answer is yes, it can be achieved using reflection:

Related learning recommendations: PHP programming from entry to proficiency

First create a file 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();
  }
}

Create a new file 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. The make function is the function we write to instantiate the class. The first parameter is passed in the class name. , the second parameter is the parameter data that needs to be passed in to the constructor of the class.

There are several situations depending on the parameters of Student's constructor: (The following code, please append it to run.php according to different situations)

Case 1: No $ is provided The value of name

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

When $name does not have a default value in the constructor, an error will be reported. You can slightly modify the Student class to provide a default value for $name, and then it will not An error was reported.

Case 2 provides the value of $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();
}

Case 3, let’s change 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();
  }
}

As you can see, a parameter $bag is added to the Student class, the type is Bag

Run it now

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

You can see that the third parameter $bag of the constructor is automatically instantiated ified, and then passed to the constructor of the Student class. This part is very critical. This place can be used to implement dependency injection. We do not have to manually instantiate the object. We can automatically instantiate the object according to the corresponding class of the parameter. This achieves decoupling between classes. If you have learned Laravel, you should be familiar with this.

The above is the detailed content of A direct look at PHP reflection learning to instantiate class operations without using the new method. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:jb51.net. If there is any infringement, please contact admin@php.cn delete