как правильно подключить класс, через конструктор?
Я пишу один контроллер для главной страницы, и у меня не получается добавить туда классы. Так же я использую в этом проекте шаблонизатор "Twig" и маршрутизатор Slim. И вот такую ошибку выдает Slim:
'Type: ArgumentCountError
Code: 0
Message: Argument 1 passed to Blog\Route\HomePage::__construct() must be an instance of Blog\LatestPosts, null given, called in D:\web-programmig\OpenServer\domains\testsite\vendor\slim\slim\Slim\CallableResolver.php on line 154
File: D:\web-programmig\OpenServer\domains\testsite\src\Route\HomePage.php
Line: 19'
Вот мой код контроллера:
<?php
declare(strict_types=1);
namespace Blog\Route;
use Blog\LatestPosts;
use Blog\OtherClasses\ApiClass;
use Blog\OtherClasses\CookiesClass;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Twig\Environment;
class HomePage
{
private LatestPosts $latestPosts;
private Environment $view;
private CookiesClass $cookie;
private ApiClass $weatherData;
public function __construct(LatestPosts $latestPosts, Environment $view,
CookiesClass $cookie, ApiClass $weatherData)
{
$this->latestPosts = $latestPosts;
$this->view = $view;
$this->cookie = $cookie;
$this->weatherData = $weatherData;
}
public function execute(Request $request, Response $response): Response
{
$posts = $this->latestPosts->get(3);
$body = $this->view->render('index.twig', [
'posts' => $posts,
'cookie' => $this->cookie->getUsernameCookie(),
'regCookie' => $this->cookie->getRegCookie(),
'weatherData' => $this->weatherData->getWeatherData('Kostanay')
]);
$response->getBody()->write($body);
return $response;
}
}
Я долго пытался разобраться, но ничего в голову не пришло. Это важный для меня проект так, как это мой первый сайт. Надеюсь на вашу помощь. Заранее большое спасибо.
Ответы (1 шт):
Вам нужно использовать контейнер зависимостей для этих целей. В Slim 3 используется pimple, в 4й версии его по умолчанию нет, но можно добавить любой, реализующий интерфейс psr/container.
Вам нужно добавить контроллер в контейнер, примерно так (зависит от конкретного контейнера, в примере pimple):
<?php
$container[\Blog\Route\LatestPosts::class] = function(\Pimple\Container $pimple) {
return new \Blog\Route\LatestPosts(
// тут параметры LatestPosts
);
};
$container[\Twig\Environment::class] = function(\Pimple\Container $pimple) {
return new \Twig\Environment(
// тут параметры twig
);
};
$container[\Blog\OtherClasses\CookiesClass::class] = function(\Pimple\Container $pimple) {
return new \Blog\OtherClasses\CookiesClass(
// тут параметры кук
);
};
$container[\Blog\OtherClasses\ApiClass::class] = function(\Pimple\Container $pimple) {
return new \Blog\OtherClasses\ApiClass(
// тут параметры апи
);
};
$container[\Blog\Route\HomePage::class] = function(\Pimple\Container $pimple) {
return new \Blog\Route\HomePage(
$pimple[\Blog\Route\LatestPosts::class],
$pimple[\Twig\Environment::class],
$pimple[\Blog\OtherClasses\CookiesClass::class],
$pimple[\Blog\OtherClasses\ApiClass::class]
);
};
А в роутах указываете нужный метод
$slim->get('/', \Blog\Route\HomePage::class . ':execute');
// с версии 4.8 можно так:
$slim->get('/', [\Blog\Route\HomePage::class, 'execute']); // тогда в шторме по ctrl+click можно будет проваливаться в метод