Инжектор зависимостей разрешает зависимости вашего класса и гарантирует, что при создании экземпляра класса будут внедрены правильные объекты.

Я могу порекомендовать только один инжектор: 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.

Поздравляем, вы успешно заложили основу для своего приложения.

Наверх