goutte / tree-bundle
Goutte 的树库
Requires
- php: >=5.3.3
Requires (Dev)
- symfony/config: >=2.1,<2.3-dev
- symfony/dependency-injection: >=2.1,<2.3-dev
- symfony/http-kernel: >=2.1,<2.3-dev
- symfony/yaml: >=2.1,<2.3-dev
This package is not auto-updated.
Last update: 2024-09-28 13:45:58 UTC
README
当前树结构仅设计了一个模型,即 Node。
提供序列化和反序列化节点服务的功能,从字符串如 A(B,C(D))
到节点,以及从节点到字符串。
提供的驱动器
-
括号 :
A(B,C(D))
-
简单的(愚蠢的!)timbre :
T("*",T(6),T("sin",T(55.2)))
-
Ascii
A +--B | +--C | +--D | +--E +--Fork
查看 测试 了解驱动器支持的更多示例。
使用方法
此库不用于在数据库中存储嵌套集合,如果您正在寻找这个,您应该查看 Doctrine 扩展。此包的原始目的是提供一套用于阅读/编写功能代码的工具,例如配置菜单的层次结构的纯文本。
请随意扩展以满足您的需求。
安装
使用 composer 将此包添加到您的项目中
composer require goutte/tree-bundle
服务
从容器中使用服务
// get the serializer service $serializer = $container->get('goutte_tree.serializer'); // this will create the nodes and return the root node $rootNode = $serializer->toNode('root(childA,childB(grandchildC))'); // this will return the string for the subtree below the passed node $string = $serializer->toString($rootNode); // returns 'root(childA,childB(grandchildC))' // ... or use another driver $string = $serializer->useDriver('ascii')->toString($rootNode); // will return: // root // +--childA // +--childB // +--grandchildC
查看 Goutte\TreeBundle\Is\Node
以获取抽象类 Goutte\TreeBundle\Model\AbstractNode
提供的方法列表。
使用自己的 Node
扩展
use Goutte\TreeBundle\Model\Node as AbstractNode; class MyNode extends AbstractNode { // ... }
实现
use Goutte\TreeBundle\Is\Node as NodeInterface; class MyNode implements NodeInterface { // ... }
然后,配置服务以使用您的自己的 Node 类。
编写一个驱动器
如下实现 Goutte\TreeBundle\Is\Driver
use Goutte\TreeBundle\Is\Driver; use Goutte\TreeBundle\Factory\NodeFactoryInterface; class MyDriver implements Driver { protected $factory public function __construct(NodeFactoryInterface $factory) { $this->factory = $factory; } // ... implement Driver }
__construct
部分是可选的,但您可能需要一个 NodeFactory 来创建节点。我们提供了一个默认的 Node Factory 作为服务,请参阅下面服务的定义中的 <argument>
。
将您的驱动器添加到您的 services.xml
中,并标记为 goutte_tree.driver
<service id="goutte_tree.driver.mydriver" class="MyVendor\MyBundle\Driver\MyDriver" public="false"> <argument type="service" id="goutte_tree.node.factory" /> <tag name="goutte_tree.driver" /> </service>
(警告) 服务 ID 将定义驱动别名,因此它需要以 goutte_tree.driver.
开头。这不是官方的做法(这将有一个在标签中的别名属性),但这会使代码更简洁。这可能以后会改变,我还在做决定。
使用 ->useDriver()
配置服务以使用您的自定义驱动器
// Get the service, tell it to use your driver $serializer = $container->get('goutte_tree.serializer')->useDriver('mydriver');
您可以通过在 services.xml
中将服务告诉使用您的驱动器作为默认值来省略对 ->useDriver()
的使用
<tag name="goutte_tree.driver" default="true" />
测试
此包被无情地测试了,除了某些服务配置异常(如果您知道如何测试这些,我很乐意听!)
使用 --dev
选项运行 composer,以便创建自动加载器并自动加载所需的 sf2 DIC 类。 奇怪的是,当我尝试使用 --test
和 require-test
在 composer.json
中安装时,我被赶了出来。(字面意思)
composer install --dev
然后,只需运行
phpunit
陷阱
括号驱动器
带有空标签的节点可以转换为字符串,但不能反向转换回节点。
例如:A(B,C)
树,如果节点标签被清空,将转换回 (,)
预期的解决方案
- 如果标签为空则在 toString 转换时抛出异常 -> 功能丢失
- 微调 toNode 正则表达式以允许空标签 -> 如
A()
将创建两个节点,这会令人不安
Timbre 驱动器
节点的标签没有被驱动程序转义,所以没有 (
、)
或 ,
。因为这些字符在 Timbre 的节点中没有被使用,所以这不应该是一个问题。
数字标签必须用 T()
括起来,例如:T(66.2)
。
Ascii 驱动程序
换行符将被(未)转义,以便标签在字符串表示中保持在同一行。
因为读者期望 正好 2 个 -
作为缩进,所以如果你添加更多,节点标签将保留额外的 -
。
例如
A
+---B
=> 子节点标签将是 -B
,而不是 B
。
变更日志
v1.0
- TreeIntegrityException
- DriverException
- 节点基础方法
- 路径查找
- 树完整性测试
- 驱动程序的 DIC
- 文档
v1.5
- 括号驱动程序
- Timbre 驱动程序
- 用于多行 ASCII 根树的多行 ASCII 驱动程序
- 使用 ->replaceBy() 替换节点
v1.6
- 节点克隆
v1.7.1
- ->getDescendants()(默认为广度优先 TWA)
- ->getRandomDescendant($includeSelf=false)
v1.7.4
- 解耦 Random 工具,以便更容易/更深入地进行确定性测试
- ->removeChildren()
v1.7.5
- 在驱动程序中使用工厂
路线图
这些没有时间表,不要等待它们。
v1.8
- ->getAncestors()
- ->getRandomAncestor($includeSelf=false)
v2.0
- 括号驱动程序中的空标签
- 图论,请参阅 BLACKBOARD
- -> 可能会在另一个包中
- 用于树展平的自定义树遍历
- 广度优先
- 深度优先