简体   繁体   English

如何从路线呼叫Container?

[英]How to call for Container from Routes?

I have created a Router based on Fast-rout and Container based on PHP-DI . 我已经创建了一个基于Fast-rout的路由器和基于PHP-DI的 Container。

It is a fragment of my Router's code: 它是我的路由器代码的一个片段:

$container = require __DIR__ . '/../config/Container.php';
$logger = $container->get(myLogger::class); 

$routes = simpleDispatcher(function (RouteCollector $r) {
    $routes = include('config/Routes.php');

    foreach ($routes as $key => $route) {
       $r->addRoute($route[0], $route[1], $route[2] );  
    }

});

$logger->warning('123'); 


$middlewareQueue[] = new FastRoute($routes);
$middlewareQueue[] = new RequestHandler($container);

$requestHandler = new Relay($middlewareQueue);
$requestHandler->handle(ServerRequestFactory::fromGlobals());

You could see that I call for Logger from the Container instance. 您可以看到我从Container实例调用Logger。 However, I have no idea how to pass container into Classes which are being initialized through the Router. 但是,我不知道如何将容器传递到通过路由器初始化的类。

For example, if I request ' /3 ' in a browser there is TestMe class is running ( route ['GET', '/3', TestMe::class] ). 例如,如果我在浏览器中请求' /3 ',则运行TestMe类( route ['GET', '/3', TestMe::class] )。 And I am able to render page or emit response from it. 我能够呈现页面或从中发出响应。 But I can't to use $container from it although looks like I add it into middleware: $middlewareQueue[] = new RequestHandler($container); 但我不能使用$ container,虽然看起来我把它添加到中间件中: $middlewareQueue[] = new RequestHandler($container);

I take it that new RequestHandler($container); 我把它new RequestHandler($container); is also from Relay, which uses the container for resolving requests as a middleware but does not pass it around otherwise because it would be a service locator. 也是来自Relay,它使用容器将请求作为中间件解析,但不会传递它,否则因为它将是一个服务定位器。

1. Quick clarification about "using" the container in classes. 1.快速说明在课堂上“使用”容器。

Rather than trying to pass the container to the classes, use the container to inject each class with its dependencies, ideally with type-hinting. 而不是尝试将容器传递给类,使用容器为每个类注入其依赖项,理想情况下使用类型提示。

For instance, if you want to use that logger in a class, it should not be through $container->get(myLogger::class) . 例如,如果要在类中使用该记录器,则不应该通过$container->get(myLogger::class) Instead, something like this: 相反,这样的事情:

use myLogger;

class MyClass

public $logger;

public function __construct(myLogger $logger)
{
    $this->logger = $logger;
}

You can then use $this->logger in the methods. 然后,您可以在方法中使用$this->logger

2. container working with the router: 2.使用路由器的容器:

What you want to achieve should be the last middleware before the dispatch. 你想要实现的应该是发送之前的最后一个中间件。

  • It should have the container in its constructor. 它应该在其构造函数中包含容器。
  • It should receive the matched route and based on its definitions it should initialize the matched class (or function). 它应该接收匹配的路由,并根据其定义初始化匹配的类(或函数)。
  • During this initialization, it can inject that class with its dependencies. 在此初始化期间,它可以为该类注入其依赖项。

There are two good examples I suggest you consider. 我建议你考虑两个很好的例子。 First the Harmony library and you see how it uses the container as described above. 首先是Harmony库 ,你可以看到它如何使用上面描述的容器。 Second, since you're using custom versions of FastRoute and PHP-DI, look at the index file of the PHP-DI demo . 其次,由于您使用的是FastRoute和PHP-DI的自定义版本,请查看PHP-DI演示的索引文件。 Although it's not a psr-15 use, it shows how to use PHP-DI to call matched routes of FastRoute. 虽然它不是psr-15使用,但它显示了如何使用PHP-DI来调用FastRoute的匹配路由。

Good luck to you. 祝你好运。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM