だから、Symfonyシリアライザでシリアライズしたいクラスがたくさんあります。生成される出力は私を与えるSymfonyシリアライザでヌル要素を表示しない
class Utils {
public static function serialize($object) {
$encoder = new XmlEncoder();
$normalizer = new ObjectNormalizer();
$serializer = new Serializer(array($normalizer), array($encoder));
$str = $serializer->serialize($object, 'xml')
}
}
:
<apple>1</apple><pear/>
予想される出力は次のようになります。
<apple>1</apple>
インスタンス私は、次の
serialize()
呼び出しでシリアライズ
class Foo
{
public $apple = 1;
public $pear = null;
public function serialize() {
Utils::serialize($this);
}
}
用
私はSymfony 2.8 docを見て、$normalizer->setIgnoredAttributes("pear")
を使って簡単な解決法を見つけました。
ので、改善されたシリアル化、静的な関数は、この
class Utils {
public static function ignoreNullAttributes($object) {
$ignored_attributes = array();
foreach($object as $member => $value) {
if (is_null($object->$member)) {
array_push($ignored_attributes, $member);
}
}
return $ignored_attributes;
}
public static function serialize($object) {
$encoder = new XmlEncoder();
$normalizer = new ObjectNormalizer();
$normalizer->setIgnoredAttributes(Utils::ignoreNullAttributes($object));
$serializer = new Serializer(array($normalizer), array($encoder));
$str = $serializer->serialize($object, 'xml')
}
}
のように見える、私は別のFoo
は、同じクラスが所有することができ、より複雑な例を持っているのでしかし、この解決策は、私を満たしていません。例えば
class Bar
{
public $foo1; // (apple=null; pear=2)
public $foo2; // (apple=2; pear=null)
public function serialize() {
Utils::serialize($this);
}
}
は、ここで私は、同じnull要素を持っていない$foo1
と$foo2
以来setIgnoredAttributes
メソッドを使用することはできません。さらに、子クラス(Foo
)からserialize
メソッドを呼び出してsetIgnoredAttributes
が空になるようにしていません。
複雑なイントロスペクションコードを書くことなく、デフォルトでSymfony 2.8シリアライザのnull要素を隠すことができますか?たとえば、デフォルトではJMSSerializerと有効になっています。我々はPerson like the one of the official documentationの配列を持っている場合
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
class CustomObjectNormalizer extends ObjectNormalizer
{
public function normalize($object, $format = null, array $context = [])
{
$data = parent::normalize($object, $format, $context);
return array_filter($data, function ($value) {
return null !== $value;
});
}
}
$encoders = array(new XmlEncoder());
$normalizers = array(new CustomObjectNormalizer());
$serializer = new Serializer($normalizers, $encoders);
// ...
:
複雑なイントロスペクションcode_を書く必要はありませんが、簡単な方法はありません。恐らく、 'elseif(null === $ val){return false; } 'ここでhttps://github.com/symfony/symfony/blob/2.8/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php#L489は問題を解決しますが、これを行うには多くのコードを書き直す必要があります。ほとんどすべてのメソッドは 'XmlEncoder'にプライベートです:( – yceruto
これは決して使用しませんでしたが、おそらくJMSシリアライザを使用してhttp://jmsyst.com/bundles/JMSSerializerBundleが助けてくれると助かります – Thomas
@Yonelありがとう本当にありがとうsymfonyのコードで私は一人ではありません!XmlEncoderを非侵入的な方法でオーバーライドすることは可能でしょうか? – coincoin