realshadow/serializers

PHP JSON, JSONP, XML, YAML, INI 序列化器集合

1.0 2015-12-18 16:30 UTC

This package is auto-updated.

Last update: 2024-09-19 01:08:25 UTC


README

为PHP 5.3编写,以解决从数组转换时元素的强化和复数化问题。当我们通过PHP、Python和.NET传递XML文件时,序列化器之间的区别很明显。后来,添加了更多序列化器以获得完整的包。

目标是自动在序列化为XML时执行复数化。例如:

array(
	'products' => array(
	    array(
	        'brand' => 'Samsung',
	        'model' => 'Galaxy',
	        'price' => 999
	    ),
	    array(
	        'brand' => 'HTC',
	        'model' => 'One',
	        'price' => null
	    )
	)
);

这将序列化为:

 <products>
  <product>
   <brand>Samsung</brand>
   <model>Galaxy</model>
   <price>999</price>
  </product>
  <product>
   <brand>HTC</brand>
   <model>One</model>
   <price xsi:nil="true"></price>
  </product>
 </products>

而不是(这是默认行为)

 <products>
   <brand>Samsung</brand>
   <model>Galaxy</model>
   <price>999</price>
 </products>
 <products>
   <brand>HTC</brand>
   <model>One</model>
   <price xsi:nil="true"></price>
 </products>

相同的规则也适用于反序列化,通过使用不同的序列化器,会变成不同的数组。通过相反的复数化,可以<强>返回与序列化相同的数组

XML序列化

支持

  • 属性、命名空间、cdata和注释
  • 单词复数化 - products => product
  • 自动添加 xsi:nil=true 到null元素选项
  • 节点操作的触发事件
$array = array(
	Serializers\Encoders\Xml::ATTRIBUTES => array(
		'xmlns' => 'http://cfh.sk/izmluvnik/xsell',
		Serializers\Encoders\Xml::NS => array(
			array(
				'name' => 'xmlns:xsi',
				'content' => 'http://www.w3.org/2001/XMLSchema-instance'
			),
			array(
				'name' => 'xmlns:xsd',
				'content' => 'http://www.w3.org/2001/XMLSchema'
			)
		)
	),
	'products' => array(
	    array(
	        'brand' => 'Samsung',
	        'model' => 'Galaxy',
	        'price' => 999
	    ),
	    array(
	        'brand' => 'HTC',
	        'model' => 'One',
	        'price' => null
	    )
	)
);

$xml = Serializers\Encode::toXml('root', $array, array(
    'singularize_words' => true,
    'nil_on_null' => true
));

print $xml->withHeaders();

输出:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://cfh.sk/izmluvnik/xsell" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <products>
  <product>
   <brand>Samsung</brand>
   <model>Galaxy</model>
   <price>999</price>
  </product>
  <product>
   <brand>HTC</brand>
   <model>One</model>
   <price xsi:nil="true"></price>
  </product>
 </products>
</root>

XML反序列化

默认情况下,每条注释、属性、命名空间都将从结果中删除,以及根元素。每个选项都可以在配置中打开/关闭

反序列化是通过SimpleXML配合json_encode(在这种情况下提供JSON解码器)完成的,增加了一个简单的方法 - SimpleXML对象在编码前会被转换(JSONSerialize接口的回滚)

注释通过DOMXpath单独解析(因为SimpleXML无法处理它们),并添加到单独的数组中,其中包含指向其原始位置的索引,这样就可以很容易地将注释与主要结果合并并接收原始数组。

默认情况下,将元素从其单数对应物转换回复数并因此简化整个数组是关闭的,必须打开。可以包括新映射的单词和排除特定单词。这与提供的XML编码器完全一样。

简化的整个目的是要返回与创建提供的XML时使用的数组<强>完全相同的数组。

// using the same XML that we got in serialization
$output = Serializers\Decode::xml($xml->load(), array('singularize_words' => true));

输出<强>完全相同的数组,如前面的例子所示

print_r($output->toArray());

JSON反序列化

