ivi/tree-manipulator

用于操作树结构数据的库

dev-master 2018-05-02 18:12 UTC

This package is not auto-updated.

Last update: 2024-09-24 17:53:07 UTC


README

TreeManipulator是一个PHP库,允许您轻松地遍历树数据结构并更改其内容。该库在保存为关联数组的树结构上工作。该库允许

  • 通过单步操作移动树
  • 通过输入路径移动树
  • 检查给定的路径是否存在于树中
  • 搜索与模式匹配的现有路径
  • 下载树元素
  • 创建树元素
  • 删除树元素
  • 复制树片段

需求

  • PHP版本至少为5.3.0
  • composer

安装

我们使用composer将库附加到项目中。composer.json文件必须包含

{
	"require": {
        "ivi/tree-manipulator": "dev-master"
    },
    "minimum-stability": "dev"
}

然后执行composer install命令。之后,您可以在项目的src文件夹中添加自动加载器

require_once '/../vendor/autoload.php';

并通过命名空间TreeManipulator导入库类。

文档

接口

IteratorInterface

描述如何与迭代器交互的接口。该接口包含描述路径元素的常量

  • SEPARATOR - /字符分隔路径中的步骤
  • STEP_ROOT - 空元素,表示移动到树的根
  • STEP_CURRENT - 字符.表示保持在当前元素中
  • STEP_UP - 字符串..表示转到父元素
  • STEP_ANY - *符号表示具有任意名称的子元素
  • STEP_MANY_ANY - 字符串**表示具有任意名称的子代

接口声明以下方法

  • setStructure($structure, $steps = null) : void - 将树数据加载到迭代器中
  • getStructure($encode = true) : array - 从迭代器加载树数据
  • getCurrent() : array - 从当前迭代器位置获取树片段
  • setCurrent($data) : void - 在当前迭代器位置设置数据
  • getSteps() : array - 获取从根到当前迭代器位置的步骤列表
  • hasParent() : boolean - 如果当前元素有父元素返回true,否则返回false
  • getCurrentChildsName() : array - 返回所有元素子元素的列表
  • hasChildNamed($childName) : boolean - 如果当前元素有名为$childName的子元素返回true,否则返回false
  • moveRoot() : void - 将迭代器指针移动到根
  • moveUp() : void - 将迭代器指针移动到父元素
  • moveDown($childName) : void - 将迭代器指针移动到具有$childName名称的子元素
  • performSimpleStep($step) : void - 执行步骤,设置为参数
  • reset() : void - 将迭代器指针移动到根
  • performSimplePath($path = IteratorInterface::STEP_CURRENT) : array - 根据路径在树中移动迭代器指针
  • checkSimplePath($path = IteratorInterface::STEP_CURRENT) : boolean - 检查从当前元素是否存在参数设置的路径,如果正确返回true

StepsIterator

StepsIterator存储树结构,关于树中当前位置的信息,并允许您更改此位置。它实现了IteratorInterface接口并实现了其中声明的一切函数。此类是一个包装器,允许您执行树操作。

PathFinder

此类将非简单路径(即包含步骤***的路径)转换为树中存在的简单路径列表,在这些路径上执行操作。它包含两个公共方法

  • isSimplePath($path) : boolean - 如果路径简单则返回 true,否则返回 false
  • createSimplePaths($iterator, $path) - 对于指定的迭代器(包含树)和给定的路径创建简单路径列表

TreeEditor

该类允许编辑树结构。构造函数参数采用实现 IteratorInterface 接口的对象,通过该对象在树上进行操作。具有以下公共方法

  • setIterator(IteratorInterface $iterator) : void - 设置新的迭代器
  • getIterator() : void - 获取当前迭代器
  • readValue() : void - 从当前迭代器指针获取值
  • readValueFrom($path) : void - 从给定路径获取值(移动迭代器指针)
  • writeValue($value) : void - 将值保存到当前迭代器指针
  • writeValueTo($path, $value, $allowCreatePath = true) : void - 将值保存到给定路径(移动迭代器指针),如果 $allowCreatePath 为 true,则创建路径(如果不存在)
  • removeValue($name) : void - 从当前迭代器位置移除具有给定名称的子节点
  • removeValueFrom($path, $name) : void - 从给定路径移除具有给定名称的子节点(移动迭代器指针)
  • addValue($name, $values = null) : void - 在当前迭代器位置添加具有给定名称和内容的子节点
  • addValueTo($path, $name, $value = null, $allowCreatePath = true) : void - 在给定路径添加具有给定名称和内容的子节点(移动迭代器指针),如果 $allowCreatePath 为 true,则创建路径(如果不存在)
  • addValues(array $values) : void - 在当前迭代器位置添加子节点
  • addValuesTo($path, array $values, $allowCreatePath = true) : void - 在给定路径添加子节点(移动迭代器指针),如果 $allowCreatePath 为 true,则创建路径(如果不存在)
  • createPath($path) : void - 创建给定路径或其片段(如果不存在)
  • copyValue($srcPath, $descPath, $allowCreatePath = true) : void - 从 $srcPath 移动内容到 $descPath,如果 $allowCreatePath 为 true,则创建路径(如果不存在)

