doctrine-orm - Zend Framework 2 中服务中的实体管理器

标签 doctrine-orm zend-framework2

我为我的模块编写了一个自定义服务。该服务提供了应验证给定 token 的公共(public)静态函数。

现在我想实现另一个公共(public)静态函数来检查 Doctrine-Entity 是否存在。对于这种情况,我需要服务中的对象管理器或服务定位器。

class ApiService 
{
    const KEY_LENGTH = 10;
    const USE_NUMBERS = true;
    const USE_CHARS = true;

    public static function isValid($apiKey) {
        $isValid = false;
        # more code tbd
        $isValid = self::exists($apiKey);
        return $isValid;
    }

    public static function exists($apiKey) {
    # Insert Object-Manager here

        $validator = new \DoctrineModule\Validator\ObjectExists(array(
           'object_repository' => $objectManager->getRepository('Application\Entity\User'),
           'fields' => array('email')
        )); 
    }
}
  • 将我的函数实现为公共(public)静态并将它们称为静态方法是“最佳实践”吗?
  • 将对象管理器注入(inject)我的 doesEntityExist() 的最佳实践是什么?功能?
  • 最佳答案

    最好的方法是从您的类中完全删除静态方法。 ZF2 使通过名称获取服务变得非常容易,因此对于这样的用例,您实际上不需要静态方法。

    首先,清理你的服务:

    namespace MyApp\Service;
    
    use Doctrine\Common\Persistence\ObjectRepository;
    use DoctrineModule\Validator\ObjectExists;
    
    class ApiService
    {
        // ...
    
        protected $validator;
    
        public function __construct(ObjectRepository $objectRepository)
        {
            $this->validator = new \DoctrineModule\Validator\ObjectExists(array(
               'object_repository' => $objectRepository,
               'fields'            => array('email')
            )); 
        }
    
        public function exists($apiKey)
        {
            return $this->validator->isValid($apiKey);
        }
    
        // ...
    }
    

    现在为它定义一个工厂:

    namespace MyApp\ServiceFactory;
    
    use MyApp\Service\ApiService;
    use Zend\ServiceManager\FactoryInterface;
    use Zend\ServiceManager\ServiceLocatorInterface;
    
    class ApiServiceFactory implements FactoryInterface
    {
        public function createService(ServiceLocatorInterface $serviceLocator)
        {
            $entityManager = $serviceLocator->get('Doctrine\ORM\EntityManager');
            $repository = $entityManager->getRepository('Application\Entity\User');
    
            return new ApiService($repository);
        }
    }
    

    然后将服务名称映射到工厂(通常在您的模块中):

    namespace MyApp;
    
    use Zend\ModuleManager\Feature\ConfigProviderInterface;
    
    class Module implements ConfigProviderInterface
    {
        public function getConfig()
        {
            return array(
                'service_manager' => array(
                    'factories' => array(
                        'MyApp\Service\ApiService'
                            => 'MyApp\ServiceFactory\ApiServiceFactory',
                    ),
                ),
            );
        }
    }
    

    注意 :您可能希望简单地使用闭包而不是定义单独的工厂类,但是当您不使用该服务时,拥有工厂类会给您带来小的性能提升。此外,在配置中使用闭包意味着您无法缓存合并的配置,因此请考虑使用此处建议的方法。

    这是一个没有工厂类的例子(同样,考虑使用上面解释的方法):

    namespace MyApp;
    
    use Zend\ModuleManager\Feature\ServiceProviderInterface;
    
    class Module implements ServiceProviderInterface
    {
        public function getServiceConfig()
        {
            return array(
                'factories' => array(
                    'MyApp\Service\ApiService' => function ($sl) {
                        $entityManager = $serviceLocator->get('Doctrine\ORM\EntityManager');
                        $repository = $entityManager->getRepository('Application\Entity\User');
    
                        return new MyApp\Service\ApiService($repository);
                    },
                ),
            );
        }
    }
    

    现在您可以在 Controller 中使用该服务:

    class MyController extends AbstractActionController
    {
        // ...
    
        public function apiAction()
        {
            $apiService = $this->getServiceLocator()->get('MyApp\Service\ApiService');
    
            if ( ! $apiService->isValid($this->params('api-key')) {
                throw new InvalidApiKeyException($this->params('api-key'));
            }
    
            // ...
        }
    
        // ...
    }
    

    您也可以在拥有服务管理器的任何地方检索它:

    $validator = $serviceLocator->get('MyApp\Service\ApiService');
    

    作为附加建议,请考虑简化您的服务。由于isValid已经是验证器的一个方法,您可以简单地返回验证器本身(为简单起见,这里使用闭包方法):

    namespace MyApp;
    
    use Zend\ModuleManager\Feature\ServiceProviderInterface;
    use DoctrineModule\Validator\ObjectExists;
    
    class Module implements ServiceProviderInterface
    {
        public function getServiceConfig()
        {
            return array(
                'factories' => array(
                    'MyApp\Validator\ApiKeyValidator' => function ($sl) {
    
                        $entityManager = $serviceLocator->get('Doctrine\ORM\EntityManager');
                        $repository = $entityManager->getRepository('Application\Entity\User');
                        new ObjectExists(array(
                           'object_repository' => $objectRepository,
                           'fields'            => array('email')
                        )); 
                    },
                ),
            );
        }
    }
    

    关于doctrine-orm - Zend Framework 2 中服务中的实体管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15266862/

    相关文章:

    php - 学说 DBAL 2 : fetchAll() unnecessary array dimensions

    Doctrine 2 findby函数,获取键和值

    php - 如何将 $_FILE 和 $_POST 数据传递到表单中?

    php - ZF2 Zend Registry 的替代品

    Symfony/Doctrine 无限递归,同时从具有多对一关系反转侧的数据库中获取

    doctrine-orm - 如何在 preUpdate 事件监听器中更改字段的值?

    zend-framework2 - ZF2 - 供应商模块 ZFcUser 的覆盖配置

    php - ZEND Framework 2 RESTful Web 服务模板错误

    php - 在 Doctrine/PDO 中,如何获取 sql 查询列名

    php - ZF2 : Groups of modules