PHP7から予約語がメソッド名として使えるようになっていた件
PHPで"echo"とか"list"という名前のメソッドを作って文法エラーになった経験はないでしょうか?
ほとんど知られていないのですが、実はPHP7からは"echo",“list"などの予約語がメソッド名として使えるんです。
<?php
class Foo
{
public function list()
{
echo "list\n";
}
public function echo()
{
echo "echo\n";
}
public static function die()
{
echo "die\n";
}
}
$foo = new Foo();
$foo->list();
$foo->echo();
Foo::die();
PHP 5だと文法エラーになっていた
$ php a.php
PHP Parse error: syntax error, unexpected 'list' (T_LIST), expecting identifier (T_STRING) in a.php on line 5
PHP 7だとちゃんと動く
$ php a.php
list
echo
die
MyClass::new()とかできる
面白いことに、newという名前のクラスメソッドを作れたりします。
public static function new()
{
//中身は自由に定義できる
}
おかげでPerlと同じ言語仕様になりましたね!
なぜ使えるのか?
公式マニュアルを見ると、listやechoなどは関数名として使えないと明記されています。
http://php.net/manual/ja/reserved.keywords.php
以下のキーワードはいずれも定数、クラス名、 関数名として使用することはできません。
つまり仕様では使えないはずのものが使えている状態です。
RFCが可決されていた
実はこの新仕様はRFCが提出されており、ステータスが「PHP7.0で実装済み」となっています。
https://wiki.php.net/rfc/context_sensitive_lexer
Pull Reqeustの方を見るとマージ済みになっていてラベルが"PHP7.1"となっています。 https://github.com/php/php-src/pull/1221/
つまりPHP7.1で公式の言語仕様として採用されるものと思われます。
[追記] 公式マニュアルの隅っこにちゃんと書いてあった
実は付録のページにちゃんと書いてありました。 PHP7.0の新機能のようです。
(はてブコメントでt-cyrillさんに教えていただきました。ありがとうございました。)
予約語の制約の緩和
http://php.net/manual/ja/migration70.other-changes.php
クラスやインターフェイスそしてトレイトの内部で、 プロパティや定数そしてメソッドの名前にグローバルな予約語を使えるようになりました。 これで、今後新たなキーワードが導入された場合でも下位互換性を維持しやすくなります。 そして、API の命名の制約も軽減できるでしょう。 これは、流れるようなインターフェイスを用いた内部 DSL を作る際などに便利です。
<?php
// 'new', 'private', 'for' は、これまでなら使うことができませんでした
Project::new('Project Name')->private()->for('purpose here')->with('username here');
?>
唯一の例外は class キーワードで、このキーワードを定数名として使うことはできません。 これを許してしまうと、クラス名の解決に使う構文 (ClassName::class) と衝突してしまうからです。
個人的にこの仕様変更はとてもうれしいので大歓迎です。
PHP ++