使用nikic/php解析器,我试图读取一个现有的配置文件,在其中找到一个数组节点,向该节点添加一个新项,然后将所有内容写回该文件
理想情况下,这不应该修改文件的其余部分,包括注释和空白。
我正在使用文档中概述的保留漂亮打印的格式化方法。
节点访问者大致如下所示(为清晰起见,已截断(:
$traverser = new NodeTraverser();
$traverser->addVisitor(new class extends Visitor {
public function leaveNode(Node $node): ?Node
{
if ($this->isParentNodeIAmLookingFor($node)) {
// Check whether the new item exists
if ($this->nodeAlreadyHasChild($node, $node->value->items)) {
throw new RuntimeException('Item exists');
}
// The structure I'd like to add
$newChild = new ExprArray_();
$newChild->setAttribute( 'kind', ExprArray_::KIND_SHORT);
// Adding a new item with my desired key into the target array here
$node->value->items[] = new ExprArrayItem(
$newChild,
new ScalarString_('<<NEWLY_INSERTED_ITEM>>')
);
return $node;
}
return null;
}
});
原始配置文件大致如下:
<?php
return [
'important stuff' => [
'with multiple lines',
/* ... */
],
// A comment I'd like to keep
'items' => [
'an existing item' => [ /* with stuff */ ],
# <------ this is where I'd like to add my new item
],
];
PHP Parser打印出的内容:
<?php
return [
'important stuff' => ['with multiple lines', /* ... */ ],
// A comment I'd like to keep
'items' => ['an existing item' => [ /* with stuff */ ], '<<NEWLY_INSERTED_ITEM>>' => []],
];
因此,看起来保留格式的漂亮打印确实删除了文件中所有项目之间的空行,即使我没有触摸它们,而且还将我现有的数组从多行转换为单行
我知道保留格式的选项仍然是实验性的和不完整的,但从我在文档中读到的内容来看,问题和代码多行数组实际上应该已经在工作了,因此我希望其他项目至少保持不变。
有没有一种方法可以强制数组结构的多行输出?我错过了什么?我对AST操作还不太深入。
您可以通过节点属性中的Comment类添加空白。(您可以在注释文本中指定空白,而不是注释字符。(例如,这里插入一个新的备用节点
return new NodeStmtProperty(
8,
[new NodeStmtPropertyProperty(
new NodeVarLikeIdentifier($ident),
static::valueNode($value)
)],
['comments'=>[new Comment("n")]]
);