异常类

StructureException

当给定的树结构不正确时抛出。错误编号 1。

StepsException

当给定的步骤列表不正确时抛出。错误编号 11。

IteratorMoveException

当在树中执行移动到非存在元素时抛出。错误编号

  • 错误 21 - 尝试执行不正确的移动
  • 错误 22 - 尝试移动到非存在的父元素
  • 错误 23 - 尝试移动到非存在的子元素
  • 错误 24 - 尝试通过一个不存在的路径

用法

将 StepsIterator 类添加到 .php 文件中

<?php
require_once '/../vendor/autoload.php';
use TreeManipulator\StepsIterator;

$iterator = new StepsIterator();
var_dump($iterator);

创建迭代器并在树中移动

<?php

require_once '/../vendor/autoload.php';

use TreeManipulator\StepsIterator;

// Create tree data structure as array
$tree = [
	'user_id' => 1,
	// other fields ...
	'transactions' => [
		[
			'transaction_id' => 123,
			'transactionStatus' => 'PAID',
			'products' => [
				[
					'product_id' => 01234,
					'value' => 1.11
				],
				[
					'product_id' => 56789,
					'value' => 2.22,
				]
			]
		],
		[
			'transaction_id' => 456,
			'transactionStatus' => 'PAID',
			'products' => [
				[
					'product_id' => 111111,
					'value' => 3.33
				]
			]
		]
	]
];

// Create iterator and set tree as data structure
$iterator = new StepsIterator();
$iterator->setStructure($tree);

// Move iterator pointer to transactions list
$iterator->moveDown('transactions');

// Move iterator pointer to second transaction
$iterator->moveDown('1');

// Save transaction data in variable
$a = $iterator->getCurrent();

// Back to transactions list
$iterator->moveUp();

// Back to root
$iterator->reset();

// Path to first transaction second product price
$path = '/transactions/0/products/1/value';
// Check if this path exist in tree
$iterator->checkSimplePath($path);
// Perform this path
$iterator->performSimplePath($path);

检查路径是否简单

<?php

require_once '/../vendor/autoload.php';

use TreeManipulator\PathFinder;

// Create PathFinder object
$pathFinder = new PathFinder();

// Simple path (without * and ** steps)
$path = '/step1/step2/step3';
// Will return true
$pathFinder->isSimplePath($path);

// Non simple path (with *)
$path = '/step1/step2/*';
// Will return false
$pathFinder->isSimplePath($path);

// Non simple path (with **)
$path = '/step1/**/step3';
// Will return false
$pathFinder->isSimplePath($path);

根据模式创建路径列表

<?php

require_once '/../vendor/autoload.php';

use TreeManipulator\StepsIterator;
use TreeManipulator\PathFinder;

// Create tree data structure as array
$tree = [
	'user_id' => 1,
	// other fields ...
	'transactions' => [
		[
			'transaction_id' => 123,
			'transactionStatus' => 'PAID',
			'products' => [
				[
					'product_id' => 01234,
					'value' => 1.11
				],
				[
					'product_id' => 56789,
					'value' => 2.22,
				]
			]
		],
		[
			'transaction_id' => 456,
			'transactionStatus' => 'PAID',
			'products' => [
				[
					'product_id' => 111111,
					'value' => 3.33
				]
			]
		],
		[
			'transaction_id' => 789,
			'transactionStatus' => 'UNPAID',
			'products' => [
				[
					'product_id' => 333333,
					'value' => 4.44
				]
			]
		]
	]
];

$iterator = new StepsIterator();
$iterator->setStructure($tree);

$pathFinder = new PathFinder();

$path = 'transactions/*';
$foundPaths = $pathFinder->createSimplePaths($iterator, $path);
// Will return Array ( [0] => transactions/0 [1] => transactions/1 [2] => transactions/2 )
print_r($foundPaths);

$path = 'transactions/**/product_id';
$foundPaths = $pathFinder->createSimplePaths($iterator, $path);
// Will return Array ( [0] => transactions/0 [1] => transactions/1 [2] => transactions/2 ) Array ( [0] => transactions/0/products/0/product_id [1] => transactions/0/products/1/product_id [2] => transactions/1/products/0/product_id [3] => transactions/2/products/0/product_id ) 
print_r($foundPaths);

从树中读取值

<?php

require_once '/../vendor/autoload.php';

use TreeManipulator\StepsIterator;
use TreeManipulator\TreeEditor;

// Create tree data structure as array
$tree = [
	'user_id' => 1,
	'firstname' => 'John',
	'lastname' => 'Smith',
	'dateOfBirth' => '1990-01-01',
	'addresses' => [
		[
			'city' => 'New York',
			'street' => 'Broadway',
			'number' => 123
		]
	],
	'phones' => [
		'123456789',
		'987654321'
	],
	'email' => 'john.smith@mail.com',
	'subscribe' => false
];

