如何为基本类型创建 JMSSerialization 处理程序,例如数组 <-> csv 字符串
How to create a JMSSerialization Handler for for base types, e.g. array <-> csv string
如何为基本类型(如字符串或数组)创建自定义 JMSSerializen 处理程序?目标是以非默认方式(反)序列化 some 属性。例如,指定一个数组 属性 应该反序列化为 CSV 字符串而不是默认的 JSON 数组或一个字符串 属性 反序列化为加密/编码的字符串,等等。
虽然为自定义 class 创建这样的处理程序没问题,但我很难为基本类型做同样的事情。
class SyncableEntityHandler implements SubscribingHandlerInterface {
public static function getSubscribingMethods() {
return [
[
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
'format' => 'json',
'type' => 'SomeClass',
'method' => 'serializeSomeClassToJson',
],
[
'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
'format' => 'json',
'type' => 'SomeClass',
'method' => 'deserializeSomeClassFromJson',
],
];
}
public function serializeSomeClassToJson(JsonSerializationVisitor $visitor, AbstractSyncableEntity $entity, array $type, Context $context) {
...
}
public function deserializeSomeClassFromJson(JsonDeserializationVisitor $visitor, $entityGuid, array $type, Context $context) {
...
}
}
class OtherClass {
/*
* @JMS\Type("SomeClass")
*/
protected $someProperty;
/*
* @JMS\Type("array")
*/
protected $serializeToDefaultArray;
/*
* @JMS\Type("csv_array") // How to do this?
*/
protected $serializeToCSVString;
}
虽然我可以用 'type' => 'array'
创建一个处理程序来更改 所有 数组的(反)序列化,但我不知道只 select 一些个数组。
我已经考虑过使用 getters
和 setters
(例如 getPropertyAsCsvString()
和 setPropertyFromCsvString()
)。虽然这适用于自定义 classes,但我想序列化一些第三方 classes 以及我在 .yaml
文件中指定序列化选项而不是注释的地方。向这些 classes 添加 getter 和 setter 是不可能(容易)的。另外创建这些 getters 和 setter 会增加很多开销。
那么,有没有办法为某些属性创建和指定特殊处理程序?
实现非常简单:
class CsvArrayHandler implements SubscribingHandlerInterface {
public static function getSubscribingMethods() {
return [
[
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
'format' => 'json',
'type' => 'csv_array',
'method' => 'serializeToJson',
],
[
'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
'format' => 'json',
'type' => 'csv_array',
'method' => 'deserializeFromJson',
],
];
}
public function serializeSomeClassToJson(JsonSerializationVisitor $visitor, array $array, array $type, Context $context) {
return implode(',', $array);
}
public function deserializeSomeClassFromJson(JsonDeserializationVisitor $visitor, string $csvString, array $type, Context $context) {
return explode(',', $csvString);
}
}
然后用 @JMS\Type("csv_array")
注释您的 属性 并注册处理程序。
请注意,使用 explode
和 implode
不会转义输入,因此您可能需要使用 league/csv 之类的东西。
如何为基本类型(如字符串或数组)创建自定义 JMSSerializen 处理程序?目标是以非默认方式(反)序列化 some 属性。例如,指定一个数组 属性 应该反序列化为 CSV 字符串而不是默认的 JSON 数组或一个字符串 属性 反序列化为加密/编码的字符串,等等。
虽然为自定义 class 创建这样的处理程序没问题,但我很难为基本类型做同样的事情。
class SyncableEntityHandler implements SubscribingHandlerInterface {
public static function getSubscribingMethods() {
return [
[
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
'format' => 'json',
'type' => 'SomeClass',
'method' => 'serializeSomeClassToJson',
],
[
'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
'format' => 'json',
'type' => 'SomeClass',
'method' => 'deserializeSomeClassFromJson',
],
];
}
public function serializeSomeClassToJson(JsonSerializationVisitor $visitor, AbstractSyncableEntity $entity, array $type, Context $context) {
...
}
public function deserializeSomeClassFromJson(JsonDeserializationVisitor $visitor, $entityGuid, array $type, Context $context) {
...
}
}
class OtherClass {
/*
* @JMS\Type("SomeClass")
*/
protected $someProperty;
/*
* @JMS\Type("array")
*/
protected $serializeToDefaultArray;
/*
* @JMS\Type("csv_array") // How to do this?
*/
protected $serializeToCSVString;
}
虽然我可以用 'type' => 'array'
创建一个处理程序来更改 所有 数组的(反)序列化,但我不知道只 select 一些个数组。
我已经考虑过使用 getters
和 setters
(例如 getPropertyAsCsvString()
和 setPropertyFromCsvString()
)。虽然这适用于自定义 classes,但我想序列化一些第三方 classes 以及我在 .yaml
文件中指定序列化选项而不是注释的地方。向这些 classes 添加 getter 和 setter 是不可能(容易)的。另外创建这些 getters 和 setter 会增加很多开销。
那么,有没有办法为某些属性创建和指定特殊处理程序?
实现非常简单:
class CsvArrayHandler implements SubscribingHandlerInterface {
public static function getSubscribingMethods() {
return [
[
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
'format' => 'json',
'type' => 'csv_array',
'method' => 'serializeToJson',
],
[
'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
'format' => 'json',
'type' => 'csv_array',
'method' => 'deserializeFromJson',
],
];
}
public function serializeSomeClassToJson(JsonSerializationVisitor $visitor, array $array, array $type, Context $context) {
return implode(',', $array);
}
public function deserializeSomeClassFromJson(JsonDeserializationVisitor $visitor, string $csvString, array $type, Context $context) {
return explode(',', $csvString);
}
}
然后用 @JMS\Type("csv_array")
注释您的 属性 并注册处理程序。
请注意,使用 explode
和 implode
不会转义输入,因此您可能需要使用 league/csv 之类的东西。