简体   繁体   中英

How to call for Container from Routes?

I have created a Router based on Fast-rout and Container based on PHP-DI .

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. 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] ). 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);

I take it that 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.

1. Quick clarification about "using" the container in classes.

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) . 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.

2. container working with the router:

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. Second, since you're using custom versions of FastRoute and PHP-DI, look at the index file of the PHP-DI demo . Although it's not a psr-15 use, it shows how to use PHP-DI to call matched routes of FastRoute.

Good luck to you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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