【问题标题】:Validation in Zend Framework 2 with Doctrine 2Zend Framework 2 中的验证与 Doctrine 2
【发布时间】:2012-09-06 12:46:51
【问题描述】:

我现在对 Zend Framework 2 越来越熟悉,同时我也对 Zend Framework 2 中的验证部分进行了更新。我见过几个例子,如何使用 Zend 验证数据库中的数据db适配器,例如Zend Framework 2官网的代码:

//Check that the username is not present in the database
$validator = new Zend\Validator\Db\NoRecordExists(
    array(
        'table' => 'users',
        'field' => 'username'
    )
);
if ($validator->isValid($username)) {
    // username appears to be valid
} else {
    // username is invalid; print the reason
    $messages = $validator->getMessages();
    foreach ($messages as $message) {
        echo "$message\n";
    }
}

现在我的问题是如何进行验证部分?

例如,我需要在插入数据库之前验证名称以检查数据库中不存在相同的名称,我已更新 Zend Framework 2 示例专辑模块以使用 Doctrine 2 与数据库进行通信,现在我想将验证部分添加到我的代码中。

假设在将专辑名称添加到数据库之前,我想验证数据库中不存在相同的专辑名称。

任何有关这方面的信息都会非常有帮助!

【问题讨论】:

  • 对 ZF2 不太熟悉,但这里有一个提示:创建自己的验证器,以默认验证器为例 =)

标签: php doctrine-orm zend-framework2


【解决方案1】:

如果你使用 DoctrineModule,已经有一个validator for your case

【讨论】:

  • 您好,感谢您的信息,您能否通过一个小例子简要说明如何使用这些模块,在我的例子中是 Rob Allen 和 Jason Grimes 的专辑模块
  • 我不知道 Rob 的专辑模块。 NoObjectExist 验证器与其他验证器一样只是一个验证器。 (它扩展了 Zend\Validator\AbstractValidator)。因此,您需要为您的 from 创建一个 InputFilter 并附加这些验证器。我在我的 repo [link]github.com/dawinterfeldt/playground/blob/master/module/User/src/…mybe 中玩了一点,它给了你一个提示。
【解决方案2】:

我遇到了同样的问题,用这种方法解决了:

  1. 创建一个自定义验证器类,将其命名为 NoEntityExists(或任何您想要的名称)。
  2. 扩展Zend\Validator\AbstractValidator
  3. Doctrine\ORM\EntityManager 提供getter 和setter
  4. 为选项(实体名称,...)提供一些额外的 getter 和 setter
  5. 创建一个isValid($value) 方法来检查记录是否存在并返回一个布尔值
  6. 要使用它,请创建它的新实例,分配 EntityManager 并像使用任何其他验证器一样使用它。

要了解如何实现验证器类,请检查已经存在的验证器(最好是像CallbackGreaterThan 这样的简单验证器)。

希望我能帮到你。

// 编辑:对不起,我迟到了 ;-)

这里有一个非常高级的示例,说明如何实现这样的验证器。

请注意,我添加了一个 translate() 方法,以便使用 PoEdit(一种翻译帮助工具,可从源代码中获取此类字符串并将它们放入列表中)来捕获语言字符串。如果你没有使用gettext(),你可以跳过它。

另外,这是我第一次使用 ZF2 的课程之一,我不会再把它放到 Application 模块中。也许,创建一个更适合的新模块,例如MyDoctrineValidator 左右。

此验证器为您提供了很大的灵活性,因为您必须在使用它之前设置查询。当然,您可以预先定义一个查询并在选项中设置实体、搜索列等。玩得开心!

<?php
namespace Application\Validator\Doctrine;

use Zend\Validator\AbstractValidator;
use Doctrine\ORM\EntityManager;

class NoEntityExists extends AbstractValidator
{
    const ENTITY_FOUND = 'entityFound';

    protected $messageTemplates = array();

    /**
     * @var EntityManager
     */
    protected $entityManager;

    /**
     * @param string
     */
    protected $query;

