[英]pass parameter from pipeline middleware to factory class in zend expressive 2
I want to connect to different database according to URL. 我想根据URL连接到其他数据库。 I try to set request attribute and get that attribute in *Factory.php
. 我尝试设置请求属性并在*Factory.php
获取该属性。
I edit autoload/pipeline.php
: 我编辑autoload/pipeline.php
:
<?php
$app->pipe(UrlHelperMiddleware::class);
$app->pipe(\App\Action\Choose::class);
$app->pipeDispatchMiddleware();
in Choose.php
I implement process()
like this: 在Choose.php
我实现了process()
如下所示:
<?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. 主要问题是在*Factory.php
我无法访问请求。
Any try to access to Interop\\Http\\ServerMiddleware\\MiddlewareInterface
or Psr\\Http\\Message\\ServerRequestInterface
in *Factory.php raises same error. 任何尝试访问* Factory.php中的Interop\\Http\\ServerMiddleware\\MiddlewareInterface
或Psr\\Http\\Message\\ServerRequestInterface
尝试都会产生相同的错误。
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): 如果您使用zend-servicemanager,则可以尝试以下操作(只是一个理论,未经测试):
Create 2 database factories in your config: 'db.connection.a' => DbFactoryA::class, 'db.connection.b' => DbFactoryB::class,
在您的配置中创建2个数据库工厂: '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. 然后根据路由,在Choose
加载所需的连接,并将其作为默认连接传递到容器。 $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
: 您如何将两者包装在一个通用的连接类中,并从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). 将其存储在用于缓存的属性中(就像容器一样)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.