5

「John Doe <jdoe@example.com>」のような「連絡先」を検証するカスタム バリデータ制約を作成しています。クックブックに従って、制約クラスを作成しました。

<?php

namespace MyCompany\MyBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

/**
 * @Annotation
 */
class Contact extends Constraint
{
    public $message = 'The string "%string%" is not a valid Contact.';
}

また、バリデーターも作成しました。

<?php

namespace MyCompany\MyBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\EmailValidator;

class ContactValidator extends ConstraintValidator
{
    public function validate($value, Constraint $constraint)
    {
        if (!preg_match('#(.*)\s+<(.*)>#', $value, $matches)) {
            $this->context->addViolation($constraint->message, array('%string%' => $value));
        }

        $emailValidator = new EmailValidator();
        if (isset($matches[2]) && $emailValidator->validate($matches[2], new Email())) {
            $this->context->addViolation($constraint->message, array('%string%' => $value));    
        }
    }
}

ポイントは、カスタムバリデーター内で Symfony の EmailValidator を使用して、メールが有効であることを確認しようとしていることです。車輪を再発明して、独自の正規表現を使用して電子メールを検証したくありません。

有効な連絡先を検証しようとするとすべて問題ありませんが、無効な電子メール ("Gabriel Garcia <infoinv4l1d3mai1.com>") を使用して連絡先をテストすると、PHP の致命的なエラーでクラッシュします。

致命的なエラー: 58 行目の /home/dev/myproject/vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/EmailValidator.php の非オブジェクトに対するメンバー関数 addViolation() の呼び出し

EmailValidator.php クラスを調べてみると、この問題は $context (ExecutionContext) に関連していることがわかりました。EmailValidator.php の 58 行目は次のとおりです。

$this->context->addViolation($constraint->message, array('{{ value }}' => $value));

クラスのコンテキスト属性が null のようです。誰でも理由を知っていますか?どこかに注入する必要がありますか?

前もって感謝します。

PS: Symfony 2.3 を使用しています。正規表現に注意を払わないでください。それがはるかに優れていることはわかっています。ただ今テスト用です。

4

3 に答える 3

5

元の質問は、カスタム バリデータ内で EmailValidator を使用することに関するものだったと思いますが、このシナリオではコンテナを使用できないため、

$this->get('validator');

動作しないでしょう。投稿者が抱えていた唯一の問題は、EmailValidator addViolation を正しいコンテキストに設定することだったようです。これはうまくいくはずです:

$emailValidator = new EmailValidator();
$emailValidator->initialize($this->context);
$emailValidator->validate($matches[2], $constraint);
于 2014-02-26T20:28:16.780 に答える
4

制約を直接使用できます

http://symfony.com/doc/current/book/validation.htmlを参照してください

use Symfony\Component\Validator\Constraints\Email

$emailConstraint = new Email();

// use the validator to validate the value
$errorList = $this->get('validator')->validateValue(
    $email,
    $emailConstraint
);

宜しくお願いします

于 2013-06-27T10:19:07.607 に答える
2

カスタム内でカスタムを呼び出そうとした後にこのトピックを見つけたので、深く調査しましたが、別のより良い方法を見つけたかもしれません(私によるともっと簡単です)。

有効: Sf2.6>=

$this->context->getValidator()
    ->inContext($this->context)
    ->atPath("time_on_point")
    ->validate($timeOnPoint, new AssertCustom\DateTimeRange(array('min' => '+1 day')));

この場合、クラス固有の Validatorのような新しいカスタム バリデータを宣言し、その名前でフィールドに直接移動できました。この利点: 「新しい AssertCustom」を適用するだけで別のカスタムを呼び出すことができます。この「AssertCustom」がコンストラクトのようなサービスを必要とする場合、構成サービスがすべてのものを透過的に呼び出すため、依存関係はありません。

再帰的に (深い) フィールドを呼び出す場合は、次のファイルにあるコメントに従ってコンテキストを調整する必要があることに注意してください: Symfony\Component\Validator\Constraints\CollectionValidator

于 2015-05-03T12:50:46.877 に答える