Toolking for smart daily work with AST




Installs: 1 418 398

Dependents: 18

Suggesters: 0

Security: 0

Stars: 23

Watchers: 2

Forks: 0


10.0.0-beta16 2021-12-02 10:51 UTC


Downloads total


composer require symplify/astral

Add to Symfony Project

Register package in config/config.php:

use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symplify\Astral\ValueObject\AstralConfig::FILE_PATH;

return static function (ContainerConfigurator $containerConfigurator): void {

Add to PHPStan Rules

Include in your phpstan.neon:

    - vendor/symplify/astral/config/services.neon


1. Resolve Name of Any Node

How can you get the name of a specific node?

// "someObject"
// "someMethodCall"

Require SimpleNameResolver in any service:

use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use Symplify\Astral\Naming\SimpleNameResolver;

final class SomeRule
    public function __construct(
        // PHP 8.0 promoted property syntax
        private SimpleNameResolver $simpleNameResolver
    ) {

    public function process(Node $node)
        if ($node instanceof MethodCall) {
            $callerName = $this->simpleNameResolver->getName($node->var);
            $methodName = $this->simpleNameResolver->getName($node->name);

For dynamic names that are not possible to resolve, the null will be returned:


2. Resolve Value of Node

$value = 1000;

How can we get the 1000 value?

use PhpParser\Node;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Scalar\LNumber;
use PHPStan\Analyser\Scope;
use Symplify\Astral\NodeValue\NodeValueResolver;

final class SomeRule
    public function __construct(
        // PHP 8.0 promoted property syntax
        private NodeValueResolver $nodeValueResolver
    ) {

    public function process(Node $node, Scope $scope)
        if ($node instanceof Assign && $node->expr instanceof LNumber) {
            $resolvedValue = $this->nodeValueResolver->resolve($node->expr, $scope->getFile());

Work for static expressions like these:

$value = 'Hey';
// "Hey"

// "SomeClass"

class SomeClass
    public const VALUE = 'different';

// "different"

// realpath of the __DIR__ in its place

3. Unique *Builder Classes

Native PhpParser node class and builder class share the same short class name.

use PhpParser\Builder\Class_;
use PhpParser\Node\Stmt\Class_;

$class = new Class_('ClassName');
$class = $class->getNode();

This confuses IDE and lead to wrong classes being used as type hints. To avoid that, this package provides *Builder names:

use Symplify\Astral\ValueObject\NodeBuilder\ClassBuilder;

$classBuilder = new ClassBuilder('some_class');
$class = $classBuilder->getNode();

4. Traverse Nodes with Simple Callback

Working with nodes is based on traversing each one of them. You can use native NodeVisitor and NodeTraverses. But that requires to create at least 2 objects, to connect them and call them.

What if we need just a small traverse right in this method? Service SimpleCallableNodeTraverser to the rescue:

use PhpParser\Node;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\ClassMethod;
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;

/** @var ClassMethod $classMethod */
$classMethod = '...';

$simpleCallableNodeTraverser = new SimpleCallableNodeTraverser();
$simpleCallableNodeTraverser->traverseNodesWithCallable($classMethod, function (Node $node) {
    if (! $node instanceof String_) {
        return null;

    $node->value = 'changed name';
    return $node;

Report Issues

In case you are experiencing a bug or want to request a new feature head over to the Symplify monorepo issue tracker


The sources of this package are contained in the Symplify monorepo. We welcome contributions for this package on symplify/symplify.