Symfony 4 中的动态数据库连接
Dynamic database connection in Symfony 4
我正在设置一个多租户 Symfony 4 应用程序,其中每个租户都有自己的数据库。
我在 doctrine.yaml
配置中设置了两个数据库连接。其中一个连接是基于环境变量的静态连接。另一个应该具有基于凭据提供程序服务的动态 URL。
doctrine:
dbal:
connections:
default:
url: "@=service('provider.db.credentials').getUrl()"
上面的表达式 "@=service('provider.db.credentials').getUrl()"
虽然没有被解析。
当将 "@=service('provider.db.credentials').getUrl()"
作为参数注入另一个服务时,provider.db.credentials
服务上的 getUrl()
的结果被注入。但是当在学说的连接配置中使用它时,表达式没有被解析。
有人知道如何解决这个问题吗?
您正试图依赖 ability of Symfony services definition to use expressions for defining certain aspects of services. However you need to remember that this functionality is part of Dependency Injection component which is able (but not limited to) to use configuration files for services. To be more precise - this functionality is provided by configuration loaders, you can take a look here 来了解 Yaml 配置加载器的处理方式。
另一方面,您尝试使用的 Doctrine bundle 配置是由 Config 组件提供的。 Dependency Injection 组件使用与 Config 组件相同的文件格式这一事实可能会给人一种印象,即这些情况的处理方式相同,但实际上它们是完全不同的。
总而言之:Doctrine 配置中的表达式无法像您期望的那样工作,因为 Doctrine 包配置处理器不希望获得表达式语言表达式并且不支持处理它们。
虽然上面给出的解释有望回答您的问题 - 您可能希望获得有关如何实际解决问题的一些信息。
至少有两种可能的方法,但选择正确的方法可能需要一些额外的信息,这超出了这个问题的范围。
如果你在构建容器时知道选择哪个连接(你的代码假设是这种情况,但你可能不知道请注意它)-那么您应该在必要时使用 compiler pass mechanism yo update Doctrine DBAL services definitions (which may be quite tricky). Reason for this non-trivial process is that configurations are loaded at the early stages of container building process and provides no extension points. You can take a look into sources。无论如何,虽然可能,但我不建议您采用这种方式,而且您很可能不需要它,因为(我想)您需要 select 在运行时而不是在容器构建时连接。
可能更正确的方法是创建自己的 DBAL Connection
class that will maintain list of actual connections and will provide required connection depending on your application's logic. You can refer to implementation details of DBAL sharding 功能包装器作为示例。包装器 class 可以通过使用 wrapper_class
key for dbal
configuration
直接通过 Doctrine bundle 配置来定义
我正在设置一个多租户 Symfony 4 应用程序,其中每个租户都有自己的数据库。
我在 doctrine.yaml
配置中设置了两个数据库连接。其中一个连接是基于环境变量的静态连接。另一个应该具有基于凭据提供程序服务的动态 URL。
doctrine:
dbal:
connections:
default:
url: "@=service('provider.db.credentials').getUrl()"
上面的表达式 "@=service('provider.db.credentials').getUrl()"
虽然没有被解析。
当将 "@=service('provider.db.credentials').getUrl()"
作为参数注入另一个服务时,provider.db.credentials
服务上的 getUrl()
的结果被注入。但是当在学说的连接配置中使用它时,表达式没有被解析。
有人知道如何解决这个问题吗?
您正试图依赖 ability of Symfony services definition to use expressions for defining certain aspects of services. However you need to remember that this functionality is part of Dependency Injection component which is able (but not limited to) to use configuration files for services. To be more precise - this functionality is provided by configuration loaders, you can take a look here 来了解 Yaml 配置加载器的处理方式。
另一方面,您尝试使用的 Doctrine bundle 配置是由 Config 组件提供的。 Dependency Injection 组件使用与 Config 组件相同的文件格式这一事实可能会给人一种印象,即这些情况的处理方式相同,但实际上它们是完全不同的。
总而言之:Doctrine 配置中的表达式无法像您期望的那样工作,因为 Doctrine 包配置处理器不希望获得表达式语言表达式并且不支持处理它们。
虽然上面给出的解释有望回答您的问题 - 您可能希望获得有关如何实际解决问题的一些信息。
至少有两种可能的方法,但选择正确的方法可能需要一些额外的信息,这超出了这个问题的范围。
如果你在构建容器时知道选择哪个连接(你的代码假设是这种情况,但你可能不知道请注意它)-那么您应该在必要时使用 compiler pass mechanism yo update Doctrine DBAL services definitions (which may be quite tricky). Reason for this non-trivial process is that configurations are loaded at the early stages of container building process and provides no extension points. You can take a look into sources。无论如何,虽然可能,但我不建议您采用这种方式,而且您很可能不需要它,因为(我想)您需要 select 在运行时而不是在容器构建时连接。
可能更正确的方法是创建自己的 DBAL
Connection
class that will maintain list of actual connections and will provide required connection depending on your application's logic. You can refer to implementation details of DBAL sharding 功能包装器作为示例。包装器 class 可以通过使用wrapper_class
key fordbal
configuration 直接通过 Doctrine bundle 配置来定义