Mam wiele klas, które chcę serializować z serializatorem Symfony. Na przykładNie wyświetlaj elementu zerowego z serializatorem Symfony
class Foo
{
public $apple = 1;
public $pear = null;
public function serialize() {
Utils::serialize($this);
}
}
które serializacji z następującym serialize()
rozmowy:
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')
}
}
Wyjście wyprodukowany daje mi:
<apple>1</apple><pear/>
Wyjście z oczekiwaniami powinny być:
<apple>1</apple>
Spojrzałem na Symfony 2.8 doc i udało mi się znaleźć szybkie rozwiązanie za pomocą $normalizer->setIgnoredAttributes("pear")
.
Więc ulepszona serialize funkcja statycznego wygląda to
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')
}
}
Jednak to rozwiązanie nie spełnia mnie, ponieważ mam bardziej skomplikowanych przypadków, w których może być różny Foo
własnością tej samej klasy. na przykład
class Bar
{
public $foo1; // (apple=null; pear=2)
public $foo2; // (apple=2; pear=null)
public function serialize() {
Utils::serialize($this);
}
}
Tutaj nie można użyć metody setIgnoredAttributes
od $foo1
i $foo2
nie mają te same elementy null. Ponadto nie nazywam metody serialize
z klasy potomnej (tj. Foo
) tutaj, aby setIgnoredAttributes
było puste.
Bez konieczności pisania skomplikowanego kodu introspekcji, jak mogę ukryć domyślnie element zerowy za pomocą serializera Symfony 2.8? Widziałem na przykład, że jest domyślnie włączone z JMSSerializer.
Obawiam się, że nie jest to łatwy sposób (bez konieczności pisania złożonego kodu introspekcji_), dodając 'elseif (null === $ val) {return false; } 'tutaj https://github.com/symfony/symfony/blob/2.8/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php#L489 rozwiązuje twój problem, ale aby to zrobić, potrzebujesz przepisać dużo kodu, ponieważ prawie wszystkie metody są prywatne w 'XmlEncoder' :( – yceruto
Nigdy go nie używam, ale może przy pomocy serializatora JMS może pomóc ten http://jmsyst.com/bundles/JMSSerializerBundle mam nadzieję, że pomoże – Thomas
@Yonel, naprawdę, chciałbym uniknąć pisania w kodzie symfony Nie jestem sam! Czy nie jest możliwe, aby zastąpić XmlEncoder w sposób nie intruzujący do tego? – coincoin