【发布时间】:2018-01-26 10:43:42
【问题描述】:
我有以下代码示例,它定义了一个联系人类,该类可以保存姓名和电话号码列表。我想要做的是在所有数字上设置一个“primary”属性,其中一个任意一个的值为“1”,其余的为“0”。
我真的很想使用类方法来做到这一点,但找不到使用 setter 的方法 - 有没有可能?
这是我的代码。在里面我:
- 创建我的对象并设置它们的属性
- print_r 联系人对象以查看其存储方式
- 将我希望能够生成的 xml 反序列化到 相同的联系人对象
- print_r 联系人对象以查看其存储方式
- 使用 setter 添加另一个数字
- print_r 联系人对象以查看其存储方式
- 序列化为 xml,看看对象和数组的混合如何处理
- 打印xml
<?php
// Symfony Serializer experiment
require $_SERVER['DOCUMENT_ROOT'].'/libraries/symfony/vendor/autoload.php';
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
Class Number {
private $Number;
private $Type;
// Getters
public function getNumber()
{
return $this->Number;
}
public function getType()
{
return $this->Type;
}
// Setters
public function setNumber($number)
{
$this->Number = $number;
return $this;
}
public function setType($type)
{
$this->Type = $type;
return $this;
}
}
class Contact
{
private $Name;
private $Numbers = array();
function __construct() {
${@Primary} = 0;
}
// Getters
public function getName()
{
return $this->Name;
}
public function getNumbers()
{
return $this->Numbers;
}
// Setters
public function setName($name)
{
$this->Name = $name;
return $this;
}
public function setNumbers($numbers)
{
$this->Numbers = $numbers;
return $this;
}
public function addNumber($number) {
$this->Numbers['Number'][] = $number;
}
}
// Serializer setup
$xmlEncoder = new XmlEncoder();
$xmlEncoder->setRootNodeName('Contact');
$encoders = array($xmlEncoder, new JsonEncoder());
$normalizers = array(new ObjectNormalizer());
$serializer = new Serializer($normalizers, $encoders);
// Create my object
$contact = new Contact();
$contact->setName('baa');
$number = new Number();
$number->setNumber('07878386123')->setType('Mobile');
$contact->addNumber($number);
// take a look at how it's stored
echo "<pre lang=xml>";
print_r($contact);
echo "</pre><br><br>";
// deserialize my desired xml into the same object
$data = <<<EOF
<Contact>
<Name>foo</Name>
<Numbers>
<Number primary='1'>
<Number>07878386459</Number>
<Type>Mobile</Type>
</Number>
<Number primary='0'>
<Number>02380860835</Number>
<Type>Landline</Type>
</Number>
</Numbers>
</Contact>
EOF;
$contact = $serializer->deserialize($data, Contact::class, 'xml', array('object_to_populate' => $contact));
// take a look at how it's stored
echo "<pre lang=xml>";
print_r($contact);
echo "</pre><br><br>";
// Add another number
$number = new Number();
$number->setNumber('02387345123')->setType('Landline');
$contact->addNumber($number);
// take a look at how it's stored
echo "<pre lang=xml>";
print_r($contact);
echo "</pre><br><br>";
// serialize to xml and see how the mixture of objects and arrays are treated
$xmlContent = $serializer->serialize($contact, 'xml');
$dom = new domDocument( '1.0', 'utf-8' );
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$result = $dom->loadXML($xmlContent);
$xmlContentFormatted=htmlentities($dom->saveXML());
?>
<pre lang=xml><?= $xmlContentFormatted ?></pre>
我在输出中看到的是:
2)
Contact Object
(
[Name:Contact:private] => baa
[Numbers:Contact:private] => Array
(
[Number] => Array
(
[0] => Number Object
(
[Number:Number:private] => 07878386123
[Type:Number:private] => Mobile
)
)
)
)
4)
Contact Object
(
[Name:Contact:private] => foo
[Numbers:Contact:private] => Array
(
[Number] => Array
(
[0] => Array
(
[@primary] => 1
[Number] => 07878386459
[Type] => Mobile
)
[1] => Array
(
[@primary] => 0
[Number] => 02380860835
[Type] => Landline
)
)
)
6) 对象和数组的混合。我可以对我的 Number 类进行编码,以便它使用数组而不是属性,并有另一种设置属性的方法吗? (例如
$number->setNumber('07878386123')->setType('Mobile')->addAttr(array('primary' => '1'));
Contact Object
(
[Name:Contact:private] => foo
[Numbers:Contact:private] => Array
(
[Number] => Array
(
[0] => Array
(
[@primary] => 1
[Number] => 07878386459
[Type] => Mobile
)
[1] => Array
(
[@primary] => 0
[Number] => 02380860835
[Type] => Landline
)
[2] => Number Object
(
[Number:Number:private] => 02387345123
[Type:Number:private] => Landline
)
)
)
)
8)
<?xml version="1.0"?>
<Contact>
<Name>foo</Name>
<Numbers>
<Number primary="1">
<Number>07878386459</Number>
<Type>Mobile</Type>
</Number>
<Number primary="0">
<Number>02380860835</Number>
<Type>Landline</Type>
</Number>
<Number>
<Number>02387345123</Number>
<Type>Landline</Type>
</Number>
</Numbers>
</Contact>
当从具有使用属性的标签的 XML 反序列化时,php 对象使用数组,因此如果你想从一个可以被赋予属性的 php 表示开始,你需要使用数组。
【问题讨论】:
标签: symfony xmlserializer serialization