在Symfony中验证字段的另一种方法

时间:2016-12-10 18:08:40

标签: php validation symfony

我在Symfony 3.2中编写应用程序。我现在正在做的是编写添加图像/ youtube视频功能。我的应用程序的逻辑是,无论用户选择一个还是第二个对象,数据都存储在同一个数据库表objects中:

  • objectID
  • object_typeID
  • object_title
  • object_filename(如果为null,则为其视频)
  • object_link(如果为空,则为其图像)

现在,在添加视频时,此link字段已通过此方法验证:

/**
 * Check if link is valid youtube URL.
 * 
 * @Assert\IsTrue(message = "This is not valid....")
 * 
 * @return bool
 */
public function isValidLink() {
    $rx = '~
        ^(?:https?://)?              # Optional protocol
         (?:www\.)?                  # Optional subdomain
         (?:youtube\.com|youtu\.be)/  # Mandatory domain name
         (?:watch\?v=)?             # optional
         (?:[a-zA-Z0-9]{11})          # mandatory
         ~x'
    ;

    return preg_match($rx, $this->link);
}

当然,添加每个对象有两种不同的形式。问题是在添加图像时也会验证链接字段。

因此,如何以这种方式验证链接字段以保持我现有的系统架构?

1 个答案:

答案 0 :(得分:2)

好的,我找到了解决方案。验证表单的最佳方法是创建我的自定义验证器并添加它,即通过表单构建器:

$builder->add('link', TextType::class, array(
    'label' => 'Link to the YT video',
    'constraints' => [
        new YouTubeURL(),
    ],
))
// ...

我还会为后人编写验证器文件:)

的appbundle /验证/约束/ YouTubeURL.php:

namespace AppBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

class YouTubeURL extends Constraint
{
    public $message = 'This is not the valid YouTube URL.';
}

的appbundle /验证/约束/ YouTubeURLValidator.php:

namespace AppBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class YouTubeURLValidator extends ConstraintValidator
{
    public function validate($value, Constraint $constraint)
    {
        $rx = '~
            ^(?:https?://)?              # Optional protocol
             (?:www\.)?                  # Optional subdomain
             (?:youtube\.com|youtu\.be)/ # Mandatory domain name
             (?:watch\?v=)?              # optional part
             (?:[a-zA-Z0-9]{11})         # mandatory video id
             ~x'
        ;

        if (!preg_match($rx, $value))
        {
            $this->context->buildViolation($constraint->message)
                 ->addViolation();
        }
    }
}