0

我想根据 URL 连接到不同的数据库。我尝试设置请求属性并在*Factory.php.
我编辑autoload/pipeline.php

<?php
$app->pipe(UrlHelperMiddleware::class);
$app->pipe(\App\Action\Choose::class);
$app->pipeDispatchMiddleware();

Choose.phpprocess()这样实现:

<?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我无法访问请求。
任何访问Interop\Http\ServerMiddleware\MiddlewareInterface或访问Psr\Http\Message\ServerRequestInterface*Factory.php 的尝试都会引发相同的错误。

有没有办法将参数从管道中间件传递到工厂类?

4

1 回答 1

0

如果你使用 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);

现在在所有以下中间件中,您可以获取默认连接。

更新:

正如评论中提到的,这需要注入容器,这被认为是不好的做法。您如何将两者包装在一个公共连接类中并设置所需的 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;
    }
}

或者您可以只注入配置并创建真正需要的数据库连接。将其存储在用于缓存的属性中(就像容器一样)。

于 2017-04-07T12:35:27.457 回答