    /**
     * Determines if empty values (null, empty string) will <b>NOT</b> be included in the check.
     * Defaults to true
     * @var bool
     */
    protected $ignoreEmpty = true;

    /**
     * Dummy to catch messages with PoEdit...
     * @param string $msg
     * @return string
     */
    public function translate($msg)
    {
        return $msg;
    }

    /**
     * @return the $ignoreEmpty
     */
    public function getIgnoreEmpty()
    {
        return $this->ignoreEmpty;
    }

    /**
     * @param boolean $ignoreEmpty
     */
    public function setIgnoreEmpty($ignoreEmpty)
    {
        $this->ignoreEmpty = $ignoreEmpty;
        return $this;
    }

    /**
     *
     * @param unknown_type $entityManager
     * @param unknown_type $query
     */
    public function __construct($entityManager = null, $query = null, $options = null)
    {
        if(null !== $entityManager)
            $this->setEntityManager($entityManager);
        if(null !== $query)
            $this->setQuery($query);

        // Init messages
        $this->messageTemplates[self::ENTITY_FOUND] = $this->translate('There is already an entity with this value.');

        return parent::__construct($options);
    }

    /**
     *
     * @param EntityManager $entityManager
     * @return \Application\Validator\Doctrine\NoEntityExists
     */
    public function setEntityManager(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
        return $this;
    }

    /**
     * @return the $query
     */
    public function getQuery()
    {
        return $this->query;
    }

    /**
     * @param field_type $query
     */
    public function setQuery($query)
    {
        $this->query = $query;
        return $this;
    }

    /**
     * @return \Doctrine\ORM\EntityManager
     */
    public function getEntityManager()
    {
        return $this->entityManager;
    }

    /**
     * (non-PHPdoc)
     * @see \Zend\Validator\ValidatorInterface::isValid()
     * @throws Exception\RuntimeException() in case EntityManager or query is missing
     */
    public function isValid($value)
    {
        // Fetch entityManager
        $em = $this->getEntityManager();

        if(null === $em)
            throw new Exception\RuntimeException(__METHOD__ . ' There is no entityManager set.');

        // Fetch query
        $query = $this->getQuery();

        if(null === $query)
            throw new Exception\RuntimeException(__METHOD__ . ' There is no query set.');

        // Ignore empty values?
        if((null === $value || '' === $value) && $this->getIgnoreEmpty())
            return true;

        $queryObj = $em->createQuery($query)->setMaxResults(1);

        $entitiesFound = !! count($queryObj->execute(array(':value' => $value)));

        // Set Error message
        if($entitiesFound)
            $this->error(self::ENTITY_FOUND);

        // Valid if no records are found -> result count is 0
        return ! $entitiesFound;
    }
}

【讨论】:

  • 嗨丹尼尔,谢谢你的帮助,如果你能提供一些示例代码,会更有帮助,只要代码的骨架就可以了
  • 对不起,我不允许。我在工作,无法复制我的代码。我现在也没有时间写东西,但我今晚可以检查一下(那是 3-4 小时后)。
  • 再次感谢您的快速回复,我的意思是您不需要复制您的确切代码,这就是我的意思只是它的一个骨架,希望当您晚上有时间时,您可以帮助它有了更多信息,对于像我这样以后会搜索这篇文章的人来说真的很有用
  • 好吧,如果你需要一个骨架,检查已经写好的其他验证器。它们都非常相似,但它们采取的选项和验证的方式不同(显然)。只需复制一个,将其放入您的目录,重命名它,实现 isValid 方法就可以了。今晚我给你举个例子。
  • 感谢您的建议,将尝试采用已编写的验证器之一,将使用它,并且还将为您的示例保持我的手指交叉(慢慢来):)。如果我的模块有效,基于您的示例,我一定会接受您的回答
猜你喜欢
  • 1970-01-01
  • 2011-06-27
  • 2011-12-13
  • 1970-01-01
  • 1970-01-01
  • 2017-07-09
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
相关资源
最近更新 更多