PHP 5.3/6.0の名前空間とは

ぶっちゃけ本当の意味での名前空間ではありません。ちょうどPHPの無名関数が実はナル文字で始まる名前付きの関数であるように、ある名前空間において定義されたクラスや関数は、普通にスクリプトに記述するとパーズエラーとなる名前で共通のシンボルテーブルに登録されます。
イメージとしては以下のコードが

<?php
namespace Foo::Bar;

class Baz
{
    /* snip. */
}

function hoge()
{
    /* snip. */
}
?>

コンパイル時に以下のように変換されると思ってください。(実際の処理とは異なるし、呼び出し時はimportが絡むのですこし複雑になります)

<?php
class Foo::Bar::Baz
{
    /* snip. */
}

function Foo::Bar::hoge()
{
    /* snip. */
}
?>

もちろん直に class Foo::Bar::Baz {...} と書こうものなら "parse error, unexpected T_PAAMAYIM_NEKUDOTAYIM" (予期しない"::") です。


5.0で導入される予定だったけど、パフォーマンスの問題で見送られた名前空間サポートはおそらくシンボルテーブルが名前空間ごとに独立していたのでしょう。そのほうがより厳密な意味での「名前空間」ではありますが、一つのハッシュテーブルから探すのと、不特定多数のハッシュテーブルから検索対象のハッシュテーブルを特定し、そこから探すのではどちらが速いかは言うまでもありませんね。(注: 実際の実装がどうなっていたかを知らずに憶測で書いています)


冒頭で「本当の意味での名前空間ではありません」と書きましたが、こういうアプローチはPHPらしくて好きです。