Инжектор зависимостей разрешает зависимости вашего класса и гарантирует, что при создании экземпляра класса будут внедрены правильные объекты.
Я могу порекомендовать только один инжектор: Auryn. К сожалению, все известные мне альтернативы используют в своей документации и примерах антишаблон локатора сервисов (Service Locator).
Установите пакет Auryn, а затем создайте новый файл с именем Dependency.php в папке src/. Туда добавьте следующий контент:
<?php declare(strict_types = 1); $injector = new \Auryn\Injector; $injector->alias('Http\Request', 'Http\HttpRequest'); $injector->share('Http\HttpRequest'); $injector->define('Http\HttpRequest', [ ':get' => $_GET, ':post' => $_POST, ':cookies' => $_COOKIE, ':files' => $_FILES, ':server' => $_SERVER, ]); $injector->alias('Http\Response', 'Http\HttpResponse'); $injector->share('Http\HttpResponse'); return $injector;
Прежде чем продолжить, убедитесь, что вы понимаете, что делают (alias, share и define). О них можно прочитать в документации Auryn.
Вы делитесь (share) объектами HTTP, потому что нет особого смысла добавлять контент в один объект, а затем возвращать другой. Таким образом, поделившись им, вы всегда получаете один и тот же экземпляр.
Псевдоним (alias) позволяет вам указывать интерфейс в качестве подсказки вместо имени класса. Это позволяет легко переключать реализацию без необходимости возвращаться и редактировать все классы, использующие старую реализацию.
Конечно, Bootstrap.php также необходимо будет изменить. Раньше вы задавали $request и $response через new. Теперь замените на инжектор, чтобы мы везде использовали один и тот же экземпляр этих объектов.
$injector = include('Dependencies.php'); $request = $injector->make('Http\HttpRequest'); $response = $injector->make('Http\HttpResponse');
Другая часть, которую необходимо изменить — это диспетчеризация маршрута. Раньше у вас был следующий код:
$class = new $className($response); $class->$method($vars);
Измените его на такой:
$class = $injector->make($className); $class->$method($vars);
Теперь все зависимости конструктора вашего контроллера будут автоматически разрешены с помощью Auryn. Вернитесь к контроллеру домашней страницы и замените код в нем:
<?php declare(strict_types = 1); namespace Example\Controllers; use Http\Request; use Http\Response; class Homepage { private $request; private $response; public function __construct(Request $request, Response $response) { $this->request = $request; $this->response = $response; } public function show() { $content = '<h1>Hello World</h1>'; $content .= 'Hello ' . $this->request->getParameter('name', 'stranger'); $this->response->setContent($content); } }
Как видно, теперь у класса есть две зависимости. Попробуйте получить доступ к странице с помощью параметра GET, например http://localhost:8000/?name=Arthur%20Dent.
Поздравляем, вы успешно заложили основу для своего приложения.