Как установить базу данных по умолчанию в зависимости от субдомена в symfony 4.2

Недавно я начал работать с 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
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
0
0
594
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы находитесь на правильном пути с точки зрения конфигурации. Но имейте в виду, что эти соединения не запускаются поддоменом 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')

Это не совсем то, что я ищу. Мне не нужно указывать, какое соединение я хочу использовать, но установить его определенно в соответствии с поддоменом. Речь идет о приложении, которое мне нужно развернуть для нескольких клиентов, и у каждого из них есть своя конкретная база данных.

Kazenone65 03.06.2019 12:29

тогда я полагаю, вам нужно пойти глубже и установить конкретную EntityManager службу с правильным подключением в прослушивателе ядра symfony или установить разные EntityManager для каждой среды, например. customer1_prod, customer2_prod

Ludo 03.06.2019 12:36

и отсортируйте, какой env запускается в конфигурации веб-сервера

Ludo 03.06.2019 12:37
Ответ принят как подходящий

Другой способ — создать отдельные среды и соответствующие index_*.php файлы, на которые вы указываете свой веб-сервер. Практически создайте 2 новые копии файла записи приложения index.phppublic/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.

Определите переменную среды для каждого поддомена на вашем веб-сервере, и вы сможете использовать ее в своих файлах конфигурации.

Другие вопросы по теме