はじめに
日本システム開発株式会社の藤井といいます。
今回は名前空間についてまとめてみました。
名前空間とは
クラス、関数...をグループ化する機能です。
PHPタグの次の行でnamespace hoge
と宣言することで、それ以降の定義はすべてその名前空間(グループ)に属します。
名前空間を使うことでクラス、関数をグループごとに管理できます。
使い方
hoge.php
<?php
namespace Hoge;
class fizz{
function __construct() {
echo "hogeFizz" . PHP_EOL;
}
}
?>
foo.php
<?php
namespace Foo;
require "hoge.php";
class buzz{
function __construct() {
echo "buzz" . PHP_EOL;
}
}
$fizz = new \Hoge\fizz();
$fizz = new buzz();
?>
require "hoge.php"
で名前空間Hogeのfizzクラスをfoo.phpに読み込みます。
先頭に\
を付けた完全修飾名で、名前空間Hogeのfizzクラスを指定しています。
グローバル空間、サブ名前空間
名前空間の宣言(namespace)が存在しない場合、そのファイルのクラス、関数...はグローバル空間に属します。
グローバル空間にはPHPの定義済みクラス、関数が存在します。
名前空間はネストすることが可能で、namespace Foo\Bar
は名前空間Fooのサブ空間Barとなります。
名前空間内でのクラス呼び出しの解決
完全修飾名
先頭に\
を付けた呼び出しは、グローバル名前空間を基準に解決されます。
\Foo\Bar\fizz
の形式。\Foo\Bar\fizz
に解決される。
修飾名
先頭以外に\
を含む呼び出しは、現在の名前空間を基準に解決されます。
Bar\fizz
の形式。現在の名前空間\Bar\fizz
に解決される。
非修飾名
どこにも\
を含まない呼び出しは現在の名前空間で解決されます。
fizz
の形式。現在の名前空間\fizz
に解決される。
useを使ったクラスのインポート/エイリアス
useを使うことで前のfoo.phpを書き換えることができます。
foo.php
<?php
namespace Foo;
require "hoge.php";
use Hoge\fizz;
$fizz = new fizz();
$fizz = new fizz();
?>
useを使うとHoge\fizzをFoo\fizzのように使えます。(インポート)
useを使うことで完全修飾名を使う必要がなくなり、簡潔に書くことができます。
useを使うとHoge\fizzを現在のFooにインポートしますが、Foo内のクラスとの重複を避けるためエイリアスをつけられます。
foo.php
<?php
namespace Foo;
require "hoge.php";
use Hoge\fizz as hogeFizz;
class fizz{
function __construct() {
echo "fooFizz" . PHP_EOL;
}
}
$fizz = new HogeFizz();
$fizz = new fizz();
?>
定義済みのクラス
PHPにはStdClassなどの定義済みクラスがあります。
名前空間を使わない場合は、new StdClass()
で呼び出せますが、
名前空間を使うと、先頭に\
のない呼び出しは現在の名前空間を基準に呼び出します。
そのため、定義済みクラスはnew \StdClass()
で呼び出します。
<?php
namespace Huge;
$std = new \StdClass();
var_dump($std);
// useでのインポートも可能です
use StdClass;
$std = new StdClass();
var_dump($std);
?>
psr-4
autoloadするための仕様のことです。
autoloadとは、
クラスを呼び出したタイミングで、そのクラスが見つからなかった場合にクラスの完全修飾名から
ファイルを自動的にロード(include)するための枠組み
具体的には、spl_autoload_registerでロード用の関数を登録し、クラスが見つからなかった場合にその関数が呼び出される。
psr-4はロード用の関数の仕様で、名前空間とディレクトリを紐づけることで、独自のディレクトリ構造からファイルをロードできる。
<?php
namespace Foo;
use Hoge\huga\fizz;
$fizz = new fizz;
?>
Hoge\huga\fizzはどこにも定義されていないため、クラスが見つからずエラーになる。
spl_autoload_registerで登録した関数は、このタイミングで呼び出される。
composer.jsonのautoload
"autoload": {
"psr-4": {
"Hoge\\": "app/"
}
}
composerのpsr-4を用いるとHoge\huga\fizzへのアクセスは、
Hogeがappディレクトリに変換され、app\huga\fizz.phpをautoloadします。
autoloadと名前空間は別の機能のため、autoloadしたファイルで該当の名前空間(Hoge\huga)
が宣言されていない場合、クラスへのアクセス(new fizz)はエラーになります。
まとめ
- 名前空間とはクラスや関数...をグループ化し管理する機能
- 名前空間内からのクラスや関数...へのアクセスは、完全修飾名、修飾名、非修飾名のいずれかを用いる
- useを使うことで、異なる名前空間にあるクラスや関数...を現在の名前空間にインポートできる
- psr-4とはautoloadの仕様で、名前空間とディレクトリを紐づけロードするファイルを見つける