[PHP] 名前空間 最速マスター

PHP 5.3.0から。

// 名前空間の宣言の前には、declare(encoding = '...');のみ記述できる
// header()やテキストもNo
declare(encoding = 'UTF-8');

// 名前空間と併用する場合、次の形式だとエラー
declare(encoding = 'UTF-8') {
	//...
}

// 名前空間の宣言
// サブ名前空間はバックスラッシュ(\)で区切る
namespace NameSample\NameSub;

// { }で範囲を明示化することもできる
namespace NameSample\NameSub {
	// ...
}

// 名前空間のネストはできない
namespace NameSample {
	namespace NameSub {
		
	}
}// エラー

// 名前空間の影響を受けるのは、
// 宣言した「ファイル」の
// クラス、インターフェイス、関数、定数の4つのみ
class Sample {}
interface ISample {}
function doSample() {}
const SAMPLE = 'sample';

// define()で設定した定数も影響を受ける
define('SAMPLE2', 2);

// 変数は影響を受けない
$sample;

// 名前空間の影響範囲は「ファイル単位」
// それが宣言されたファイルをinclude、requireしても
// 読み込んだ側では影響を受けない
require 'sample.php'
// 以下ではsample.phpとは別のスコープになる

// 名前空間付き識別子の呼び出し
// 完全修飾名では、グローバルスコープを明示するために、
// 先頭にバックスラッシュ(\)をつける
$a = \NameSample\NameSub::SAMPLE;

// 名前空間宣言の影響下ならば、省略できる
$b = SAMPLE;

// 名前空間宣言の影響下だと、
// たとえ標準APIの関数やクラス、定数であっても
// 先頭にバックスラッシュ(\)をつけなければならない
\strlen(SAMPLE);

// 名前空間付きの関数なども、
// 文字列から動的に呼び出すことができる
// 文字列はシングルクオートで囲う
// (バックスラッシュ(\)がエスケープ文字とみなされないように)
call_user_func('\NameSample\NameSub::doSample');

// 現在の名前空間の識別子は、
// マジック定数「__NAMESPACE__」に文字列で入っている
// グローバルスコープ(名前空間なし)ならば、空文字列
echo __NAMESPACE__;

// エイリアスの作成(インポート)
// グローバルスコープか、名前空間の中でのみ行える
// グローバルスコープを示す先頭のバックスラッシュ(\)は
// つけない

// クラス、インターフェイス
use NameSample\NameSub::Sample;
use ArrayObject;

// 名前空間の別名
use NameSample\NameSub as NameAlias;

// 名前空間のインポート
use NameSample\NameSub;
// use NameSample\NameSub as NameSubと同じ;

// 同一行に書くこともできる(カンマ区切り)
use ArrayObject, NameSample\NameSub as NameAlias;

// 関数や定数はインポートできない
use strlen; // エラー

// エイリアスよりも完全修飾名のほうが優先される
$c = \NameSub::SAMPLE;
// グローバルスコープにNameSubがあれば

// クラスなどを文字列から動的に使用する場合は
// インポートの影響を受けない
$sampleClass = 'Sample';
$smp = new $sampleClass;
echo $smp instanceof \NameSample\NameSub::Sample;
// output : 0

// たとえ独自の名前空間の中であっても、
// NULL, TRUE, FALSE, ZEND_THREAD_SAFE, ZEND_DEBUG_BUILDは
// 上書きできない
namespace bar;
const NULL = 0; // 致命的なエラー
const true = 'stupid'; // これも、致命的なエラー

なお、PHPの標準APIやPEARでは、名前空間をパスカル記法(アッパーキャメル記法)で書いている。

標準に合わせることも大事だが、個人的には違和感が強いのと、どこまでが名前空間でどこがクラス名なのか判別しづらいので、自分は他の言語と同じように名前空間はすべて小文字で記述している。

【2012.11.06】クラス名などからの動的生成の場合を修正