-1

nikic/php-parserを使用して、既存の構成ファイルを読み取り、その中の配列ノードを見つけ、このノードに新しい項目を追加してから、すべてをファイルに書き戻そうとしています。
理想的には、これにより、コメントや空白を含むファイルの残りの部分が変更されるべきではありません。

ドキュメントで概説されている書式設定を保持するきれいな印刷へのアプローチを使用しています。

ノード ビジターは、大まかに次のようになります (わかりやすくするために一部を省略しています)。

$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 Expr\Array_();
            $newChild->setAttribute( 'kind', Expr\Array_::KIND_SHORT);

            // Adding a new item with my desired key into the target array here
            $node->value->items[] = new Expr\ArrayItem(
                $newChild,
                new Scalar\String_('<<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 操作について深くは知りません。

4

1 に答える 1