о php
Фреймворке обоих yii
, symfony
Или, может быть, laravel
Мы все балуемся нашей работой. Для пакета ресурсов, хранящегося в папке поставщик
, файлы ввода( index.php
возможно app.php
)И мы все встречаемся с ними каждый день. Но действительно ли вы знакомы с этими файлами/папками? Как полный проект развивается из чистой структуры? Какую роль играет каждая часть в структуре здания?
Внедрение зависимостей – это не SQL-инъекция
1.1 взаимосвязь между внедрением зависимостей и классом отражения
Когда дело доходит до внедрения зависимостей DI
Когда дело доходит до этого, в 90% статей упоминается статья под названием Отражение
На самом деле, это две концепции, которые отличаются друг от друга. Размышление
Является классом отражения, но внедрением зависимостей DI
Это шаблон дизайна. Как классы отражения и шаблоны проектирования могут принадлежать одному и тому же? Таким образом, их отношения являются зависимостями – внедрение зависимостей-это шаблон проектирования, основанный на классах отражения.
1.2 что такое отражение
Напишите очень простой класс A, в котором есть только один объект $a
, метод a()
.
class A { public $a; public function a() { echo __FUNCTION__; } }
Затем мы вызываем класс отражения Отражение
$A = new A(); $reflect = new ReflectionObject($A); $props = $reflect - > getproperties(); // get all objects of this class ...
Мы можем узнать все содержимое этого класса путем отражения, точно так же, как рентгеновский снимок, чтобы получить все детали класса. Однако, когда я закончил урок рефлексии, я снова заблудился. Какова цель разработки этого класса отражения? Если вы хотите знать, сколько методов/объектов содержится в исходном классе, не можете ли вы просто посмотреть на исходный класс напрямую? Зачем беспокоиться? Какое это имеет отношение к внедрению зависимостей? Не волнуйся. Давайте сначала поговорим о чем-нибудь другом, а потом оглянемся назад.
1.3 что делать с зависимостью
Теперь есть сцена, подобная этой , я хочу создать ее экземпляр B
, но B
Зависит от A
. Что мне делать? Это можно решить следующим образом.
Class A{ // do sth. } Class B{ public function __construct(A $a){ //Class B depends on a } } $a = new A(); $b = new B($a);
Это просто, не так ли? Это можно решить в два раза. Здесь нет никаких трудностей. Но если сейчас такая ситуация: есть A-Z
Есть 26 категорий, B
Класс зависит от A
, C
Класс зависит от B
и так далее. Итак, если я хочу создать экземпляр Z
Класса, что вам нужно сделать? Вы все еще используете метод, описанный на рисунке выше? Разве для создания экземпляра Z
не нужно написать 26 строк?
Есть ли способ создать экземпляр B напрямую, а затем автоматически загрузить все остальные классы? Это правда. Вам нужно использовать класс отражения, только что упомянутый выше.
newInstanceArgs($paramArr); } /** *Get the method parameters of the class, only the parameters of the type. *By recursion *@ param [type] $classname [class name] *@ param [type] $methodsname [method name] * @return [mixed] */ protected static function getMethodParams($className, $methodsName = '__construct') { //Get this class by reflection $class = new ReflectionClass($className); $paramarr = []; // record parameter and parameter type //Determine whether the class has a constructor if ($class->hasMethod($methodsName)) { //Get constructor $construct = $class->getMethod($methodsName); //Judge whether the constructor has parameters $params = $construct->getParameters(); if (count($params) > 0) { //Judge parameter type foreach ($params as $key => $param) { if ($paramClass = $param->getClass()) { //Get parameter type name $paramClassName = $paramClass->getName(); /** *Get parameter type *Use recursion here */ $args = self::getMethodParams($paramClassName); $paramArr[] = (new ReflectionClass($paramClass->getName()))->newInstanceArgs($args); } } } } return $paramArr; } /** *Methods for executing classes *@ param [type] $classname [class name] *@ param [type] $methodname [method name] *@ param [type] $params [extra parameters] * @return [type] [description] */ public static function make($className, $methodName, $params = []) { //Get an instance of a class $instance = self::getInstance($className); //Get the parameters of dependency injection required by the method $paramArr = self::getMethodParams($className, $methodName); return $instance->{$methodName}(...array_merge($paramArr, $params)); } } class A { // ... } class B { public function __construct(A $a) { // ... } } class C { public function __construct(B $b) { // ... } } $cObj = Ioc::getInstance('C');
Давайте сосредоточимся на нем Ioc
Этого класса GetMethod/| метода.
Давайте начнем с общей ситуации: этот метод использует рекурсию для обхода загруженных классов, чтобы загрузить все зависимые классы.
Сначала создается экземпляр этого метода Отражение
, а затем используется метод GetMethod
для получения метода __construct
, затем посмотрите на эту __конструкцию
Есть ли другие классы в качестве параметров, если да Рекурсивное повторение
Описанный выше процесс, пока нет никакой зависимости.
Вышесказанное является использованием Отражения
Простой пример внедрения зависимостей. Хотя это будет сложнее, чем приведенный выше пример в реальной структуре, это все равно то же самое.
Например, во многих фреймворках используется контейнер container
Концепция использования $this->getContainer()->get(ИМЯ вашего КЛАССА)
Получает класс. Что за высокотехнологичная штука этот контейнер? Не волнуйся. В конце концов, он все еще зависит от инъекции.
Позже мы подробно рассмотрим дизайн контейнера symfony.