Недавно я начал работать с Symfony 4 и с нетерпением жду установки базы данных по умолчанию в зависимости от субдомена.
Речь идет о приложении, которое мне нужно развернуть для нескольких клиентов, и у каждого из них есть своя конкретная база данных.
я начал работать с соединениями, как показано ниже. по идее было бы установить раз и навсегда соединение по умолчанию с переменной из env, но не знаю как.
Я делаю это правильно?
doctrine:
dbal:
default_connection: customer1
connections:
customer1:
url: '%env(DATABASE_CUSTOMER1_URL)%'
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
customer2:
url: '%env(DATABASE_CUSTOMER2_URL)%'
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci




Вы находитесь на правильном пути с точки зрения конфигурации. Но имейте в виду, что эти соединения не запускаются поддоменом HTTP-запроса, а просто подключаются к другому серверу базы данных на основе вызова в реальном PHP-коде.
Ваша переменная envDATABASE_CUSTOMER?_URL должна указывать соединение с экземпляром MySQL, что-то вроде 'mysql://user:secret@localhost/mydb'
И конфигурация доктрины YAML должна быть отформатирована немного по-другому и должна включать EntityManager config.
doctrine:
dbal:
default_connection: customer1
connections:
customer1:
url: '%env(DATABASE_CUSTOMER1_URL)%'
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
customer2:
url: '%env(DATABASE_CUSTOMER2_URL)%'
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
orm:
default_entity_manager: customer1
entity_managers:
customer1:
connection: customer1
customer2:
connection: customer2
https://symfony.com/doc/current/doctrine/multiple_entity_managers.html
Теперь вы можете указать, какой Connection/EntityManager вы хотите использовать. Вы можете различать их, например. в ваших контроллерах с помощью http-хоста.
public function someAction(Request $request)
{
if ($request->getHttpHost() === 'customer2url.com') {
$em = $this->getDoctrine()->getManager('customer2');
} else {
$em = $this->getDoctrine()->getManager();
}
}
или позвоните в репозиторий
$this->getDoctrine()->getRepository(Entity::class, 'customer1')
тогда я полагаю, вам нужно пойти глубже и установить конкретную EntityManager службу с правильным подключением в прослушивателе ядра symfony или установить разные EntityManager для каждой среды, например. customer1_prod, customer2_prod
и отсортируйте, какой env запускается в конфигурации веб-сервера
Другой способ — создать отдельные среды и соответствующие index_*.php файлы, на которые вы указываете свой веб-сервер. Практически создайте 2 новые копии файла записи приложения index.php — public/index_customer1.php и public/index_customer2.php. Внутри вы меняете среду, которую использует Symfony:
<?php
...
$kernel = new AppKernel('customer1', false); # or new AppKernel('customer2', false)
...
?>
И теперь вам нужно иметь отдельную конфигурацию Doctrine для обеих этих сред. В config/packages/customer1/config.yml:
imports:
- { resource: '../prod/' } # imports default prod env config
doctrine: # specify different database connection for whole env
dbal:
default_connection: default
connections:
default:
url: '%env(DATABASE_CUSTOMER1_URL)%'
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
и в config/packages/customer2/config.yml
imports:
- { resource: '../prod/' }
doctrine:
dbal:
default_connection: default
connections:
default:
url: '%env(DATABASE_CUSTOMER2_URL)%'
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
https://symfony.com/doc/master/configuration/environments.html
И вам нужно настроить свой веб-сервер так, чтобы он указывал на разные index.php в зависимости от домена.
Вы пробовали что-то подобное?
В вашем бутстрапе:
// load all the .env files
// (new Dotenv(false))->loadEnv(dirname(__DIR__).'/.env');
$d = new Dotenv(false);
$d->loadEnv(dirname(__DIR__).'/.env');
$s = dirname(__DIR__).'/.env.'.filter_input(INPUT_SERVER, 'SERVER_NAME');
if (is_readable($s) ) {
$d->load($s);
}
И создайте другое .env.server_name с
# your server_name database
DATABASE_URL=mysql://user:secret@localhost/mydb
Профайлер Symfony

Я был здесь. Вам не нужно использовать отдельные соединения или среды. Добавление новой среды означало бы добавление тонны файлов кеша.
Вы можете установить переменные среды на уровне веб-сервера в зависимости от поддомена, вы можете использовать VirtualDocumentRoot в apache или просто псевдоним сервера с подстановочными знаками в Nginx.
Определите переменную среды для каждого поддомена на вашем веб-сервере, и вы сможете использовать ее в своих файлах конфигурации.
Это не совсем то, что я ищу. Мне не нужно указывать, какое соединение я хочу использовать, но установить его определенно в соответствии с поддоменом. Речь идет о приложении, которое мне нужно развернуть для нескольких клиентов, и у каждого из них есть своя конкретная база данных.