4 Since the introduction of namespaces in PHP 5.3, literal names in PHP code are subject to a
5 relatively complex name resolution process, which is based on the current namespace, the current
6 import table state, as well the type of the referenced symbol. PHP-Parser implements name
7 resolution and related functionality, both as reusable logic (NameContext), as well as a node
8 visitor (NameResolver) based on it.
10 The NameResolver visitor
11 ------------------------
13 The `NameResolver` visitor can (and for nearly all uses of the AST, is) be applied to resolve names
14 to their fully-qualified form, to the degree that this is possible.
17 $nameResolver = new PhpParser\NodeVisitor\NameResolver;
18 $nodeTraverser = new PhpParser\NodeTraverser;
19 $nodeTraverser->addVisitor($nameResolver);
22 $stmts = $nodeTraverser->traverse($stmts);
25 In the default configuration, the name resolver will perform three actions:
27 * Declarations of functions, classes, interfaces, traits and global constants will have a
28 `namespacedName` property added, which contains the function/class/etc name including the
29 namespace prefix. For historic reasons this is a **property** rather than an attribute.
30 * Names will be replaced by fully qualified resolved names, which are instances of
31 `Node\Name\FullyQualified`.
32 * Unqualified function and constant names inside a namespace cannot be statically resolved. Inside
33 a namespace `Foo`, a call to `strlen()` may either refer to the namespaced `\Foo\strlen()`, or
34 the global `\strlen()`. Because PHP-Parser does not have the necessary context to decide this,
35 such names are left unresolved. Additionally a `namespacedName` **attribute** is added to the
38 The name resolver accepts an option array as the second argument, with the following default values:
41 $nameResolver = new PhpParser\NodeVisitor\NameResolver(null, [
42 'preserveOriginalNames' => false,
43 'replaceNodes' => true,
47 If the `preserveOriginalNames` option is enabled, then the resolved (fully qualified) name will have
48 an `originalName` attribute, which contains the unresolved name.
50 If the `replaceNodes` option is disabled, then names will no longer be resolved in-place. Instead a
51 `resolvedName` attribute will be added to each name, which contains the resolved (fully qualified)
52 name. Once again, if an unqualified function or constant name cannot be resolved, then the
53 `resolvedName` attribute will not be present, and instead a `namespacedName` attribute is added.
55 The `replaceNodes` attribute is useful if you wish to perform modifications on the AST, as you
56 probably do not wish the resoluting code to have fully resolved names as a side-effect.
61 The actual name resolution logic is implemented in the `NameContext` class, which has the following
66 public function __construct(ErrorHandler $errorHandler);
67 public function startNamespace(Name $namespace = null);
68 public function addAlias(Name $name, string $aliasName, int $type, array $errorAttrs = []);
70 public function getNamespace();
71 public function getResolvedName(Name $name, int $type);
72 public function getResolvedClassName(Name $name) : Name;
73 public function getPossibleNames(string $name, int $type) : array;
74 public function getShortName(string $name, int $type) : Name;
78 The `$type` parameters accept on of the `Stmt\Use_::TYPE_*` constants, which represent the three
79 basic symbol types in PHP (functions, constants and everything else).
81 Next to name resolution, the `NameContext` also supports the reverse operation of finding a short
82 representation of a name given the current name resolution environment.
84 The name context is intended to be used for name resolution operations outside the AST itself, such
85 as class names inside doc comments. A visitor running in parallel with the name resolver can access
86 the name context using `$nameResolver->getNameContext()`. Alternatively a visitor can use an
87 independent context and explicitly feed `Namespace` and `Use` nodes to it.