togatttiのエンジニアメモ

過度な期待はしないでください.

PHPのnamespace(名前空間)について

PHP5.3から使えるnamespaceだけど、正直意味がよく分かってない(汗)

だから、少し調べてみた。

namespaceとは

名前空間ソースコード上で冗長な命名規則を用いなくても名前の衝突が
起こらないようにし、しかもそれを容易に記述できるようにするためだけの概念
名前空間 - Wikipedia

クラス名とか関数名の名前の衝突を防ぐというのがキーワード

名前の衝突が起きそうなケースとして考えられるのは、どこかのライブラリ、
モジュールを引っ張ってきて、自分でカスタマイズしていくときとかに、既
に予約済みクラス、関数、定数があったときとかに見られそう。

例えば、UserとかDataBaseObjectという名前のクラス名。

よく使いたくなる。分かりやすい名前だしね。

namespaceを使えば、そんな問題を解決してくれる。

あとZendframework2の中でもnamespaceが使われていたりする。

ZendFrameWork2系

ZendSkeltonApplication/module/Application/Module.php


まぁ、実際にテストコードを書いてみた。

テスト1:予約済みの関数を宣言してみる。

まず、通常の

test.php

と書くと

Fatal error: Cannot redeclare var_dump() in /var/www/html/Test/test.php on line 10

var_dump()は既に予約済みのfunctionであるので、使おうとすれば
当然エラーになる。

しかし、namespaceを設定すると、

test.php

It is private var_dump!! your input is test

と問題なく表示される。

どのように処理されているかというと、

namespaceのTestを設定することで、上記で設定したfunctionは名前空間
Testの中に設定したvar_dump()として実行していることになる。

そのためグローバルに設定されているvar_dumpとは別の領域の関数として
扱われる。

テスト2:クラス

test.php

lib/dummy1.php

lib/dummy2.php

とすると、以下のように実行される。

lib/dummy1
lib/dummy2

namespaceを設定していれば、

・lib\dummy1という名前空間の中のDummyクラス

・lib\dummy2という名前空間の中のDummyクラス

という別のクラスとしてみなしていることになる。

namespaceがなければ、当然、Dummyクラスが2回宣言されているわけ
だから、名前の衝突が起きる。

Fatal error: Cannot redeclare class Dummy in 

怒られる...

テスト3:エイリアスを使って、クラスを呼び出す。

namespaceを使う際、useを使ってエイリアスを作成できる。

出力してみると、

hogehoge hogehoge hogehoge

いづれのインスタンスも有効であることが分かる。

コードの中で、名前空間の中でFooクラスのインスタンスを作成するためには
new \Test\Inside\Foo;が必要となる。

しかし、それでは長くなりがちだし、プログラマーなら短くて、シンプルを
求めたい...

というときに、useを使ってエイリアスを作成し、短くすることができる。

上記ではuseを用いたエイリアスの作り方を2つ書いてみた。

  • 一つがuse \A as B;という形、見れば分かるから説明しない。
  • 次に use \;Aという形。これを使うとnew Aで呼び出せるようになる。

自分で意識して使うことはあまりないかもしれないけど、開発の規模が大きく
なったり、コードリーディングを行う際には、どのような機能があるのかは
知っておいた方がいいと思う。




参考: