【发布时间】:2015-10-22 20:58:42
【问题描述】:
我正在构建一个 Rest API,我从客户端收到一个 json_encoded 字符串。
我希望在保存我的实体之前解码此字符串,因为它会进入 PostgreSQL 中的 jsonb 字段。
我想要的行为是:
- 验证字符串是否为有效的json,如果不是,则通过自定义验证器在表单中添加违规
- 自动解码字符串并在实体属性中设置json对象
我尝试了两种不同的策略
- 在实体
setMetadata($value) method中,如果$value是string,我对其进行解码 - 我创建了一个 DataTransformer,它
json_decode表单中收到的值
但这两种解决方案都不起作用,因为我创建的自定义验证器是在之后调用的,它直接调用$lesson->getMetadata()。由于该值已被解码(在setMetadata() method 或DataTransformer 中,validator 接收json object 或null。所以我不能在表单中添加违规,因为我无法知道收到的值是否实际上为 null,或者字符串是否格式错误。
这是课程实体:
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 对象?
【问题讨论】:
-
首先想到 - 对于 json 验证,您最好不要测试
json_decode()的返回值,而是使用json_last_error()来验证操作结果并使用json_last_error_msg()来构建错误字符串如果合适的话。
标签: json validation symfony