allegiance-group/nested-set

PHP 库,使用嵌套集模型技术来操作和检索数据库记录,以表示树形数据结构

2.3.4 2022-07-13 15:24 UTC

README

简介

这是 metalspired 在 https://github.com/metalinspired/NestedSet 上找到的存储库的分支。创建此分支是为了应用以下补丁:(通过自定义数据查找嵌套集节点 ID)[https://github.com/Beaconfire/NestedSet/commit/f52319a30c295fb1bc373a260aeaf50a59c21235.patch] (防止 Drupal 管理员中的警告)[https://github.com/Beaconfire/NestedSet/commit/75367158584e16c0e5612159f16703c64c8fa2ae.patch]

此库允许您使用嵌套集模型技术来操作和检索数据库记录,以表示树形数据结构。它使用 Laminas\Db 作为底层数据库抽象层。

需求

  • PHP >= 5.6
  • Laminas\Db >= 2.8

安装

$ composer require metalinspired/nested-set

使用

(混合) 嵌套集

嵌套集只需要表中的 leftright 列来表示树形结构。混合嵌套集需要额外的 parentorderingdepth 列。这种添加使得操作更复杂,但极大地简化了节点的检索。例如,为了找到节点的兄弟节点,我们只需查询具有相同父节点的节点,而不是使用 join 来找到父节点并使用 join 来获取父节点的直接子节点。Ordering 列用于表示节点的自然顺序。

配置对象

Config 类,正如其名所示,用于创建具有预定义配置的对象,用于在此实用程序中操作/选择类,您可以通过更改其公共成员的值来实现这一点。它还具有三个静态方法,用于创建 Config 对象实例并将其 $adapter 成员设置为 Laminas\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;

操作

HybridManipulateManipulate 类包含用于在嵌套集模型中创建(插入)、移动和删除节点的方法。它还具有 createRootNode 方法,用于创建一个根节点,作为其他所有节点的容器。

示例

// 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 的额外方法。它允许您通过使用顺序列值作为目的地而不是节点标识符来在父节点内移动节点。

检索记录

HybridFindFind 类包含用于检索记录的方法,它们的名字基本上说明了它们的功能。您只需要提供节点标识符($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。与find方法不同,这些方法不将标识符作为参数,而是定义一个:id占位符。使用示例,只需查看find*方法之一。

重要提示:$columns$where参数不同,当使用$order参数时,必须匹配列名与表名tt是查询的表的别名),例如

$where = new Where();
$where->equalTo('column3', 'some_value');

$find->findChildren(3, ['alias' => 'column1', 'column2'], 't.column4 ASC', $where);

工厂

工厂将NestedSetHybridNestedSet的查找和操作类封装在一个类中。

// 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();
...