codrasil / closurable
PHP Laravel 中任何层次数据的闭包关系数据库实现
Requires (Dev)
- orchestra/testbench: ^6.0@dev
- phpunit/phpunit: ^8.3@dev
This package is auto-updated.
Last update: 2024-09-07 19:26:55 UTC
README
PHP 中任何层次数据的闭包关系数据库实现。要求
PHP
:^7.x
MySQL
: 任何版本均可。
安装
此包最初是为 Laravel 构建的,但也可用于任何 PHP 项目。
通过 composer
composer require codrasil/closurable
发布配置
将包的服务提供者传递给 artisan 命令
php artisan vendor:publish --provider="Codrasil\Closurable\NestableServiceProvider"
设置
生成迁移文件
首先,运行控制台命令以生成嵌套迁移表。
格式
make:closurable [options] [--] <reference>
示例
我们将使用 users
模型来生成用户的嵌套关系。
php artisan make:closurable users
命令接受一个参数,即 引用表
。这将是要“闭包”的表。
它将生成一个名为 userstree
的表,该表预先填充了必要的列。
生成的文件应如下所示
Schema::create('userstree', function (Blueprint $table) { $table->unsignedBigInteger('ancestor_id')->index(); $table->unsignedBigInteger('descendant_id')->index(); $table->unsignedBigInteger('depth')->index()->default(0); $table->unsignedBigInteger('root')->index()->default(0); $table->unique(['ancestor_id', 'descendant_id']); $table->index(['ancestor_id', 'descendant_id', 'depth']); $table->index(['descendant_id', 'depth']); $table->index(['depth', 'root']); $table->foreign('ancestor_id') ->references('id') ->on('users') ->onDelete('cascade') ->onUpdate('cascade'); $table->foreign('descendant_id') ->references('id') ->on('users') ->onDelete('cascade') ->onUpdate('cascade'); });
注意 在运行命令之前,您应该自己生成 引用表 的迁移文件(在上面的示例中,您应该自己生成 users
表的迁移文件)。
注意 要更改闭包表的表名,请传递选项 --table
或 --create
php artisan make:closurable users --table=familytree
运行 php artisan make:closurable --help
获取有关配置命令的更多信息。
模型使用
接下来,在要嵌套闭包的模型上使用两种选项之一。
根据我们上面的示例,User
模型应实现以下之一:
-
特质,
Closurable
use Codrasil\Closurable\Closurable; class User extends Authenticatable { use Closurable; }
或
-
通过扩展抽象类
Codrasil\Closurable\Model
,而不是默认的 Illuminate Model 类use Codrasil\Closurable\Model; class User extends Model { // Of course, you will need to reimplement the Authenticatable traits // to the User model if you ARE going to nest the User model. }
用法
保存分支节点
假设我们在 users
表上具有以下数据
我们需要以下关系
要保存上述描述的关系,我们需要使用 User 模型中的 closurables() 来访问 attach(Model $model) 方法。
$parent = User::find(1); // Jones, Sr. $junior = User::find(2); // Indy $parent->closurables()->attach($junior); ... $child = User::find(3); // Susie $parent->closurables()->attach($child); ... $child = User::find(4); // Jones III $junior->closurables()->attach($child);
该关系将保存到 familytree
表中,如下所示
可视化表示
显示根节点
-
根
要显示没有父级的资源,请使用
roots
范围$roots = MyModel::roots()->get();
查询相邻关系
默认情况下,排序通过在 参考表 中找到的 sort
列来处理。如果 sort
列不可用,则默认为 id
或 $this->getKeyName()
将返回的内容。
-
兄弟姐妹
要检索子级的所有兄弟姐妹,请使用
siblings()
方法$child = MyModel::find(2); $siblings = $child->siblings(); // or $child->siblings
- 一个用于检查空值的辅助方法
->hasSiblings()
可用。 - 一个访问器方法
getSiblingsAttribute
可用。
- 一个用于检查空值的辅助方法
-
下一个兄弟姐妹
要在
$user->children
中显示下一个兄弟姐妹,请使用next()
方法$firstChild = MyModel::find(2); $secondChild = $firstChild->next(); // or $firstChild->next
- 一个用于检查空值的辅助方法
->hasNext()
可用。 - 一个访问器方法
getNextAttribute
可用。
- 一个用于检查空值的辅助方法
-
上一个兄弟姐妹
要显示上一个兄弟姐妹,请使用
previous()
方法$secondChild = MyModel::find(3); $firstChild = $secondChild->previous(); // or $secondChild->previous
- 一个用于检查空值的辅助方法
->hasPrevious()
可用。 - 一个访问器方法
getPreviousAttribute
可用。
- 一个用于检查空值的辅助方法
查询线性关系
-
父级
要检索子级的直接父级,请使用
parent()
方法$child = MyModel::find(2); $parent = $child->parent(); // or $child->parent
- 一个用于检查空值的辅助方法
->hasParent()
可用。 - 提供了一个访问器方法
getParentAttribute
。
- 一个用于检查空值的辅助方法
-
子节点
要显示特定资源的子节点,请使用
children()
方法$user = User::find(1);
{{-- in a blade file --}} @foreach ($user->children() as $child) {{ $child->name }} @endforeach {{-- use @dd($user->children) to see entire collection --}}
- 提供了一个用于检查空性的辅助方法
->hasChildren()
。 - 提供了一个访问器方法
getChildrenAttribute
。
- 提供了一个用于检查空性的辅助方法
-
祖先
要获取子节点的所有父节点(以及子节点的父节点的父节点等),请使用
ancestors()
方法$child = MyModel::find(4); $ancestors = $child->ancestors(); // will output the parent([of the parent]*n) + the child. // dd($ancestors) to inspect actual data.
- 提供了一个用于检查空性的辅助方法
->hasAncestors()
。 - 提供了一个访问器方法
getAncestorsAttribute
。
- 提供了一个用于检查空性的辅助方法
-
后代
要获取父节点的所有子节点(以及父节点子节点的子节点等),请使用
descendants()
方法$parent = MyModel::find(2); $descendants = $parent->descendants(); // will output the children([of the children]*n) + the parent. // dd($descendants) to inspect actual data.
- 提供了一个用于检查空性的辅助方法
->hasDescendants()
。 - 提供了一个访问器方法
getDescendantsAttribute
。
- 提供了一个用于检查空性的辅助方法
有关 adjacent
和 lineal
关系的更多使用案例,请查看文档中的 “关系” 部分。
文档 & 示例
要了解更多关于 API 的信息,请访问 docs 文件夹。
更多示例实现,请查看 docs/examples 文件夹。示例页面包含各种用例,例如 评论系统、动物王国的分类排名、家谱 等。
许可证
此库是开源软件,采用 MIT 许可协议。