【问题标题】:zf2 + Doctrine a different database for each memberzf2 + Doctrine 为每个成员创建不同的数据库
【发布时间】:2016-04-21 21:48:45
【问题描述】:

我网站的每个连接成员都有自己的数据库。 这是“user_1”的原则配置:

return array(
'doctrine' => array(
    'connection' => array(
        'orm_default' => array(
            'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
            'params' => array(
                'host'     => 'localhost',
                'port'     => '3306',
                'user'     => 'user_1',
                'password' => 'psswd_user_1',
                'dbname'   => 'database_user_1',
                'charset' => 'utf8',
                'driverOptions' => array (1002 => 'SET NAMES utf8'),
            )),),),);

有没有办法替换: “user_1”、“psswd_user_1”和“database_user_1” 和 'user_x'、'psswd_user_x' 和 'database_user_x' 用于 user_x 吗?

我不知道该怎么做! 我想避免为每个用户复制相同的代码...

感谢您的帮助

【问题讨论】:

    标签: doctrine-orm zend-framework2 multiple-users multi-database


    【解决方案1】:

    执行此操作的正确方法可能是在创建连接时注入您需要的配置。我找不到任何你可以挂钩的事件,所以你必须找到正确的服务管理器键来覆盖。

    通过一点源代码挖掘,我发现这些选项被发送到一个DoctrineORMModule\Options\DBALConnection实例,并且这个实例是由DoctrineORMModule\Service\DBALConnectionFactory创建的

    你需要用这样的东西覆盖这个工厂:

    <?php
    namespace MyModule\Service;
    use DoctrineORMModule\Service\DBALConnectionFactory;
    use Zend\ServiceManager\ServiceLocatorInterface;
    
    class MyDBALConnectionFactory extends DBALConnectionFactory
    {
    
        public function getOptions(ServiceLocatorInterface $sl, $key, $name = null)
        {
            $options = parent::getOptions($sl, $key, $name);
    
            // override for everyone that needs a DBALConnection
            if ($this->getOptionClass() === 'DoctrineORMModule\Options\DBALConnection') {
    
                 // set custom parameters here
                 // maybe fetch the current user with $sl->get('...')
                 $params = [/* ... */];
                 $options->setParams($params);
            }
    
            return $options;
        }
    }
    

    然后你只需告诉服务经理:

    <?php 
    return [
        ...
        'doctrine' => [
            'doctrine_factories' => [
                'connection' => 'MyModule\Service\DBALConnectionFactory',
            ]
        ]
        ...
    ];
    

    【讨论】:

    • Bonjour et Merci ClémentJe vais travailler sur cette piste
    • 乐于助人。如果这段代码没有按预期工作,请告诉我,我们可能没有相同版本的 ZF2 和 Doctrine
    • Je le ferai bien sûr avec plaisir
    • 此解决方案似乎不适用于您的用例。您不能仅使用配置,因为您有未预先确定的可能连接器数量。
    【解决方案2】:

    感谢亚历杭德罗·塞拉亚。 1st link2d link

    我希望它会有用。 我知道这并不完美,但我不能做得更好!我想批评一下。

    在 config/autoload/doctrine.local.php:

    'doctrine' => array(
    'connection' => array(
        'orm_default' => array(
            'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
            'params' => array(
                'host'     => 'localhost',
                'port'     => '3306',
                'user'     => 'root',
                'password' => '',
                'dbname'   => 'gestion_toto_default',
                'charset' => 'utf8',
                'driverOptions' => array(1002 => 'SET NAMES utf8'),
            )
        ),
        'orm_toto_users' => array(
            'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
            'params' => array(
                'host'     => 'localhost',
                'port'     => '3306',
                'user'     => 'root',
                'password' => '',
                     //gestion_toto_users has 2 tables : users and db_users
                'dbname'   => 'gestion_toto_users', 
                'driverOptions' => array(1002 => 'SET NAMES utf8'),
            )
        ),
        'dynamic_orm' => array(
            'driverClass' =>'Doctrine\DBAL\Driver\PDOMySql\Driver',
            'params' => array(
                'host'     => 'localhost',
                'port'     => '3306',
                'user'     => '',
                'password' => '',
                'dbname'   => '',
                'driverOptions' => array(1002 => 'SET NAMES utf8'),
            ),
        ),
    ),
    
    'driver' => array(
        'orm_toto_users' => array(
            'class'   => 'Doctrine\ORM\Mapping\Driver\DriverChain',
            'drivers' => array(
                __NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_driver'
            )
        ),
        'dynamic_orm' => array(
            'drivers' => array(
                __NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_driver'
            )
        ),
    ),
    
    'entitymanager' => array(
        'orm_toto_users' => array(
            'connection'    => 'orm_toto_users',
            'configuration' => 'orm_default'
        ),
        'dynamic_orm' => array(
            'connection' => 'dynamic_orm',
        ),
    ),
    
    'eventmanager' => array(
        'orm_toto_users' => array()
    ),
    
    'sql_logger_collector' => array(
        'orm_toto_users' => array(),
    ),
    
    'entity_resolver' => array(
        'orm_toto_users' => array()
    ),),
    

    module.config.php:

        'doctrine' => array(
        'driver' => array(
            __NAMESPACE__ . '_driver' => array(
                'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
                'cache' => 'array',
                'paths' => array(
                    __DIR__ . '/../src/' . __NAMESPACE__ . '/Entity'
                ),
            ),
            'orm_default' => array(
                'drivers' => array(
                    __NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_driver'
                )
            ),
        ),
        'authentication' => array(
            'orm_default' => array(
                'object_manager' => 'doctrine.entitymanager.orm_toto_users',
                'identity_class' => 'MyModule\Entity\User',
                'identity_property' => 'identifiant',  
                'credential_property' => 'password', 
                'credential_callable' => function(\MyModule\Entity\User $user, $passwordGiven) {
                    $bcrypt   = new \Zend\Crypt\Password\Bcrypt();
                    return $bcrypt->verify($psswdGiven, $user->getPsswd()) && $user->getIsactif();
                },
            ),
        ),
    ),
    

    在 Xcontroller 中:

        public function getEntityManager()
    {
        if (null === $this->em) {
    
            $this->em = $this->getServiceLocator()->get('dynamic_entity_manager');
        }
        return $this->em;
    }
    

    在用户控制器中:

        public function getEntityManager()
    {
        if (null === $this->em) {
            $this->em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_toto_users');
        }
        return $this->em;
    }
    

    在 DynamicEMFactory.php 中:

    class DynamicEMFactory implements FactoryInterface {
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
            // Get current user
        $authService = $serviceLocator->get('Zend\Authentication\AuthenticationService');
        if (! $authService->hasIdentity()) {
            throw new \RuntimeException(
                'It is not possible to create a dynamic entity manager before a user has logged in'
            );
        }
    
        $user = $authService->getIdentity();
        $db_User = $user->getUser_db()->getDbuser();
        $db_Psswd = $user->getUser_db()->getDbpsswd();
        $db_Name = $user->getUser_db()->getDbname();
    
            // Update connection config
        $globalConfig = $serviceLocator->get('config');
        $globalConfig['doctrine']['connection']['dynamic_orm']['params']['user'] = $db_User;
        $globalConfig['doctrine']['connection']['dynamic_orm']['params']['password'] = $db_Psswd;
        $globalConfig['doctrine']['connection']['dynamic_orm']['params']['dbname'] = $db_Name;
    
        $isAllowOverride = $serviceLocator->getAllowOverride();
        $serviceLocator->setAllowOverride(true);
        $serviceLocator->setService('config', $globalConfig);
        $serviceLocator->setAllowOverride($isAllowOverride);
    
        return $serviceLocator->get('doctrine.entitymanager.dynamic_orm');
    }
    

    }

    在 module.config 中:

        'service_manager' => array(
        'factories' => array(
    
            'dynamic_entity_manager' => 'XXX\Service\Factory\DynamicEMFactory',
    

    在 onBootstrap 中(改变外观):

        $authService = $serviceManager->get('Zend\Authentication\AuthenticationService');
        if ($authService->getIdentity()) {
            $em = $serviceManager->get('dynamic_entity_manager');
        } else {
            $em = $serviceManager->get('doctrine.entitymanager.orm_default');
        }
        $viewModel = $e->getApplication()->getMvcEvent()->getViewModel();
        $query = $serviceManager->get('param_user');
        $tab = $query->getReponse($em);
        $nom_theme = $tab['something']));
        $viewModel->nom_theme = $nom_theme;//to layout
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-14
      • 2013-11-30
      • 1970-01-01
      • 1970-01-01
      • 2018-03-25
      • 1970-01-01
      相关资源
      最近更新 更多