【问题标题】:Zend Framework 2: How to create own User mapper for ZfcUserZend Framework 2:如何为 ZfcUser 创建自己的用户映射器
【发布时间】:2014-09-23 14:57:31
【问题描述】:

我正在开发我的第一个 Zend Framework 2 项目。我已经在我的项目中实现了 ZfcUser,并且由于我的数据库表中的列略有不同,我想从 ZfcUser 覆盖用户映射器。我已经在 Internet 和此处进行了搜索,但没有得到有效的解决方案。我不得不承认我找到的解决方案是从 2012 年开始的 (ZF2: Custom user mapper for ZfcUser module),所以在此期间可能发生了一些变化。

那么到目前为止我做了什么。我创建了自己的用户实体。如果我理解正确,那么它需要扩展 ZfcUser,我已经这样做了:

模块/Application/src/Entity/User.php

namespace Application\Entity;
use Doctrine\ORM\Mapping as ORM;
use ZfcUser\Entity\User as ZfcUser;

/**
 * User
 *
 * @ORM\Table(name="user")
 * @ORM\Entity
 */
 class User extends ZfcUser
 {

/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer", nullable=false)
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
 protected $id;

/**
 * @var string
 *
 * @ORM\Column(name="username", type="string", length=255, nullable=false)
 */
 protected $username;

然后我复制了 zfcuser.global.php 并将其移动到文件夹 config/autoload/zfcuser.global.php

在这个文件中,我激活了 'user_entity_class' => 'Application\Entity\User', 我希望到目前为止这是正确的。

现在我需要自己的 UserMapper。据我了解,这无法通过配置文件完成。我将文件夹“Mapper”及其所有文件从 zfc-user/src/ZfcUser/Mapper 复制到我的应用程序模块中。我从所有文件中更改了命名空间。现在我很困惑我还需要复制什么,服务和/或工厂文件夹?我在哪里以及如何告诉我的应用程序使用我自己的 Mapper 而不是 ZfcUser?我只是不明白,希望有人能给我一些帮助。非常感谢您!

【问题讨论】:

    标签: php zend-framework2


    【解决方案1】:

    ZfcUser 只是向服务管理器询问 UserMapper 的实例。他们使用的别名称为“zfcuser_user_mapper”。

    因此,如果您将该别名链接到您自己的 UserMapper,那么您应该很高兴。 您可以在模块的 module.config.php 文件中进行设置,即:

    'service_manager' => array(
    
            'invokables' => array(
                'MyModule\Mapper\UserMapper' => 'MyModule\Mapper\UserMapper',
            ),
    
            'aliases' => array(
                'zfcuser_user_mapper' => 'MyModule\Mapper\UserMapper',
            ),
    ),
    

    或者你也可以在你的 Module.php 中的 getServiceConfig() 中设置它。

    只需确保在 application.config.php 中的 ZfcUser 之后加载自己的模块。

    请注意,我没有对此进行测试,但理论上它应该可以工作。

    编辑 (2014/09/24) 由于您收到错误消息名称为“zfcuserusermapper”或“zfcuser_user_mapper”的别名已存在,请尝试直接在您自己的模块中覆盖工厂。在你自己模块的module.config.php中:

    'service_manager' => array(
        'factories' => array(
            // Override ZfcUser User Mapper factory
            'zfcuser_user_mapper' => function ($sm) {
                $options = $sm->get('zfcuser_module_options');
                $mapper = new MyModule\Mapper\User($sm->get('Zend\Db\Adapter\Adapter'));
                $entityClass = $options->getUserEntityClass();
                $mapper->setHydrator(new ZfcUser\Mapper\UserHydrator());
                $mapper->setTableName($options->getTableName());
                return $mapper;
            },
        )
    ),
    

    【讨论】:

    • 感谢 Ruben,我已经尝试过了,但收到消息:“名称为“zfcuserusermapper”或“zfcuser_user_mapper”的别名已经存在 vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager .php on line 801" 这将是一个不错的解决方案
    • @Luka 请检查上面答案中的编辑。这有帮助吗?
    【解决方案2】:

    感谢鲁本和他的建议。我不得不稍微改变一下才能让它工作,可能是因为我使用的是最新的 Zend Framework 2。

    我将在这里描述我的错误消息和解决方案,以防其他人遇到同样的问题。

    module.php

    // This solution did not work for me
    public function getServiceConfig()
    {
        return array(
          'service_manager' => array(
             'factories' => array(
              // Override ZfcUser User Mapper factory
              'zfcuser_user_mapper' => function ($sm) {
                  $options = $sm->get('zfcuser_module_options');
                  $mapper = new MyModule\Mapper\User($sm->get('Zend\Db\Adapter\Adapter'));
                  $entityClass = $options->getUserEntityClass();
                  $mapper->setHydrator(new ZfcUser\Mapper\UserHydrator());
                  $mapper->setTableName($options->getTableName());
                  return $mapper;
               },
            )
         );     
    } 
    

    首先我必须删除 'service_manager' => array(),否则代码将被完全忽略并使用正常的 ZfcUser。删除后,我收到 3 错误消息。

    1.可捕获的致命错误:传递给 ZfcUser\Mapper\UserHydrator::__construct() 的参数 1 必须是 Zend\Crypt\Password\PasswordInterface 的实例,没有给出,

    为了修复它,我不得不改变它:

     $mapper->setHydrator(new ZfcUser\Mapper\UserHydrator());
    

    到此代码:

     $mapper->setHydrator($sm->get('zfcuser_user_hydrator'));
    

    之后我收到下一条错误消息:

    2.没有数据库适配器

    再次需要更改一些代码:

     $mapper = new MyModule\Mapper\User($sm->get('Zend\Db\Adapter\Adapter'));
    

    进入这个

     $mapper = new \ZfcUserExtension\Mapper\User();                   
     $mapper->setDbAdapter($sm->get('zfcuser_zend_db_adapter'));
    

    还有最后一条错误信息

    3.没有实体原型集

    当我添加以下行时,此消息消失了:

    $mapper->setEntityPrototype(new $entityClass);
    

    这里是最终的工作代码:

    public function getServiceConfig()
    {
        return array(
                'factories' => array(
                        'zfcuser_user_mapper' => function ($sm) {
                            $options = $sm->get('zfcuser_module_options');
                            $mapper = new \ZfcUserExtension\Mapper\User();
                            // No db adapter present add below line
                            $mapper->setDbAdapter($sm->get('zfcuser_zend_db_adapter'));
                            $entityClass = $options->getUserEntityClass();
                            // No entity prototype set add below line
                            $mapper->setEntityPrototype(new $entityClass);
                            $mapper->setHydrator($sm->get('zfcuser_user_hydrator'));
                            $mapper->setTableName($options->getTableName());
                            return $mapper;
                        },
                    )
                );  
    }
    

    我最后将映射器和实体文件夹从 ZfcUser 复制到我的模型中,称为 ZfcUserExtension。然后我在 UserMapper 中将数据库列名从 user_id 更改为 id。我现在可以使用新的列名登录和注册。

    不幸的是,我还不能使用 Change-Password,因为它仍在使用 user_id,我还没有找到它的设置位置以及如何覆盖它,但我会更新当我找到解决方案时发布。如果有人知道这个问题的解决方案,请随时分享。

    非常感谢@Ruben 的帮助!!

    【讨论】:

    • 如果将配置放在 Module.php 的 getServiceConfig() 中,则不应使用 service_manager 键。我写的是把它放在你模块的module.config.php中。在这种情况下,您确实需要 service_manager 键。该文件应位于模块的配置文件夹中,即 /module/MyModule/config/module.config.php。当你的模块被加载时,这将由框架自动加载。因此,您可以选择将模块的服务管理器配置放在 Module.php 或 module.config.php 中的 getServiceConfig 中。不管怎样,很高兴你能解决它!
    • 啊,好吧。感谢您指出这一点,仍然需要学习很多。仍在寻找更改密码的工作。以为是表单,但它使用电子邮件作为隐藏字段。
    • 不客气。您应该为更改密码问题打开一个新问题,因为它与原始问题不同。
    • 你是对的,问题的标题可能不是最好的。我想要一种在我的数据库中使用不同列名的方法,这意味着我需要拥有自己的映射器来更改该映射器中的列名,但现在我意识到这还不够。所以也许我应该重新考虑一下标题。
    • 我认为这个问题的标题还可以,因为您确实想使用自己的 UserMapper。但是,如果您有后续问题,最好提出一个新问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-23
    • 1970-01-01
    • 2013-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多