передать параметр из промежуточного программного обеспечения конвейера в фабричный класс в 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 У меня нет доступа к запросу.
Любая попытка доступа к Interop\Http\ServerMiddleware\MiddlewareInterface или же Psr\Http\Message\ServerRequestInterface в * Factory.php возникает такая же ошибка.

Есть ли способ передать параметр из промежуточного программного обеспечения конвейера в фабричный класс?

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

И теперь во всех следующих промежуточных программах вы можете получить соединение по умолчанию.

ОБНОВИТЬ:

Как упоминалось в комментариях, для этого требуется вставить контейнер, что считается плохой практикой. Как насчет того, чтобы обернуть их в общий класс соединения и установить требуемый из 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;
}
}

Или вы можете внедрить только конфигурацию и создать соединение с базой данных, которое действительно необходимо. Сохраните его в свойстве для кэширования (как это делает контейнер).

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]