【问题标题】:symfony architecture: custom method with repository access on entity creationsymfony 架构:在实体创建时具有存储库访问权限的自定义方法
【发布时间】:2013-10-16 09:11:00
【问题描述】:

我有一个包含唯一列的数据库表,该列应包含唯一的 8 个字符的字母数字字符串。

我(终于)从我自己的 MVC 框架迁移到了 symfony。到目前为止,我在 CREATE 上调用的模型中有一个私有方法。该方法中的循环会生成一个随机散列,并对表执行 READ 以查看它是否唯一:如果是,则该散列将被返回并注入到 CREATE 请求中。

我看到的问题是 在 symfony 中我无法从实体类中访问存储库,所以我不能使用lifecycle callback。我理解这背后的原因。另一方面,哈希生成与控制器无关——对我来说,它是属于模型的内部逻辑。如果我以后更改数据结构,我需要编辑控制器。

我的问题是:在架构方面,我应该把哈希生成方法放在哪里?

【问题讨论】:

    标签: php symfony


    【解决方案1】:

    您可以使用监听器。您是对的,因为您需要访问存储库,所以生命周期回调不是正确的解决方案。但是您可以定义一个侦听器来侦听与生命周期回调相同的事件,但它是一项服务,因此可以将存储库作为依赖项。

    【讨论】:

      【解决方案2】:

      回答我自己的问题:

      我创建了一个custom repository,它可以访问学说实体管理器。

      存储库有一个createNewHash 方法:

      class HashRepository extends EntityRepository
      {
          public function createNewHash()
          {
              $hash = new Hash();
              $hash->setHash($this->_getUniqueHash());
              $em = $this->getEntityManager();
              $em->persist($hash);
              $em->flush();
              return $hash;
          }
      
          private function _getUniqueHash()
          {
              $hash = null;
              $hashexists = true;
              while ($hashexists) {
                  $hash = $this->_generateRandomAlphaNumericString();
                  if (!$hashobject = $this->findOneByHash($hash)) {
                      $hashexists = false;
                  }
              }
              return $hash;
          }
      
          private function _generateRandomAlphaNumericString( $length=8 )
          {
              $bits = $length / 2;
              return bin2hex(openssl_random_pseudo_bytes($bits));
          }
      }
      

      然后可以从 Controller 调用 createNewHash() 方法,并且 Controller 不必自己关心哈希创建。

      编辑:监听器是另一种方式。

      【讨论】:

        【解决方案3】:

        在你的实体构造函数中,我可以添加这个:

        <?php
        
        namespace Acme\DemoBundle\Entity;
        
        use Doctrine\ORM\Mapping as ORM;
        
        /**
         * MyEntity
         *
         * @ORM\Table(name="my_entity")
         */
        class MyEntity
        {
            /**
             * @ORM\Column(type="string", length=8, unique=true, nullable=false)
             * @var string
             */
            private $uniqId;
        
            public function __construct()
            {
                $this->uniqId = hash('crc32b', uniqid());
            }
        
            // ...
        
        }
        

        希望对你有帮助

        【讨论】:

        • 谢谢,但我知道如何生成哈希——我需要在实体中执行数据库读取以查看它是否真的是唯一的。 (有关生成的哈希的唯一性,请参阅此评论:stackoverflow.com/a/4070171/698511
        • 所以你需要使用事件监听器:symfony.com/doc/current/cookbook/doctrine/…
        • 看着他们,但设法用 EntityRepository 做到了(见我的回答)。可能有几种方法可以做到这一点。感谢您的帮助!
        猜你喜欢
        • 1970-01-01
        • 2011-04-02
        • 1970-01-01
        • 1970-01-01
        • 2012-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-01
        相关资源
        最近更新 更多