superruzafa/settings-loader

1.0.1 2014-10-16 20:43 UTC

This package is not auto-updated.

Last update: 2024-09-24 07:55:22 UTC


README

Build Status

设置加载器是一个库,可以从多个来源(目前仅支持XML)加载设置。

XML加载器

此加载器从具有给定结构的XML文件中加载设置

<!-- settings.xml -->

<?xml version="1.0" encoding="UTF-8"?>
<s:abstract xmlns="http://github.com/superruzafa/settings-loader">

	<country>Japan</country>

	<s:settings>
    	<company>Nintendo</company>
    </s:settings>

	<s:settings>
    	<company>Sony</company>
    </s:settings>

</s:abstract>
<?php

use \DomDocument;
use Superruzafa\Settings\Loader\XmlLoader;

$doc = new DomDocument();
$doc->load(__DIR__ . '/settings.xml');
$loader = new XmlLoader($doc);
$loader->load();
$settings = $loader->getSettings();

// $settings = array(
//   array(
//     'country' => 'Japan',
//     'company' => 'Nintendo',
//   ),
//   array(
//     'country' => 'Japan',
//     'company' => 'Sony',
//   )
// )

本质上,您可以按照以下步骤创建自己的XML设置文件

  • 在XML中定义一个命名空间,指向 http://github.com/superruzafa/settings-loader
  • 使用该命名空间中的两个保留标签来定义 设置条目<abstract><settings>
  • 无命名空间的标签将用作键值对,并构建 设置条目

<abstract><settings>

<abstract><settings> 标签都定义一个上下文(或更改上一个上下文)。然而,<settings> 接受当前上下文并在全局设置列表中创建一个 设置条目

总结来说,当您想定义一个将被 <settings> 使用来覆盖的 <abstract> 定义的全球上下文时,应该使用 <abstract>

继承

<abstract><settings> 节点都继承其祖先定义的值,并可以组合在一起轻松创建大量设置。这些标签可以嵌套

<s:settings>
    <s:abstract>
        <s:settings>
            <s:settings>
                ...
            </s:settings>
        </s:settings>
    
        <s:settings>
            <s:abstract>
                ...
            </s:abstract>
        </s:settings>
    <s:abstract>

    <s:settings>
        ...
    </s:settings>
</s:settings>

元素与属性

<abstract><setting> 节点都允许使用元素和属性来定义它们的上下文。这两个示例会创建相同的设置

<s:settings>
  <language>PHP</language>
  <purpose>Web and more</purpose>
</s:settings>
<s:settings language="PHP" purpose="Web and more" />
<s:settings language="PHP">
  <language>PHP</language>
</s:settings>

您可以使用最适合您需求的方法。

数组

当同一上下文中出现两次或更多相同的键时,该键的值将解释为数组,而不是保留最后一个定义的值

<s:settings>
	<colors>red</colors>
	<colors>green</colors>
	<colors>blue</colors>
</s:settings>
// array(
//   array('colors' => array('red', 'green', 'blue'))
// )

在继承中,子设置会覆盖其父设置

原因:否则具有其父设置已定义的键的设置节点总是会将其值附加到其父设置的值上,从而创建一个数组。

<s:settings>
	<colors>black</colors>
	<colors>white</colors>
    
	<s:settings>
		<colors>red</colors>
		<colors>green</colors>
		<colors>blue</colors>
	</s:settings>
    
	<s:settings>
		<colors>transparent</colors>
	</s:settings>
      
<s:settings>	
// array(
//   array('colors' => array('black', 'white')),
//   array('colors' => array('red', 'green', 'blue'))
//   array('colors' => 'transparent')
// )

字符串插值

字符串值可以被视为模板。

当字符串包含类似 {{ username }} 的内容时,解析器会在当前上下文中查找与键 "username" 关联的值并进行替换。

<s:settings>
	<language>PHP</language>
	<string>I like {{ language }}</string>
</s:settings>
// array(
//   'language' => 'PHP',
//   'string' => 'I like PHP',
// )

您甚至可以链式进行更复杂的插值和层次结构

<s:abstract>
	<s:settings who="I">
		<language>PHP</language>
		<string>{{ who }} {{ preference }} {{ language }} {{ how-many }}</string>
        <preference>like</preference>
	</s:settings>
    
	<how-many>so much!<how-many>
    <preference>love</preference>
    
</s:abstract>
// array(
//   'who' => 'I',
//   'language' => 'PHP',
//   'string' => 'I like PHP so much!',
//   'preference' => 'like',
// )

注意事项

不存在的键将被替换为空字符串,并生成警告。

<s:settings>
   	<string>My name is {{ name }}</key1>
</s:setting>
// array(
//   array (
//     'string' => 'My name is ',
//   )
// )

循环递归解析将以空字符串结束,并生成警告

<s:settings>
   	<key1>Need {{ key2 }}</key1>
   	<key2>Need {{ key3 }}</key2>
   	<key3>Need {{ key1 }}</key3>
</s:setting>
// array(
//   array (
//     'key1' => 'Need Need Need ',
//     'key2' => 'Need Need ',
//     'key3' => 'Need ',
//   )
// )

数组插值将被替换为 "<array>" 并生成警告

<s:settings>
   	<seasons>Spring</seasons>
   	<seasons>Summer</seasons>
   	<seasons>Autumn</seasons>
   	<seasons>Winter</seasons>
    <year>A year is composed by {{ seasons }}</year>
</s:setting>
// array(
//   array (
//     'seasons' => array('Spring','Summer','Autumn','Winter'),
//     'year' => 'A year is composed by <array>',
//   )
// )