jared / php-docblock-parser
该包最新版本(dev-main)没有可用的许可证信息。
解析文档块
dev-main
2023-09-14 00:08 UTC
Requires
- php: >=8.1
- jared/php-tokenizer: dev-main
Requires (Dev)
- phpunit/phpunit: ^10.2
This package is auto-updated.
Last update: 2024-09-14 02:07:52 UTC
README
这是一个用于解析文档块的独立库。目前只支持PHPDoc v3。
安装
composer require jared/php-docblock-parser
用法
$raw = '/** * The summary string * having two lines. * The description with a {@link proto://domain.tld The Link} element. * @method int[]|Some\Class myMethod(int[] $param1, SomeType|null $param2) and method description * @param int[] $param1 Param description * @param Some\Class $param2 Param2 description * having two lines * @return mixed[] return description * @see Something\Here */'; $docblock = new Falloff\DocBlock\PHPDoc( $raw ); foreach( $docblock as $index => $element ) print_r($element);
遍历
直接访问
解析的文档块是一个递归结构,由文本块和标签结构组成。后者可能包含自己的文本块,这些文本块可能包含内联标签,可能包含...可以通过以下方式遍历此结构,而无需额外工具
$queue = [$docblock]; while( !empty( $queue ) ){ $element = array_shift($queue); if( is_object($element) and get_class( $element ) == Falloff\DocBlock\PHPDoc\TextBlock::class ){ // Gives 'The cummary string....' print $element->summary[0] . "\n"; // Gives 'The Description...' print $element->text[0] . "\n"; // Refers to Placeholder object, containing the Link tag print get_class($element->text[1]) . "\n"; // The 'proto://domain.tld' string print $element->text[1]->tag->url . "\n"; // The 'The Link' string print $element->text[1]->tag->description[0] . "\n"; } if( is_object($element) and get_class( $element ) == Falloff\DocBlock\PHPDoc\Tag\Method::class ){ // The 'int[]|Some\Class' string print $element->type . "\n"; ; // 'myMethod' print $element->definition->name . "\n"; ; // The params are accessed like the `definition` was an array: // 'int[]' print $element->definition[0]->type . "\n"; // '$param1' print $element->definition[0]->name . "\n"; } // Adding param's tags descriptions to the queue if( is_object($element) and get_class( $element ) == Falloff\DocBlock\PHPDoc\Tag\Param::class ){ // Elements in the description might be objects or regular strings foreach( $element->description as $param_description_chunk ){ $queue[] = $param_description_chunk; } } if( is_scalar($element) ){ // Will produce following two strings: // 'The following is a regular scalar string: `Param description`' // 'The following is a regular scalar string: `Param2 description`'' print 'The following is a regular scalar string: `' . $element . "`\n"; } if( is_object($element) ){ foreach ($element as $child) { $queue[] = $child; } } }
在某些情况下可以使用这种方法,但看起来相当不方便。
通过访问者
该包包含Visitor
接口,可用于简化遍历
$visitor = new class implements Falloff\DocBlock\Visitor{ function in( Falloff\DocBlock\Entity|string|null $entity, array $payload, int|string $idx ) { print 'Index is: ' . $idx . "\n"; print ( is_object( $entity ) ? "Entity is an object of class " . get_class( $entity ) . "\n" : ( is_null( $entity ) ? "Entity is NULL\n" : "Entity is a string containing: " . $entity . "\n" ) ); print "Payload is: \n"; print_r($payload); print "\n"; return true; } function out( Falloff\DocBlock\Entity|string|null $entity, array $payload, int|string $idx){} }; $docblock->visit( $visitor );
访问者必须实现in
和out
方法。在遍历过程中,这些方法会与当前实体本身一起调用,这可能是代表文档块或其组件的实例。$payload
参数是一个数组,包含当前元素的某些内部结构,例如@param
标签的name
和type
。$idx
参数是当前元素在其父结构中的索引。这可能对于像Text
这样的普通容器是整数,而对于像@link
这样的标签是属性的名称,如url
。in
方法的返回值如下
- 纯
false
值表示停止遍历当前元素、其子元素或属性,并移动到树中的下一个元素 - 纯
true
值表示遍历当前元素属性,即@see
标签的ref
和description
- 任何其他值将使遍历跳过元素的属性,并在有子元素的情况下移动到元素的子元素,或在没有其他元素的情况下继续前进
当$payload
包含处理元素所需的所有数据时,遍历而不返回值应该足够。如果不是这样,请确保返回true
以在下一个迭代中访问元素的属性。