支持

  • 自动解析Microsoft的JSON日期格式(例如 /Date(1425556377427+0100)/
  • PHP 5.4.0中可用的JSON_BIGINT_AS_STRING的回滚
  • isValid方法用于检查提供的JSON字符串的有效性
  • 可能从JSON转换为
    • PHP类型(字符串、数组、对象)
    • XML、YAML、INI

通过覆盖配置,可以更改MS日期转换的默认时间格式和时区设置,或完全关闭。

可以在大整数转义期间注册事件回调,以在转义不足或完全关闭的情况下调用。

回调方法必须接受一个参数,即注册的JSON字符串。回调可以是闭包或其他任何可以作为可调用的东西。

$json = <<<EOT
    {
        "foo" : "bar",
        "small" : "123456",
        "large" : 200000000000009093302,
        "text" : "Example ratio 1000000000000000:1",
        "date" : "/Date(1425556377427+0100)/"
    }
EOT;

$s = Serializers\Decode::json($json);

print_r($s->toObject());

// transform said json to xml and output it

print Serializers\Decode::json($json)->toXml('root')->withHeaders();

// events

$json = Serializers\Decode::json($json)->on(Serializers\Events::JSON_MSDATE_MATCH, function($date) {
    // matches returned from preg_replace_callback
    list(, $timestamp,,) = $date;

    return date('Y-m-d H:i:s', $timestamp);
});

JSON序列化

可以注册JSON_SERIALIZE事件,它的工作方式与PHP 5.4的JsonSerializable接口完全相同,因此允许在对象转换为JSON之前对其进行修改。

JSON序列化器还包括创建Microsoft JSON日期格式日期的方法,例如 /Date(1425556377427+0100)/

$json = Serializers\Encode::toJson(array(
    'foo' => 'bar',
    'foodate' => date('d.m.Y H:i:s')
))->onSerialize(function($data) {
    $data['foodate'] = Serializers\Encoders\Json::toMSDate($data['foodate']);

    return $data;
});

print $json->withHeaders();

JSONP序列化

一个易于JSONP序列化的类,行为类似于JSON序列化器,并增加了对回调函数名称的验证检查,可以通过自定义事件来更改

$jsonp = Serializers\Encode::toJsonp('_foo.bar', array(
    'foo' => 'bar',
    'bar' => 'foo'
));

$jsonp->allowCors('*', array('GET', 'POST'));

print $jsonp->withHeaders();

JSONP反序列化

一个易于JSONP反序列化的类,行为类似于JSON反序列化器

$json = '_foo.bar({"foo":"bar","bar":"foo"})';

$data = Serializers\Decode::jsonp($json);

print_r($data->toObject());

// transform said json to xml with callback name as root element and output it

print Serializers\Decode::jsonp($json)->toXml()->withHeaders();

YAML序列化器

底层使用Symfony的YAML组件

$yaml = \Serializers\Encode::toYaml($array);

print_r($yaml->load());

// or

$yaml->toFile('config.yml');

YAML反序列化器

底层使用Symfony的YAML组件。

转换到XMLJSON等格式是可能的,但受YAML转换器可能性的限制。

$yaml = Serializers\Decode::yaml(file_get_contents('config.yml'));

print_r($yaml->toObject());

// transform said json to xml and output it

print Serializers\Decode::yaml(file_get_contents('config.yml'))->toXml('yaml')->withHeaders();

INI反序列化器

使用由@austinhyde编写的INI解析器

$array = array(
	'a' => 'd',
	'b' => array('test' => 'c'),
	'database' => array(
		'default' => array(
			'name' => 'db',
			'host' => 'master.db',
			'ip' => 'dd',
		)
	),
	'array' => array('a', '1', 3),
);

$encode = Serializers\Encode::toIni($array);
$encode->toFile('config.ini');

INI序列化器

功能仅限于基本的INI格式,例如不支持继承。由于目前看不到很好的用例,这个类仅用于保持完整的编码器/解码器堆栈在一起

$ini = Serializers\Encode::toIni($array);

print_r($ini->load());