metalinspired / nested-set
PHP 库,用于使用嵌套集合模型技术操作和检索使用数据库记录来表示树形数据结构
Requires
- php: ^5.6 || ^7.0
- zendframework/zend-db: ^2.8
Requires (Dev)
- phpunit/dbunit: ^3.0
- phpunit/phpunit: ^6.1
- squizlabs/php_codesniffer: ^3.0
README
简介
此库允许您使用嵌套集合模型技术来表示树形数据结构,通过操作和检索数据库记录。它使用 Zend\Db 作为底层数据库抽象层。
要求
- PHP >= 5.6
- Zend\Db >= 2.8
安装
$ composer require metalinspired/nested-set
使用
(混合) 嵌套集合
嵌套集合只需在表中包含 left
和 right
列来表示树结构。混合嵌套集合需要额外的 parent
、ordering
和 depth
列。这种添加使操作更复杂,但极大地简化了节点的检索。例如,为了找到节点的兄弟节点,我们只需查询具有相同父节点的节点,而不是使用 join
来找到父节点并使用 join
来获取父节点的直接后代。Ordering
列用于表示节点的自然顺序。
配置对象
Config 类,正如其名称所示,用于创建具有预定义配置的配置对象,以便在此实用程序中对操作/选择类进行操作,您可以通过更改其公共成员的值来完成此操作。它还具有三个静态方法,用于创建 Config 对象的实例并将其 $adapter 成员设置为 Zend\DB\Adapter\Driver 实例。
示例
// Create Config object with DSN data $config = Config::createWithDsn('mysql:dbname=some_database;host=localhost', 'some_user', 'some_password'); // Set table name $config->table = 'some_table'; // If we don't want to retrieve all columns when using find methods // we specify which columns we want to fetch $config->columns = ['column1', 'column5', 'alias_of_column' => 'column7']; // You can also instruct methods from Find class to include searching node in results // For example, if you want to get children of node with id 5 including the node with id 5 $config->includeSearchingNode = true;
操作
HybridManipulate 和 Manipulate 类包含在嵌套集合模型中创建(插入)、移动和删除节点的方法。它还具有创建根节点的方法,该根节点作为所有其他节点的容器。
示例
// Create an instance of Manipulate class $manipulate = new Manipulate($config); // Create a root node on an empty table $rootId = $manipulate->createRootNode(); // Create a node $node1 = $manipulate->insert($rootId, ['column1' => 'some data', 'column2' => 'some more data']); // Create another node that is child/leaf of first node $node2 = $manipulate->insert($node, ['column1' => 'child data', 'column2' => 'some more child data']); // Move node2 so it is on same level as node1 $manipulate->moveAfter($node2, $node1); // Or we could have moved it in front of node1 $manipulate->moveBefore($node2, $node1); // Move node2 back to its original position (as child of node1) $manipulate->moveMakeChild($node2, $root1); // Delete a node (and all its children, if any) $manipulate->delete($node); // You can also empty a node by delete all of its descendants // or enter a node identifier as second parameter to move descendants to a new location $manipulate->clean($parentNode, $destinationNode);
除了 insert
之外的操作方法也可以接受数组形式的节点标识符作为其第一个参数,这意味着您可以通过一个调用来移动、删除和清理多个节点。
示例
$manipulate->moveBefore([5,6,26,88], 33);
HybridManipulate 类有一个额外的名为 reorder
的方法。它允许您使用顺序列值作为目的地而不是节点标识符来在父节点内移动节点。
检索记录
HybridFind 和 Find 类包含用于检索记录的方法,它们的名字基本上说明了它们的功能。您只需要提供节点标识符($id 参数),其他所有参数都是可选的。有关参数列表,请参阅每个函数的源代码;
// Create instance of Find class $find = new Find($config); $find->findAncestors(); $find->findParent(); $find->findDescendants(); $find->findChildren(); $find->findFirstChild(); $find->findLastChild(); $find->findSiblings(); $find->findNextSibling(); $find->findPreviousSibling();
这些方法中的每一个都有一个(几乎)相同的 get*Query 方法(例如 getFindAncestorsQuery
),它返回一个 Select 对象而不是 ResultInterface。与查找方法不同,这些方法不取标识符作为参数,而是定义一个 :id 占位符。对于用法示例,只需查看 find* 方法之一。
重要提示:与 $columns 或 $where 参数不同,当使用 $order 参数时,您必须将列名与查询表的代码 t
(t
是查询的表的别名)匹配,例如
$where = new Where(); $where->equalTo('column3', 'some_value'); $find->findChildren(3, ['alias' => 'column1', 'column2'], 't.column4 ASC', $where);
工厂
工厂类封装了对NestedSet
和HybridNestedSet
类进行查找和操作的功能。
// Get factory from config object $factory = $config->getFactory(); // Manually create factory $factory = new Factory($config); // Usage examples $factory->find->findChild(); $factory->manipulate->moveAfter(); $factory->hybridFind->findAncestors(); $factory->hybridManipulate->moveBefore(); ...