php - 如何在 PHP 包中访问 Doctrine?
问题描述
我正在创建一个将驻留在/vendor
目录中的 PHP 包,它需要使用 Doctrine 访问数据库。在我的 Symfony 4.2 主代码中,我可以通过在构造函数中使用自动装配来访问数据库,如下所示:
public function __construct(EntityManagerInterface $em)
然而,这只适用于 Symfony,并且似乎不适用于公共包。请注意,我需要访问默认数据库连接,如果已经存在,我不想创建新连接。
我正在尝试创建一个可以使用和不使用 Symfony 的包,所以我真正需要的是原始 PHP 来获取当前数据库连接(不是新连接),而不需要所有的自动装配魔法。
如果包在 Symfony 下运行,它应该使用当前的 Symfony 数据库连接。如果没有,它应该创建自己的连接。
例如,我可以像这样打开一个新连接:
$conn = \Doctrine\DBAL\DriverManager::getConnection($params, $config)
这很好,但我需要一种方法来获取当前的 Symfony 数据库连接(类似这样):
$conn = \Doctrine\DBAL\DriverManager::getCurrentConnection()
不幸的是,没有这样的功能,我不知道如何创建自己的版本。
解决方案
经过几天尝试创建一个 Symfony 捆绑包以使事情以“官方”方式运行后,我想出了一个单行黑客,它可以获取 Symfony Doctrine 连接并满足我的需要。$kernel
它依赖于Symfony 全局的事实:
// Singleton to get Doctrine database connection
//
// If we are running on the legacy system, it will open a new database connection.
//
// If we are running under Symfony, it will use the existing Doctrine
// connection.
class Doctrine
{
static private $instance = null;
private $conn;
// The database connection is established in a private constructor
private function __construct()
{
global $kernel;
if (class_exists('\config')) {
// running on legacy system
$cfg = new \config();
//
// set up Doctrine connection
//
$params = [
'driver' => 'pdo_mysql',
'user' => $cfg->db_username,
'password' => $cfg->db_password,
'host' => $cfg->db_hostname,
'dbname' => $cfg->db_name,
];
$config = new \Doctrine\DBAL\Configuration();
$this->conn = \Doctrine\DBAL\DriverManager::getConnection($params, $config);
} else {
// running on Symfony system
$this->conn = $kernel->getContainer()->get('doctrine.orm.default_entity_manager')->getConnection();
}
}
static public function getInstance()
{
if (!self::$instance) {
self::$instance = new Doctrine();
}
return self::$instance;
}
static public function connection()
{
return self::getInstance()->getConnection();
}
public function getConnection()
{
return $this->conn;
}
}
通过使用上面的类,这个简单的语句将在 Symfony 和我们的遗留代码中获得一个 Doctrine 连接:
$conn = Doctrine::connection()
现在我们可以在 Symfony 和我们的遗留代码上使用相同的库。是的,我知道这是一个 hack,但它比创建一个简单的 Symfony 包所需的 10 多个文件和数十行代码更容易理解和维护(并且遗留系统不会识别一个包)。我已经把这个类放在一个私有的 composer 包中,遗留系统和 Symfony 都可以使用它。在我们可以将所有遗留的东西迁移到 Symfony 之前,这将使保持运行变得更加容易。完成之后,我就可以以正确的方式做事了。
推荐阅读
- azure - 从 powershell 查询中删除括号
- javascript - 如何使用 setInterval 移动具有弹跳效果的对象?
- sqlalchemy - Sqlalchemy 自动加载似乎一次加载多个模式
- c# - 在 ListView 中编辑列项
- java - 将正则表达式与 Java 匹配,显示与 + 号不匹配?
- python - Python List Comprehenion 获取 JSON 值
- java - 计算android studio中的分钟持续时间?
- php - 调试 mongoDB 服务器为什么没有运行的正确步骤是什么?
- ms-word - 如何在 MS Word 中搜索连续的特殊字符?
- c# - 有没有办法在我的可可应用程序的单个 ViewController 中显示两个 NSViewController?