Могу ли я использовать отложенную загрузку с фабриками?Php

Кемеровские программисты php общаются здесь
Ответить
Anonymous
 Могу ли я использовать отложенную загрузку с фабриками?

Сообщение Anonymous »

В моем приложении есть некоторые определения зависимостей PHP-DI, которые привязаны к фабрикам, производящим экземпляры PDO, например:

Код: Выделить всё

$appConfig = [...];
$config1 = $appConfig['mysql'];
$config2 = $appConfig['mssql'];

$builder = new ContainerBuilder();
$containerBuilder->useAttributes(true);
$builder->addDefinitions([
'mysql' => factory(fn(ContainerInterface $c) => new PDO('...', $config1['user'], $config1['pass'])),
'mssql' => factory(fn(ContainerInterface $c) => new PDO('...', $config2['user'], $config2['pass'])),
]);
Я хочу лениво загружать эти экземпляры PDO в классы, которые их используют, чтобы соединения с базой данных устанавливались только в том случае, если используются PDO. Рассмотрим следующее:

Код: Выделить всё

class MyClass
{
private PDO $mysql;
private PDO $mssql;

#[Inject(['mysql', 'mssql'])]
public function __construct(PDO $mysql, PDO $mssql)
{
$this->mysql = $mysql;
$this->mssql = $mssql;
}

public function foo()
{
$ps = $this->mysql->prepare('...');
$ps->execute();
return $ps->fetchAll();
}

public function bar()
{
$ps = $this->mssql->prepare('...');
$ps->execute();
return $ps->fetchAll();
}
}
В этом сценарии я не хочу, чтобы контейнер зависимостей создавал экземпляр $mysql, если foo() никогда не вызывается, а также не должен создавать $mssql, если bar() никогда не вызывается.
Теперь я мог бы сделать что-то подобное для каждого соединения:

Код: Выделить всё

class MySql
{

private array $config;
private ?PDO $pdo = null;

#[Inject('appconfig')]
public function __construct(array $appConfig)
{
$this->config = $appConfig['mysql'];
}

public function getPdo(): PDO
{
if (is_null($this->pdo))
$this->pdo = new PDO('...', $this->config['user'], $this->config['pass']);
return $this->pdo;
}
}
А затем используйте autowire и lazy для определения:

Код: Выделить всё

$builder->addDefinitions([
'mysql' => autowire(MySql::class)->lazy(),
'mssql' => autowire(MsSql::class)->lazy(),
]);
Но это привело бы к появлению большого количества шаблонов, поскольку для каждого подключения к базе данных потребуется свой собственный класс.
Есть ли способ использовать отложенную загрузку на моих фабриках, чтобы избежать использования автоматического подключения?
ПРИМЕЧАНИЕ. Отложенная загрузка PHP DI работает с использованием прокси-серверов для отложенно загруженных объектов. Интересно, будет ли потенциальное решение моего сценария включать возврат прокси из фабричного метода.

Подробнее здесь: https://stackoverflow.com/questions/798 ... -factories
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Php»