php – 不要使用Symfony序列化程序显示null元素

所以我有很多我想用Symfony序列化程序序列化的类.例如
class Foo
{
  public $apple = 1;
  public $pear = null;

  public function serialize() {
    Utils::serialize($this);
  }
}

我使用以下serialize()调用序列化:

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>

我查看了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),'xml')
    }
}

然而,这个解决方案并不满足我,因为我有更复杂的情况,其中不同的Foo可以由同一个类拥有.例如

class Bar
{
  public $foo1; // (apple=null; pear=2)
  public $foo2; // (apple=2; pear=null)

  public function serialize() {
    Utils::serialize($this);
  }
}

这里我不能使用setIgnoredAttributes方法,因为$foo1和$foo2没有相同的null元素.此外,我不在这里从子类(即Foo)调用serialize方法,因此setIgnoredAttributes为空.

无需编写复杂的内省代码,如何使用Symfony 2.8序列化器默认隐藏null元素?例如,我已经看到它默认启用了JMSSerializer.

解决方案是从ObjectNormalizer类扩展,覆盖normalize()方法删除那里的所有空值:
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);

// ...

如果我们有一个Person like the one of the official documentation的数组:

// ...

$person1 = new Person();
$person1->setName('foo');
$person1->setAge(null);
$person1->setSportsman(false);

$person2 = new Person();
$person2->setName('bar');
$person2->setAge(33);
$person2->setSportsman(null);

$persons = array($person1,$person2);
$xmlContent = $serializer->serialize($persons,'xml');

echo $xmlContent;

结果将是那些非空节点:

<?xml version="1.0"?>
<response>
    <item key="0">
        <name>foo</name>
        <sportsman>0</sportsman>
    </item>
    <item key="1">
        <name>bar</name>
        <age>33</age>
    </item>
</response>

相关文章

Hessian开源的远程通讯,采用二进制 RPC的协议,基于 HTTP 传输。可以实现PHP调用Java,Python,C#等多语...
初识Mongodb的一些总结,在Mac Os X下真实搭建mongodb环境,以及分享个Mongodb管理工具,学习期间一些总结...
边看边操作,这样才能记得牢,实践是检验真理的唯一标准.光看不练假把式,光练不看傻把式,边看边练真把式....
在php中,结果输出一共有两种方式:echo和print,下面将对两种方式做一个比较。 echo与print的区别: (...
在安装好wampServer后,一直没有使用phpMyAdmin,今天用了一下,phpMyAdmin显示错误:The mbstring exte...
变量是用于存储数据的容器,与代数相似,可以给变量赋予某个确定的值(例如:$x=3)或者是赋予其它的变...