Syrafony中的ConstraintViolationListInterface到Exception

问题描述 投票:1回答:2

我需要将ConstraintViolationListInterface类型的对象转换为单个异常以进行进一步的日志记录,其中消息是在验证失败时来自列表上每个约束违规的消息的串联。

显然,我无法使用验证来重复每个包中的foreach循环来实现这一点,因此我考虑创建一个包,提供接受ConstraintViolationListInterface并返回单个异常的简单服务。在Symfony中有这个标准的解决方案吗?似乎很奇怪我需要编写这个服务,这个问题似乎对我来说很常见。

php symfony symfony-validator
2个回答
4
投票

我也很惊讶symfony对此没有任何帮助,这就是我创建自定义异常的原因:

class ValidationException extends \Exception
{
    private $violations;

    public function __construct(array $violations)
    {
        $this->violations = $violations;
        parent::__construct('Validation failed.');
    }

    public function getMessages()
    {
        $messages = [];
        foreach ($this->violations as $paramName => $violationList) {
            foreach ($violationList as $violation) {
                $messages[$paramName][] = $violation->getMessage();
            }
        }
        return $messages;
    }

    public function getJoinedMessages()
    {
        $messages = [];
        foreach ($this->violations as $paramName => $violationList) {
            foreach ($violationList as $violation) {
                $messages[$paramName][] = $violation->getMessage();
            }
            $messages[$paramName] = implode(' ', $messages[$paramName]);
        }
        return $messages;
    }
}

所有代码可用here

我在下一个方面使用此异常:

try {
    $errors = $validator->validate(...);
    if (0 !== count($errors)) {
        throw new ValidationException($errors);
    }
} catch (ValidationException $e) {
    // Here you can obtain your validation errors. 
    var_dump($e->getMessages());
}

0
投票

也许你可以像这样创建一个ConstraintViolationsEvent:

namespace AppBundle\Event;

use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\Validator\ConstraintViolationListInterface;

/**  
 * The order.placed event is dispatched each time an order is created
 * in the system.
 */
class ConstraintViolationsEvent extends Event
{
    const VIOLATIONS_DETECTED = 'constraint_violations.detected';

    protected $constraintViolationList;

    public function __construct(ConstraintViolationListInterface $constraintViolationList)
    {
        $this->constraintViolationList = $constraintViolationList;
    }

    public function getConstraintViolationList()
    {
        return $this->constraintViolationList;
    }
}

然后,您可以为此事件创建一个侦听器,并在此侦听器中,根据找到的所有违规创建您的异常。每次您发现违规行为时,您只需在控制器内发送您的活动,如下所示:

class MyController extends Controller
{
    public function myFormAction(Request $request)
    {
        /** handle the request, get the form data, validate the form...etc. **/
        $event = new ConstraintViolationsEvent($constraintViolationList);
        $dispatcher->dispatch(ConstraintViolationsEvent::VIOLATIONS_DETECTED, $event);
    }
}

实际上,您可以在服务中管理Exception的创建,并在侦听器中调用服务。它是由你决定。

© www.soinside.com 2019 - 2024. All rights reserved.