Doctrine orm zf2 doctrine2和Zend\Db\Adapter\Adapter使用一个Db连接

Doctrine orm zf2 doctrine2和Zend\Db\Adapter\Adapter使用一个Db连接,doctrine-orm,zend-framework2,Doctrine Orm,Zend Framework2,我将doctrine2与ZF2一起使用,我的一些库与Zend\Db\Adapter\Adapter一起使用,其他库与doctrine2一起使用。现在,它们连接到数据库两次。是否可以在doctrine和标准ZF2 db适配器中使用一个db连接?DoctrineORM模块接受一个PDO资源或服务名称,实例可以位于服务管理器中,而不是通常的连接参数 第一步是创建一个服务工厂,它从Zend\Db\Adapter\Adapter服务检索PDO资源 <?php namespace Applicatio

我将doctrine2与ZF2一起使用,我的一些库与Zend\Db\Adapter\Adapter一起使用,其他库与doctrine2一起使用。现在,它们连接到数据库两次。是否可以在doctrine和标准ZF2 db适配器中使用一个db连接?

DoctrineORM模块接受一个
PDO
资源或服务名称,实例可以位于服务管理器中,而不是通常的连接参数

第一步是创建一个服务工厂,它从
Zend\Db\Adapter\Adapter
服务检索PDO资源

<?php
namespace Application\Db\Service;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\Exception\ServiceNotCreatedException;

class PdoResourceFactory implements FactoryInterface
{
    /**
     * @param ServiceLocatorInterface $serviceLocator
     * @return \PDO resource
     */
    public function createService(ServiceLocatorInterface $services)
    {
        $dbAdapter = $services->get('Zend\Db\Adapter\Adapter');

        $pdo = $dbAdapter->getDriver()->getConnection()->getResource();
        if (!$pdo instanceof \PDO) {
            throw new ServiceNotCreatedException('Connection resource must be an instance of PDO');
        }
        return $pdo;        
    }
} 

很抱歉将此作为新答案发布,但我无法在Crisp的答案中添加评论,因为我的声誉太低,因为我只在stackoverflow注册以撰写此评论:

在显示的
dbconn.local.php
中,确保将
dbname
设置为
null
,如以下代码段所示:

除了Crisp的回答之外: 在
EntityManager
上,如果没有将
dbname
设置为
null
,您将获得
“database”
作为数据库的名称,因为这是由
DoctrineORMModule
module.config.php
设置的默认值。将
dbname
设置为
null
将导致扩展
doctor\DBAL\Driver\pdomsql\Driver
doctor\DBAL\Driver\AbstractMySQLDriver
通过
SELECT database()
从数据库本身加载数据库名称,如您所见

另外,如果不将
dbname
设置为
null
(或设置为正确的数据库名称),将导致
schemaInSyncWithMetadata()
条令\ORM\Tools\SchemaValidator
函数始终返回false,因为它无法加载当前数据库设置,因为它使用了
条令\ORM\Tools\SchemaTool
,它使用
EntityManager
连接,认为正在使用的数据库称为
“数据库”

所以我希望有人能利用这些信息来节省一些时间。我浪费了半天时间才弄明白


再次感谢Crisp为我节省了很多时间的回答。

这太棒了,不知道为什么还没有被接受。谢谢,这对我很有帮助。
<?php
return array (
    'service_manager' => array(
        'factories' => array(
            'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
            // include the pdo resource factory
            'PdoResource' => 'Application\Db\Service\PdoResourceFactory',
        ),
    ),
    // db adapter config
    'db' => array(
        'driver'    => 'pdo',
        'dsn'       => 'mysql:dbname=database;host=127.0.0.1',
        'username'  => 'username',
        'password'  => 'password',
    ),

    'doctrine' => array (
        'connection' => array (
            'orm_default' => array (
                'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
                // use the resource from the zend adapter 
                'pdo' => 'PdoResource',
            ),
        ),
    ),
);
<?php
return array(
    'service_manager' => array(
        'factories' => array(
            'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
            // the lazy way of Crisp's PdoResourceFactory:
            'PdoResource' => function (ServiceLocatorInterface $services) {
                $dbAdapter = $services->get('Zend\Db\Adapter\Adapter');

                $pdo = $dbAdapter->getDriver()->getConnection()->getResource();
                if (!$pdo instanceof \PDO) {
                    throw new ServiceNotCreatedException('Connection resource must be an instance of PDO');
                }
                return $pdo;  
            },
        ),
    ),
    // db adapter config
    'db' => array(
        'driver'    => 'pdo',
        'dsn'       => 'mysql:dbname=database;host=127.0.0.1',
        'username'  => 'username',
        'password'  => 'password',
    ),

    'doctrine' => array (
        'connection' => array (
            'orm_default' => array (
                'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
                // use the resource from the zend adapter 
                'pdo' => 'PdoResource',
                // important addition to Crisp's answer:
                'params' => array(
                    'dbname' => null,
                ),
            ),
        ),
    ),
);
$em->getConnection()->getDatabase();