[英]pass parameter from pipeline middleware to factory class in zend expressive 2
我想根据URL连接到其他数据库。 我尝试设置请求属性并在*Factory.php
获取该属性。
我编辑autoload/pipeline.php
:
<?php
$app->pipe(UrlHelperMiddleware::class);
$app->pipe(\App\Action\Choose::class);
$app->pipeDispatchMiddleware();
在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);
}
主要问题是在*Factory.php
我无法访问请求。
任何尝试访问* Factory.php中的Interop\\Http\\ServerMiddleware\\MiddlewareInterface
或Psr\\Http\\Message\\ServerRequestInterface
尝试都会产生相同的错误。
有什么方法可以将参数从管道中间件传递给工厂类?
如果您使用zend-servicemanager,则可以尝试以下操作(只是一个理论,未经测试):
在您的配置中创建2个数据库工厂: 'db.connection.a' => DbFactoryA::class, 'db.connection.b' => DbFactoryB::class,
然后根据路由,在Choose
加载所需的连接,并将其作为默认连接传递到容器。 $db = $container->get('db.connection.a'); $container->setService('db.connection.default', $db);
现在,在以下所有中间件中,您都可以获取默认连接。
更新:
如评论中所提到的,这要求注入容器,这被认为是不好的做法。 您如何将两者包装在一个通用的连接类中,并从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;
}
}
或者,您可以只注入配置并创建真正需要的数据库连接。 将其存储在用于缓存的属性中(就像容器一样)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.