PHPの名前空間とは
名前空間とはnamespaceのことで、文字通り名前(name)を置く空間(space)のことです。
名前の衝突を回避するために、名前の居場所を明示します。
ここでいう名前とはPHPのクラス名、インターフェース名、関数名、定数名のことです。
同じ名前のクラスをつけないように気をつければよいじゃないか、と思うかもしれません。
それは間違いではありません。。実際名前空間という機能が提供される前のPHPではそうやっていました。クラス名に機能を表す文字をつけたりしてクラス名が長くなったりして。
複数人で開発をしたり、サードパーティのライブラリで使用している名前とかぶってしまったり。
また、不要なファイルをrequireしなければよいじゃないかと思うかもしれません。
実際それも間違いではないのですが、ファイルの読み込みがフレームワークによって自動的に行われていたりrequireしたファイルがさらに別のファイルをrequireしているなど、すべての範囲を見通すのは大変です。
requireを1つ追加するたびに影響範囲の調査をしなくてはなりません。
またそれ以前に同名で違う機能を持つクラスをそれぞれ使いたいことがあるかもしれません。
その場合はクラス名を変えるしかありません。
名前空間を適用すると、そもそもそういうことを気にしないでよくなります。
ルールを決めておけば、「気をつける」必要がなくなるのです。
では実際にソースを見てみます。
<?php
class Dog{
function bark(){
echo "wan!";
}
}
<?php
require_once "japan/dog.php";
$dog = new Dog();
echo $dog->bark();
c:\tmp>php sample01.php
wan!
これに同名のDogクラスを追加してみます。
<?php
class Dog{
function bark(){
echo "bow!";
}
}
そして新しいクラスをrequireします。
require_once "japan/dog.php";
require_once "usa/dog.php";
c:\tmp>php sample01.php
Fatal error: Cannot redeclare class Dog in C:\tmp\usa\dog.php on line 2
Call Stack:
0.0100 123048 1. {main}() C:\tmp\sample01.php:0
0.0100 126024 2. require_once('C:\tmp\usa\dog.php') C:\tmp\sample01.php:3
Dogが2回宣言されているとエラーが出ました。
1つめをjapan、2つ目をusaとして、namespaceを追加します。
<?php
namespace japan;
class Dog{
~
<?php
namespace usa;
class Dog{
~
これで実行してみます。
c:\tmp>php sample01.php
Fatal error: Class 'Dog' not found in C:\tmp\sample01.php on line 5
Call Stack:
0.0050 123048 1. {main}() C:\tmp\sample01.php:0
エラーになりました。Dogが見つからないとのことです。
そうです。名前空間を指定したクラスは使用するときに、その名前空間を指定する必要があるのです。
呼び出し側を修正します。
<?php
require_once "japan/dog.php";
require_once "usa/dog.php";
$dog = new japan\Dog();
echo $dog->bark();
c:\tmp>php sample01.php
wan!
正常に実行できました。
ファイル名との関係
名前空間とファイル・ディレクトリ構成には一切関連がありません。
たとえば下記のようにfranceディレクトリのファイルにitalyという名前空間をつけることも可能です。
<?php
namespace italy;
class Dog{
function bark(){
echo "bau!";
}
}
呼び出すときはこうします。
<?php
require_once "france/dog.php";
$dog = new italy\Dog();
echo $dog->bark();
ちゃんと実行できます。
c:\tmp>php sample02.php
bau!
ただし、これはできるというだけで、わかりにくすぎますし、こんなことをする意味はありません。
実際PHPのコーディング規約がPSR-Xという形で標準化されれいるのですが、
そこでは基本的にはディレクトリと名前空間の区切りはあわせることになっています。