symfony2形式的

时间:2015-07-31 08:41:58

标签: json validation symfony

我正在构建一个Rest API,我从客户端收到一个json_encoded字符串。 我想在保存我的实体之前解码这个字符串,因为它会进入PostgreSQL中的jsonb字段。

我想要的行为是:

  1. 验证字符串是否有效json,如果没有,请通过自定义验证器在表单中添加违规
  2. 自动解码字符串并在实体属性
  3. 中设置json对象

    我尝试了两种不同的策略

    1. 在实体setMetadata($value) method中,如果$valuestring,我会对其进行解码
    2. 我创建了一个DataTransformer json_decode
    3. 形式收到的值

      但是这两个解决方案都不起作用,因为我创建的自定义验证器被调用,并直接调用$lesson->getMetadata()。由于该值已经被解码(在setMetadata() methodDataTransformer中,validator会收到json objectnull。所以我可以' t为表单添加违规,因为我无法知道收到的值是否实际为空,或者字符串是否格式错误。

      以下是课程实体:

      class Lesson extends BaseContent
      {
          […]
      
          /**
           * @var jsonb
           *
           * @ORM\Column(name="metadata", type="jsonb", nullable=true)
           * @KreactiveAssert\Json
           */
          private $metadata;
          […]
      }
      

      以下是自定义验证器:

      class JsonValidator extends ConstraintValidator
      {
          public function validate($value, Constraint $constraint)
          {
              if ($value && !json_decode($value)) {
                  $this->context->addViolation($constraint->message, array('%string%' => $value));
              }
          }
      }
      

      这是DataTransformer:

      class StringToJsonTransformer implements DataTransformerInterface
      {
          /**
           * Transform a json object to a string
           * @param  Json|null $json
           * @return String
           */
          public function transform($json)
          {
              if (null === $json) {
                  return "";
              }
      
              return json_encode($json);
          }
      
          /**
           * Transform a string to a json object
           * @param  String $string
           * @return Object
           */
          public function reverseTransform($string)
          {
              if (!$string) {
                  return null;
              }
      
              throw new TransformationFailedException('error transforming');
      
              return json_decode($string);
          }
      }
      

      有什么方法可以验证表单中的输入数据,然后将元数据设置为json对象?

1 个答案:

答案 0 :(得分:0)

我发现了这个(我不知道为什么我之前没找到它):

Combine constraints and data transformers

我会按照建议制作一个丑陋的解决方法,即使我不喜欢这个解决方案。

<?php

class StringToJsonTransformer implements DataTransformerInterface
{

    /**
     * Transform a string to a json object
     * @param  String $string
     * @return Object
     */
    public function reverseTransform($string)
    {
        if (!$string) {
            return null;
        }


        /*
         * UGLY WORKAROUND
         * we return -1 if the json_decode fail
         * so the validator can add a violation in the form telling
         * the json string was not valid
         * If we don't do this, the validator will receive either
         * null or a json object. In case of null, there is no way to
         * tell if the client sent null, or if the decoding failed
         */
        $value = json_decode($string);

        return $value ? $value : -1;
    }
}

我还不确定我是否要返回-1或其他东西。在自定义验证器中,如果我尝试将jsonObject与-1进行比较(这是正常的),我会收到错误。