$iterator = new StepsIterator();
$iterator->setStructure($tree);
$treeEditor = new TreeEditor($iterator);

// Will return full tree
$treeEditor->readValue();

$treeEditor->getIterator()->moveDown('phones');
// Will return list of phone numbers
$treeEditor->readValue();

// Will return 'New York'
$treeEditor->readValueFrom('/addresses/0/city');

在树中更改值

<?php

require_once '/../vendor/autoload.php';

use TreeManipulator\StepsIterator;
use TreeManipulator\TreeEditor;

// Create tree data structure as array
$tree = [
	'user_id' => 1,
	'firstname' => 'John',
	'lastname' => 'Smith',
	'dateOfBirth' => '1990-01-01',
	'addresses' => [
		[
			'city' => 'New York',
			'street' => 'Broadway',
			'number' => 123
		]
	],
	'phones' => [
		'123456789',
		'987654321'
	],
	'email' => 'john.smith@mail.com',
	'subscribe' => false
];

$iterator = new StepsIterator();
$iterator->setStructure($tree);
$treeEditor = new TreeEditor($iterator);

$treeEditor->getIterator()->moveDown('phones');
// Will change list of phone numbers to 'foo' string
$treeEditor->writeValue('foo');

// Will change 'New York' to 'Dallas'
$treeEditor->writeValueTo('/addresses/0/city', 'Dallas');

从树中移除值

<?php

require_once '/../vendor/autoload.php';

use TreeManipulator\StepsIterator;
use TreeManipulator\TreeEditor;

// Create tree data structure as array
$tree = [
	'user_id' => 1,
	'firstname' => 'John',
	'lastname' => 'Smith',
	'dateOfBirth' => '1990-01-01',
	'addresses' => [
		[
			'city' => 'New York',
			'street' => 'Broadway',
			'number' => 123
		]
	],
	'phones' => [
		'123456789',
		'987654321'
	],
	'email' => 'john.smith@mail.com',
	'subscribe' => false
];

$iterator = new StepsIterator();
$iterator->setStructure($tree);
$treeEditor = new TreeEditor($iterator);

$treeEditor->getIterator()->moveDown('phones');
// Will remove first phone number
$treeEditor->removeValue('0');

// Will remove 'city' field from tree
$treeEditor->removeValueFrom('/addresses/0', 'city');

向树中添加元素

<?php

require_once '/../vendor/autoload.php';

use TreeManipulator\StepsIterator;
use TreeManipulator\TreeEditor;

// Create tree data structure as array
$tree = [
	'user_id' => 1,
	'firstname' => 'John',
	'lastname' => 'Smith',
	'dateOfBirth' => '1990-01-01',
	'addresses' => [
		[
			'city' => 'New York',
			'street' => 'Broadway',
			'number' => 123
		]
	],
	'phones' => [
		'123456789',
		'987654321'
	],
	'email' => 'john.smith@mail.com',
	'subscribe' => false
];

$iterator = new StepsIterator();
$iterator->setStructure($tree);
$treeEditor = new TreeEditor($iterator);

$treeEditor->getIterator()->moveDown('phones');
// Will add new phone number
$treeEditor->addValue('2', '999999999');

// Will add new address
$treeEditor->addValueTo('/addresses', '1', [
	'city' => 'Dallas',
	'street' => 'Main street',
	'number' => 456
]);

在树中创建路径

<?php

require_once '/../vendor/autoload.php';

use TreeManipulator\StepsIterator;
use TreeManipulator\TreeEditor;

// Create tree data structure as array
$tree = [
	'user_id' => 1,
	'firstname' => 'John',
	'lastname' => 'Smith',
	'dateOfBirth' => '1990-01-01',
	'addresses' => [
		[
			'city' => 'New York',
			'street' => 'Broadway',
			'number' => 123
		]
	],
	'phones' => [
		'123456789',
		'987654321'
	],
	'email' => 'john.smith@mail.com',
	'subscribe' => false
];

$iterator = new StepsIterator();
$iterator->setStructure($tree);
$treeEditor = new TreeEditor($iterator);

// Will create new path /foo/bar in tree
$treeEditor->createPath('foo/bar');

复制树片段

<?php

require_once '/../vendor/autoload.php';

use TreeManipulator\StepsIterator;
use TreeManipulator\TreeEditor;

// Create tree data structure as array
$tree = [
	'user_id' => 1,
	'firstname' => 'John',
	'lastname' => 'Smith',
	'dateOfBirth' => '1990-01-01',
	'addresses' => [
		[
			'city' => 'New York',
			'street' => 'Broadway',
			'number' => 123
		]
	],
	'phones' => [
		'123456789',
		'987654321'
	],
	'email' => 'john.smith@mail.com',
	'subscribe' => false
];

$iterator = new StepsIterator();
$iterator->setStructure($tree);
$treeEditor = new TreeEditor($iterator);

// Will copy first address as addresses list second element
$treeEditor->copyValue('/addresses/0', 'addresses/1');