stefano / stefano-tree
PHP 的嵌套集(MPTT)实现
5.0.0
2022-09-29 18:55 UTC
Requires
- php: >=7.1.0
Requires (Dev)
- ext-pdo: *
- doctrine/dbal: >=2.0 <4
- friendsofphp/php-cs-fixer: ^3.0.0
- laminas/laminas-db: *
- mockery/mockery: ^1.0.0
- php-coveralls/php-coveralls: ^2.0
- phpunit/phpcov: >=5 <9
- phpunit/phpunit: >=7 <10
- zf1/zend-db: ^1.12
Suggests
- doctrine/dbal: If you want to use Doctrine DBAL
- laminas/laminas-db: If you want to use Laminas Db
- zf1/zend-db: If you want to use Zend1 Db
This package is auto-updated.
Last update: 2024-09-27 22:24:15 UTC
README
PHP 的嵌套集实现。
特性
- NestedSet(MPTT - 修改后的前序树遍历)
- 支持范围(一个数据库表中多个独立的树)
- 重建损坏的树
- 已与 MySQL/MariaDB 和 PostgreSQL 测试,但应适用于支持事务的任何数据库供应商
- 支持 PDO、Zend Framework 1、Laminas Db、Doctrine 2 DBAL 和 Doctrine 3 DBAL。它易于实现对任何框架的支持
- 支持嵌套事务
- PHP 7 和 PHP 8 支持
依赖关系
- 此库没有外部依赖。可以与纯 PHP 一起使用。
安装
在终端中运行以下命令
composer require stefano/stefano-tree
创建树适配器
use \StefanoTree\NestedSet;
$options = array(
'tableName' => 'tree_traversal',
'idColumnName' => 'tree_traversal_id',
// other options
);
$dbAdapter = pure \PDO, Zend1 Db Adapter, Laminas Db Adapter, Doctrine DBAL Connection or any class which implements StefanoTree\NestedSet\Adapter\AdapterInterface interface
$tree = new NestedSet($options, $dbAdapter);
- 您可以连接表。
$options = array(
'tableName' => 'tree_traversal',
'idColumnName' => 'tree_traversal_id',
'dbSelectBuilder' => function() {
// You can use any "callable" like function or object
// Select must be without where or order part
return 'SELECT tree_traversal.*, m.something, ...'
.' FROM tree_traversal'
.' LEFT JOIN metadata AS m ON tree_traversal.id=m.tree_id';
},
// other options
);
$tree = new NestedSet($options, $dbAdapter);
API
创建节点
- 创建根节点
use StefanoTree\Exception\ValidationException;
try {
$data = array(
// values
// id_column_name => uuid
);
// create root node.
$rootNodeId = $tree->createRootNode($data);
// create root node. Second param "$scope" is required only if scope support is enabled.
$rootNodeId = $tree->createRootNode($data, $scope);
} catch (ValidationException $e) {
$errorMessage = $e->getMessage();
}
- 创建新节点。您可以在 4 个不同的位置创建新节点。
use StefanoTree\Exception\ValidationException;
try {
$targetNodeId = 10;
$data = array(
// values
// id_column_name => uuid
);
$nodeId = $tree->addNode($targetNodeId, $data, $tree::PLACEMENT_CHILD_TOP);
$nodeId = $tree->addNode($targetNodeId, $data, $tree::PLACEMENT_CHILD_BOTTOM);
$nodeId = $tree->addNode($targetNodeId, $data, $tree::PLACEMENT_TOP);
$nodeId = $tree->addNode($targetNodeId, $data, $tree::PLACEMENT_BOTTOM);
} catch (ValidationException $e) {
$errorMessage = $e->getMessage();
}
更新节点
use StefanoTree\Exception\ValidationException;
try {
$targetNodeId = 10;
$data = array(
// values
);
$tree->updateNode($targetNodeId, $data);
} catch (ValidationException $e) {
$errorMessage = $e->getMessage();
}
移动节点
- 您可以在 4 个不同的位置移动节点。
use StefanoTree\Exception\ValidationException;
try {
$sourceNodeId = 15;
$targetNodeId = 10;
$tree->moveNode($sourceNodeId, $targetNodeId, $tree::PLACEMENT_CHILD_TOP);
$tree->moveNode($sourceNodeId, $targetNodeId, $tree::PLACEMENT_CHILD_BOTTOM);
$tree->moveNode($sourceNodeId, $targetNodeId, $tree::PLACEMENT_TOP);
$tree->moveNode($sourceNodeId, $targetNodeId, $tree::PLACEMENT_BOTTOM);
} catch (ValidationException $e) {
$errorMessage = $e->getMessage();
}
删除节点或分支
use StefanoTree\Exception\ValidationException;
try {
$nodeId = 15;
$tree->deleteBranch($nodeId);
} catch (ValidationException $e) {
$errorMessage = $e->getMessage();
}
获取节点
- 获取子节点
$nodeId = 15;
// all descendants
$tree->getDescendantsQueryBuilder()
->get($nodeId);
// all descendants result as nested array
$tree->getDescendantsQueryBuilder()
->get($nodeId, true);
// only children
$tree->getDescendantsQueryBuilder()
->excludeFirstNLevel(1)
->levelLimit(1)
->get($nodeId);
// exclude first level($nodeId) from result
$tree->getDescendants()
->excludeFirstNLevel(1)
->get($nodeId);
// exclude first two levels from result
$tree->getDescendantsQueryBuilder()
->excludeFirstNLevel(2)
->get($nodeId);
// return first 4 level
$tree->getDescendantsQueryBuilder()
->levelLimit(4)
->get($nodeId);
// exclude branch from result
$tree->getDescendantsQueryBuilder()
->excludeBranch(22)
->get($nodeId);
- 获取祖先节点
$nodeId = 15;
// get all
$tree->getAncestorsQueryBuilder()
->get($nodeId);
// get all as nested array
$tree->getAncestorsQueryBuilder()
->get($nodeId, true);
// exclude last node($nodeId) from result
$tree->getAncestorsQueryBuilder()
->excludeLastNLevel(1)
->get($nodeId);
// exclude first two levels from result
$tree->getAncestorsQueryBuilder()
->excludeFirstNLevel(2)
->get($nodeId);
验证和重建损坏的树
- 检查树是否有效
use StefanoTree\Exception\ValidationException;
try {
$satus = $tree->isValid($rootNodeId);
} catch (ValidationException $e) {
$errorMessage = $e->getMessage();
}
- 重建损坏的树
use StefanoTree\Exception\ValidationException;
try {
$tree->rebuild($rootNodeId);
} catch (ValidationException $e) {
$errorMessage = $e->getMessage();
}
贡献
欢迎任何贡献。如果您发现任何问题,请毫不犹豫地打开新问题或发送 pull request。