Я пытаюсь получить доступ к $container
из своего промежуточного программного обеспечения, но мне не очень везет.
В моем файле index.php
у меня есть
require '../../vendor/autoload.php';
include '../bootstrap.php';
use somename\Middleware\Authentication as Authentication;
$app = new \Slim\App();
$container = $app->getContainer();
$app->add(new Authentication());
А еще у меня есть такой класс Authentication.php
namespace somename\Middleware;
class Authentication {
public function __invoke($request, $response, $next) {
$this->logger->addInfo('Hi from Authentication middleware');
Но я получаю сообщение об ошибке
Неопределенное свойство: somename \ Middleware \ Authentication :: $ logger in ***
Я также пробовал добавить в класс следующий конструктор, но тоже не получаю радости.
private $container;
public function __construct($container) {
$this->container = $container;
}
Может ли кто-нибудь помочь?
2 ответа
Лучшая практика реализации промежуточного программного обеспечения выглядит примерно так:
Поместите этот код в раздел зависимостей:
$app = new \Slim\App();
$container = $app->getContainer();
/** Container will be passed to your function automatically **/
$container['MyAuthenticator'] = function($c) {
return new somename\Middleware\Authentication($c);
};
Затем внутри вашего класса аутентификации создайте функцию конструктора, как вы упомянули: namespace somename \ Middleware;
class Authentication {
protected $container;
public function __invoke($request, $response, $next)
{
$this->container->logger->addInfo('Hi from Authentication middleware');
}
public function __construct($container) {
$this->container = $container;
}
/** Optional : Add __get magic method to easily use container
dependencies
without using the container name in code
so this code :
$this->container->logger->addInfo('Hi from Authentication middleware');
will be this :
$this->logger->addInfo('Hi from Authentication middleware');
**/
public function __get($property)
{
if ($this->container->{$property}) {
return $this->container->{$property};
}
}
}
После того, как внутри вашего index.php добавьте промежуточное ПО, используя разрешение имен следующим образом:
$app->add('MyAuthenticator');
Я не согласен с ответом Али Кавиани. При добавлении этой функции __magic (__get
) PHP, код будет намного сложнее протестировать.
Все необходимые зависимости должны быть указаны в конструкторе. Преимущество состоит в том, что вы можете легко увидеть, какие зависимости имеет класс, и поэтому вам нужно только имитировать эти классы в модульных тестах, иначе вам пришлось бы создавать контейнер в каждом тесте. Также Keep It Simple Stupid
Я покажу это на примере регистратора:
class Authentication {
private $logger;
public function __construct($logger) {
$this->logger = $logger;
}
public function __invoke($request, $response, $next) {
$this->logger->addInfo('Hi from Authentication middleware');
}
}
Затем добавьте в контейнер промежуточное ПО с параметром logger:
$app = new \Slim\App();
$container = $app->getContainer();
$container['MyAuthenticator'] = function($c) {
return new somename\Middleware\Authentication($c['logger']);
};
Примечание: указанную выше регистрацию в контейнере можно выполнить автоматически с помощью PHP-DI Slim. (но это также должно быть медленнее).
Похожие вопросы
Связанные вопросы
Новые вопросы
php
PHP - это широко используемый высокоуровневый, динамический, объектно-ориентированный и интерпретируемый язык сценариев, в первую очередь предназначенный для серверной веб-разработки. Используется для вопросов о языке PHP.