さわって慣れるPHP Parser - IdentifierとNameとFullyQualified
さわって慣れるPHP Parserの続編です。
簡単なコードを解析してみることでPHP Parserに慣れ、ノードの理解を深めることを目指しています。今回はIdentifier
, Name
, FullyQualified
という3つのノードの注目します。
さっそくPHP Parserをインストールします。
$ composer require --dev nikic/php-parser
解析対象のコード(Thoth.php
)をしたためます。(PHPとしての適切さは度外視し、ノードを観察するためだけのコードです。)
<?php
Boingo::foresee();
\Boingo::foresee();
Oingo\Boingo::foresee();
\Oingo\Boingo::foresee();
解析します。
$ vendor/bin/php-parse Thoth.php
====> File Thoth.php:
==> Node dump:
array(
0: Stmt_Expression(
expr: Expr_StaticCall(
class: Name(
parts: array(
0: Boingo
)
)
name: Identifier(
name: foresee
)
args: array(
)
)
)
1: Stmt_Expression(
expr: Expr_StaticCall(
class: Name_FullyQualified(
parts: array(
0: Boingo
)
)
name: Identifier(
name: foresee
)
args: array(
)
)
)
2: Stmt_Expression(
expr: Expr_StaticCall(
class: Name(
parts: array(
0: Oingo
1: Boingo
)
)
name: Identifier(
name: foresee
)
args: array(
)
)
)
3: Stmt_Expression(
expr: Expr_StaticCall(
class: Name_FullyQualified(
parts: array(
0: Oingo
1: Boingo
)
)
name: Identifier(
name: foresee
)
args: array(
)
)
)
)
色々でてますがサラリと流して、Expr_StaticCall
に注目します。
--var-dump
モードで実行するとStaticCall
クラスだと分かります。
StaticCall
クラスのgetSubNodeNames()
を確認します。
public function getSubNodeNames() : array {
return ['class', 'name', 'args'];
}
プロパティも確認します。
class StaticCall extends CallLike
{
/** @var Node\Name|Expr Class name */
public $class;
/** @var Identifier|Expr Method name */
public $name;
/** @var array<Arg|VariadicPlaceholder> Arguments */
public $args;
Boingo::foresee();
においてBoingo
が$class
、foresee
が$name
、もしあればforesee()
の引数が$args
で、Boingo
の型はName
かExpr
、foresee
の型はIdentifier
かExpr
だとわかります。Expr
になりえるのは例えば変数のケースがあるからです。
変数のケースというのは、一例をあげると、以下のようにclass
の部分が変数になっているケースです。
<?php
$boingo::foresee();
$ vendor/bin/php-parse ThothVariable.php
====> File ThothVariable.php:
==> Node dump:
array(
0: Stmt_Expression(
expr: Expr_StaticCall(
class: Expr_Variable(
name: boingo
)
name: Identifier(
name: foresee
)
args: array(
)
)
)
)
Expr_StaticCall
のclass
がExpr_Variable
になりました。
Expr
は式を表すノードで、Variable
は変数を表すノードです。そして変数は式です。
さてName
とIdentifier
に注目します。Identifier
の定義を見てみます。
Represents a non-namespaced name. Namespaced names are represented using Name nodes.
とあります。
メソッド名は名前空間付きで表記されるものではない一方でクラス名は名前空間付きで表記されますし、観察結果とも整合的です。
さて、冒頭の解析結果にはExpr_StaticCall
が4つありました。これらの相違点にも注目してみます。
class: Name(
parts: array(
0: Boingo
)
)
class: Name_FullyQualified(
parts: array(
0: Boingo
)
)
class: Name(
parts: array(
0: Oingo
1: Boingo
)
)
class: Name_FullyQualified(
parts: array(
0: Oingo
1: Boingo
)
)
先頭に\
をつけるとFullyQualified
、つけないとName
になるようです。また、名前空間は配列で表現されるようです。
Fully Qualifiedは日本語でいうと完全修飾名で、PHPマニュアルも参考になります。
FullyQualified
の定義を見てみます。
FullyQualified
はName
を拡張したものということも分かりました。
Discussion