I want to connect to different database according to URL. I try to set request attribute and get that attribute in *Factory.php
.
I edit autoload/pipeline.php
:
<?php
$app->pipe(UrlHelperMiddleware::class);
$app->pipe(\App\Action\Choose::class);
$app->pipeDispatchMiddleware();
in Choose.php
I implement process()
like this:
<?php
public function process(ServerRequestInterface $request, DelegateInterface $delegate)
{
/** @var RouteResult $route */
$route = $request->getAttribute(RouteResult::class);
if ($route->getMatchedRouteName() == 'FirstRoute' or $route->getMatchedRouteName() == 'SecondRoute') {
$request = $request->withAttribute('DB_NAME', $route->getMatchedParams()['param']);
}
return $delegate->process($request);
}
The main problem is in *Factory.php
I don't access to request.
Any try to access to Interop\\Http\\ServerMiddleware\\MiddlewareInterface
or Psr\\Http\\Message\\ServerRequestInterface
in *Factory.php raises same error.
Is there any way pass parameter from pipeline middleware to factory class?
If you use zend-servicemanager you can try this (just a theory, not tested):
Create 2 database factories in your config: 'db.connection.a' => DbFactoryA::class, 'db.connection.b' => DbFactoryB::class,
Then depending on the route, in Choose
you load the connection you need and pass it to the container as the default connection. $db = $container->get('db.connection.a'); $container->setService('db.connection.default', $db);
And now in all following middleware you can grab the default connection.
UPDATE:
As mentioned in the comments, this requires the container to be injected which is considered bad practice. How about you wrap the two in a common connection class and set the required from Choose
:
class Connection
{
private $connection;
/**
* @var ConnectionInterface
*/
private $db_a;
/**
* @var ConnectionInterface
*/
private $db_b;
public function __construct(ConnectionInterface $a, ConnectionInterface $b)
{
$this->db_a = $a;
$this->db_b = $b;
}
public function setConnection($connection)
{
if ($connection === 'a') {
$this->connection = $this->db_a;
return;
}
$this->connection = $this->db_b;
}
public function getConnection()
{
return $this->connection;
}
}
Or you can inject only the config and create the database connection that's really needed. Store it in a property for caching (like the container does).
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.