PHP 名前空間とuseキーワードの使い方
はじめに
PHPを用いたアプリケーション開発の際に使用する名前空間やuseキーワードですが、その意味や使い方に惑われた方も多いのではないでしょうか。PHPを独学で学習されている方であればこれらの文法はあまり気にならなかったかもしれませんが、大規模な開発やチーム開発に携わるとこれらの仕様を理解しておく必要が出てきます。なぜなら、他の人が作成したクラスを導入したり合わせて使用したりするときに、クラス名や関数名が重複して名前の衝突を起こしてしまうことがあるからです。
例えば、Javaではパッケージによってクラス名や関数名の衝突がないようにしていますが、PHPでは名前空間を用いることで区別しているのです。
本記事では、この名前空間を宣言するnamespaceの使用方法とuseという単語を用いた使用方法をご紹介いたします。最後までお読みいただければ、PHPで大規模なアプリケーション開発に携わっても名前の重複で困ることは無くなるでしょう。
名前空間について
PHPでは同一の関数名を定義することはできません。重複したメソッド名を定義して実行すると、Fatal error: Cannot redeclare というエラーが表示されます。
Fatal error(フェイタルエラー)とは、 処理が停止してしまう致命的なエラーです。
PHPには注意程度のレベルから、重大なエラーまでありますが、その中でもFatal errorは処理を停止するほどの重大なエラーということです。
<greeting.php>
function hello() {
return 'こんにちは';
}
<calling.php>
function hello() {
return 'もしもし';
}
<sample.php>
require_once 'greeting.php'; // greeting.phpの読み込み
require_once 'calling.php'; // calling.phpの読み込み
echo hello(); // エラー表示:PHP Fatal error: Cannot redeclare hello()
上記のような例では重複した名前を避けて宣言すればいいと思うでしょう。しかし、冒頭でも述べたように、大規模な開発となると自分のみならず他人のコードも意識して使わなくてはならなくなります。
すべての関数名やクラス名を把握するのは非常に難しいですが、そこでこの問題を解決するのが名前空間となります。名前空間とはその名の通り名前の空間のことで、ある領域に名前をつけることによりクラスや関数がその空間に所属していると区別できるようになります。
namespace の使い方
名前空間を定義するには namespace 空間名;
とこのようにコーディングします。実際に名前空間を使った例を下記のサンプルコードで確認してください。
<greeting.php>
namespace greet; // 名前空間を定義
function hello() {
return 'こんにちは';
}
<calling.php>
namespace call; // 名前空間を定義
function hello() {
return 'もしもし';
}
greeting.phpとcalling.phpで重複したhelloメソッドを使用しました。本来、同一名のメソッドが2つ以上存在するときは実行時にエラーが表示されますが、namespaceを用いて名前空間を明示しているため、エラーは表示されません。
名前空間を指定したいときは空間名/メソッド名();
とコーディングし、利用する空間を指定しましょう。
<sample.php>
require_once 'greeting.php';
require_once 'calling.php';
echo greet¥¥hello(); // 出力結果:こんにちは
sample.phpではhelloメソッドが定義されているgreeting.phpとcalling.phpの2つのファイルを読み込んでいます。
greet/hello();
でgreetと定義した名前空間を指定しているため、指定された名前空間のhelloメソッドが呼び出され、出力結果は「こんにちは」となるのです。
call/hello();
とcallの名前空間を指定したときは「もしもし」と表示されます。
useキーワード
名前空間はディレクトリ構造のように階層をもたせることができます。階層は ¥¥(バックスラッシュ)
で区切って書いていきます。
<greeting.php>
namespace Earth¥¥Asia¥¥Japan¥¥Kanto¥¥Tokyo;
function hello() {
return 'こんにちは';
}
<calling.php>
namespace Earth¥¥Asia¥¥Japan¥¥Hokkaido¥¥Hokkaido¥¥Sapporo;
function hello() {
return 'もしもし';
}
<sample.php>
require_once 'greeting.php';
require_once 'calling.php';
echo ¥¥Earth¥¥Asia¥¥Japan¥¥Hokkaido¥¥Hokkaido¥¥Sapporo¥¥hello(); // 出力結果:もしもし
階層が多くなれば多くなるほど毎回名前空間を書くのが大変になりますが、そこで活躍するのがuseキーワードなのです。
use キーワードの使い方
<エイリアスの作成>
useキーワード用いてエイリアスを作ることが可能になり、簡単に名前空間を指定できるようになります。
エイリアス(alias)とは別名、通称、あだ名のようなものです。useキーワードで長くなった名前空間に名前をつけることで、多くの階層を持った名前空間も簡単に指定することができます。エイリアスを作成するには use 名前空間 as エイリアス;
とコーディングします。
<greeting.php>
namespace Asia¥¥Japan¥¥Kanto¥¥Tokyo;
function hello() {
return 'こんにちは';
}
<calling.php>
namespace Asia¥¥Japan¥¥Hokkaido¥¥Hokkaido¥¥Sapporo;
function hello() {
return 'もしもし';
}
<sample.php>
require_once 'greeting.php';
use Asia¥¥Japan¥¥Kanto¥¥Tokyo as Tokyo;
require_once 'calling.php';
use Asia¥¥Japan¥¥Hokkaido¥¥Hokkaido¥¥Sapporo as Hokkaido;
echo Tokyo¥¥hello(); // 出力結果:こんにちは
echo Hokkaido¥¥hello(); // 出力結果:もしもし
useキーワードでエイリアスを作成しておくことで、名前空間をわざわざ記述する必要がなくなります。useキーワードのその他の使い方もみていきましょう。
<名前空間のインポート>
useキーワードは use 名前空間;
と記述することで名前空間をインポートします。エイリアスを作成しないときは一番右の非修飾名でインポートされます。こうすることで、すべて指定しなくても一番右にある非修飾名だけでインポートが可能です。
<greeting.php>
namespace Asia¥¥Japan¥¥Kanto¥¥Tokyo;
function hello() {
return 'こんにちは';
}
<sample.php>
require_once 'greeting.php';
use Asia¥¥Japan¥¥Kanto¥¥Tokyo;
echo Tokyo¥¥hello(); // 出力結果:こんにちは
Asia¥¥Japan¥¥Kanto¥¥Tokyo;
と名前空間を記述したため、一番右の非修飾名Tokyoでインポートされます。そのため次回以降、この名前空間を指定したいときにはTokyoと記述するだけで問題ありません。
<クラスのインポート>
use名前空間¥¥クラス名;
と記述することでクラスをインポートすることも可能です。
<greeting.php>
namespace Asia¥¥Japan¥¥Kanto¥¥Tokyo;
class hoge {
function hello() {
return 'こんにちは';
}
}
<sample.php>
require_once 'greeting.php';
use Asia¥¥Japan¥¥Kanto¥¥Tokyo¥¥hoge;
$a = new hoge;
echo $a->hello(); // 出力結果:こんにちは
sample.phpでは名前空間 Asia¥¥Japan¥¥Kanto¥¥Tokyo
のあとにクラス名¥¥hoge
をつけることでインポートします。
<関数のインポート>
useキーワードはクラスだけでなく関数もインポート可能です。関数のインポートをするためにはuse function 名前空間¥¥関数名;
とコーディングします。
<calling.php>
namespace Asia¥¥Japan¥¥Hokkaido¥¥Hokkaido¥¥Sapporo;
function hello() {
return 'もしもし';
}
<sample.php>
require_once 'calling.php';
use function Asia¥¥Japan¥¥Hokkaido¥¥Hokkaido¥¥Sapporo¥¥hello;
echo hello(); // 出力結果:もしもし
名前空間 Asia¥¥Japan¥¥Hokkaido¥¥Hokkaido¥¥Sapporo
のあとに、関数名¥¥hello
と記述することで関数をインポートすることができ hello();
のみで出力することができます。別の名前空間から同じ名前のhello関数はインポートできないということに注意しましょう。
<定数のインポート>
PHP5.6.0からuseキーワードで定数をインポートできるようになりました。定数をインポートするには function const 名前空間¥¥定数名;
とコーディングします。
<greeting.php>
namespace Asia¥¥Japan¥¥Kanto¥¥Tokyo;
const Hello = 'やあ、こんにちは';
<sample.php>
require_once 'greeting.php';
use const Asia¥¥Japan¥¥Kanto¥¥Tokyo¥¥Hello;
echo Hello; // 出力結果:やあ、こんにちは
名前空間 Asia¥¥Japan¥¥Kanto¥¥Tokyo;
に続けて定数名Helloを記述することでインポートすることができました。
まとめ
いかがだったでしょうか。 多くの人が関わる開発では、名前の衝突が起こらないようにするために名前空間を使うことが多々あります。開発をしていく中でも、コードを読み解く上でも、これらの知識は役に立つでしょう。
現場によっては命名規則を用いて、もとから重複しないようにしているところもあります。実際に自分がコーディングをしていくときには、これらを意識して命名していくと良いかもしれません。本記事によって名前空間やnamespaceとuseの使い方について少しでも理解を深めていただければ幸いです。最後までお読みいただき、ありがとうございました。