Udemy で講座の販売を開始しました!
Udemy で「プログラミング学習の心得&HTTPの基礎」の動画講座を公開しました。
特別に 85% OFFのクーポンを発行します。
通常価格 10,800 円が 1,800 円で購入できます。
動画内でも説明していますが、初心者・初学者向けの内容です。
事前に自分の知りたい内容・興味のある内容か確認してからご購入ください。
はじめに
Webアプリケーションを作るときに名前空間という機能がよく利用されています。
便利な機能なので、理解しておきましょう。
この記事は、関数ぐらいまでの知識がある方が対象です。
クラスの基礎(プロパティやメソッド)知識があると尚よいです。
クラスのプロパティやメソッドについて理解していない方は、下記の該当箇所をご覧ください。
今回、名前空間について学ぶために
- PHPは同じ名前の関数は定義できない?
- 名前空間を定義する
- 名前空間に属する関数を利用するには?
- 実際に名前空間を利用してみる
- 一つのファイルに複数の名前空間を記述できるの?
- 名前空間の外にも命令文を記述できるの?
- 複数のファイルで同じ名前空間は使えるの?
- サブ名前空間って何?
- 名前空間の記述について
- 名前空間を定義しない場合は?
- use キーワードについて
- インポート・エイリアスの有効範囲
- 現在の名前空間名を表示する
という流れでまとめました。
今回は、下記のローカル環境で動作確認しています。
OS | XAMPP | Apache | PHP |
---|---|---|---|
Windows10 | 5.6.24 | 2.4.23 | 5.6.24 |
私自身、未熟ですので説明に誤りがあるかもしれません。
そのときは、ご指摘ください((_ _ (´ω` )ペコ
PHPは同じ名前の関数は定義できない?
本当に同じ名前の関数が定義できないのか確かめてみましょう。
sato.php
と suzuki.php
の2つのファイルで同名の getGreeting()
という挨拶を返してくれる関数を定義します。
<?php
function getGreeting() {
return 'おはよう';
}
<?php
function getGreeting() {
return 'こんばんは';
}
call.php
から2つのファイルを読み込み、getGreeting()
関数を呼びましょう。
<?php
require_once 'sato.php';
require_once 'suzuki.php';
echo getGreeting();
sato.php
の getGreeting()
なら おはよう
と表示され、suzuki.php
の getGreeting()
なら こんばんは
と表示されるはずですが、エラーが表示されました。
Fatal error: Cannot redeclare getGreeting() (previously declared in C:\xampp\htdocs\suzuki.php:3) in C:\xampp\htdocs\sato.php on line 4
Fatal error
は致命的なエラーという意味で、redeclare
は re- + declare
という英語で declare
は宣言という意味ですので、Cannot redeclare getGreeting()
は getGreeting()
関数を再度宣言することはできませんという意味になります。
ご覧の通り、同じ関数名を使うことはできません。
別の関数名にすれば問題は解決できますが、定義する関数が多くなると名前の衝突を避けるために冗長な名前にしなければなりません。
また、複数人で各々がコードを書いて、それぞれのコードを読み込んだときに名前が衝突する可能性もあります。
名前空間を使うことで、この問題を解決できます。
名前空間を定義する
名前空間とは、文字通り名前の空間のことで、ここからここまでのコードが○○という空間に属していると定めることができます。
空間が違えば、同じ関数名を定義して使うことができます。
名前空間という仕組みは、PHP5.3.0で導入されました。
名前空間を定義するには、namespace
キーワードの後に任意の空間名を記述します。
namespace 名前空間名;
この namespace
の記述ですが、今は関数を定義する方に記述します。
先ほどの例で言えば、sato.php
または suzuki.php
に記述します。
また、namespace
は、最初に記述してください。
<?php
namespace test;
namespace
の前にphpの命令文やHTMLなどを記述するとエラーが表示されます。
namespace
より前に書くことが許されているコードは declare(ディクレア)文のみです。
<?php
require_once 'test.php';
namespace test;
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<?php
namespace test;
?>
</body>
</html>
次は、名前空間に属する関数を利用する方法を見ていきましょう。
名前空間に属する関数を利用するには?
名前空間に属する関数を呼ぶときは、○○の名前空間にある関数だよと記述する必要があります。
最初に名前空間名を記述した後に \
(バックスラッシュ)を記述し、その後に関数名を記述します。
バックスラッシュは、円記号で入力できます。
環境によっては、バックスラッシュではなく、円記号で表示されますが、円記号のままで問題ありません。
名前空間名\関数名;
先ほどの例でいえば、call.php
で関数を利用するときに上述したように記述します。
今まで同名の関数は定義できないと言ってきましたが、下記も同様です。
- 関数
- クラス
- インターフェイス
- 定数(constで定義)
これらも名前空間を利用することで、名前の衝突を避けることができます。
逆に言えば上述した4つ以外は、名前空間の影響を受けません。
今回は関数を例にしていますが、主にクラス名の衝突を避けるために名前空間が用いられることが多いです。
名前空間に属するクラスを利用する場合は、先ほどの関数名をクラス名にするだけです。
名前空間名\クラス名;
ちなみにPHPで定数を定義するには、 const
キーワードとdefine
関数を使う2種類の方法があります。
名前空間の影響を受けるのは、const
キーワードのみで、define
関数は影響を受けません。
次は、名前空間を利用してみましょう。
実際に名前空間を利用してみる
最初にエラーが発生した sato.php
と suzuki.php
で名前空間を定義してみましょう。
sato.php
に namespace sato;
を追記します。
<?php
namespace sato;
function getGreeting() {
return 'おはよう';
}
今度は、suzuki.php
に namespace suzuki;
を追加しましょう。
<?php
namespace suzuki;
function getGreeting() {
return 'こんばんは';
}
call.php
では sato\getGreeting();
として関数を利用します。
<?php
require_once 'sato.php';
require_once 'suzuki.php';
echo sato\getGreeting();
これで、sato
という名前空間にあるgetGreeting()
関数が呼ばれ おはよう
と表示されます。
sato\getGreeting();
を、suzuki\getGreeting();
に変更すれば、こんばんは
と表示されます。
今回、名前空間名をファイル名と同じく命名しましたが、名前空間名は任意で決められますので、ファイル名と関係ない名前空間名にすることも可能です。
ただ、全く関係がない名前空間名にするとわかりにくいので、ファイル名と同じくするなどわかりやすい名前空間名にしてください。
一つのファイルに複数の名前空間を記述できるの?
先ほどは、一つのファイルに一つの名前空間を定義しましたが、一つのファイルに複数の名前空間を定義することが可能です。
複数の名前空間を定義するには、2つの方法があります。
それぞれの方法を確認しましょう。
No.1 名前空間を続けて記述する方法
<?php
namespace takahashi;
function getGreeting() {
return 'ごきげんよう';
}
namespace tanaka;
function getGreeting() {
return 'Hello';
}
namespace
で名前空間を宣言した後に記述した関数などは、その名前空間に属します。
その後にまた namespace
で名前空間を宣言すれば、その名前空間に属します。
先ほどの記述は、下記のような名前空間になります。
call.php
で関数を呼ぶときに適切に名前空間名を記述すれば、それぞれの関数を呼ぶことができます。
<?php
require_once 'function.php';
echo takahashi\getGreeting();
echo tanaka\getGreeting();
実行すると ごきげんよう
と Hello
が表示されます。
名前空間を続けて記述する方法を紹介しましたが、この方法は、どこまでがどの名前空間かわかりにくいので推奨されません。
もう一つの方法も見ていきましょう。
No.2 波括弧で囲む方法
波括弧で囲むことで名前空間を定義することが可能です。
波括弧内に記述した関数などは、その名前空間に属します。
<?php
namespace takahashi {
function getGreeting() {
return 'ごきげんよう';
}
}
namespace tanaka {
function getGreeting() {
return 'Hello';
}
}
下記のような名前空間になります。
先ほどと同様に call.php
で名前空間を含めて関数を記述すれば、それぞれの関数を呼ぶことができます。
<?php
require_once 'function.php';
echo takahashi\getGreeting();
echo tanaka\getGreeting();
実行すると ごきげんよう
と Hello
が表示されます。
波括弧を使って複数の名前空間を定義する方法を紹介しました。
先ほどの方法より、わかりやすくなっていますが、なるべく一つのファイルでは一つの名前空間にするのがわかりやすいです。
波括弧を使って複数の名前空間を定義する方法を紹介しましたが、名前空間の外(波括弧の外)に命令文を記述できるのか確かめてみましょう。
名前空間の外にも命令文を記述できるの?
名前空間の外にも、命令文を記述できるのか確かめてみましょう。
先ほどの記述の最後に echo
文を追記します。
<?php
namespace takahashi {
function getGreeting() {
return 'ごきげんよう';
}
}
namespace tanaka {
function getGreeting() {
return 'Hello';
}
}
echo 'ニーハオ';
実行すれば ニーハオ
と表示されるはずですが、下記のようなエラーが表示されました。
Fatal error: No code may exist outside of namespace {}
Fatal error
は致命的なエラーという意味で、No code may exist outside of namespace
は、「コードは名前空間の外に存在してはいけません」というような意味だと思います。
英語がダメな人なので、意訳に誤りがあればご指摘ください。
ご覧のように名前空間の外に命令文を記述することはできませんので気をつけましょう。
名前空間は、複数のファイルで同じ名前空間を宣言することが可能です。
その方法を見ていきましょう。
複数のファイルで同じ名前空間は使えるの?
複数のファイルで同じ名前空間を使えます。
単純に同じ名前空間名の namespace
を宣言すれば、同じ名前空間になります。
<?php
namespace human;
<?php
namespace human;
takahashi.php
と tanaka.php
は同じ名前空間です。
当たり前ですが、同じ名前空間になるので、同名の関数などは定義できません。
今まで、名前空間名を takahashi
や tanaka
などと命名してきましたが、単純なので名前空間名が重複する可能性があります。
サブ名前空間を使うことでもっと自由な命名が可能になります。
サブ名前空間って何?
名前空間は、ディレクトリ構造の概念と同じく階層を持たせて記述することが可能です。
\
で区切ってサブ名前空間を記述できます。
名前空間\サブ名前空間\サブ名前空間
sato.php
の名前空間名をサブ名前空間使って japan\tokyo\chiyoda\sato
にしてみましょう。
<?php
namespace japan\tokyo\chiyoda\sato;
function getGreeting() {
return 'おはよう';
}
名前空間に属する関数を利用するには、名前空間名も記述する必要があります。
このときにサブ名前空間も忘れずに記述しましょう。
<?php
require_once 'sato.php';
echo japan\tokyo\chiyoda\sato\getGreeting();
実行すると おはよう
と表示されます。
サブ名前空間が使えることで、実際のディレクトリ構造と同じ命名が可能になります。
サブ名前空間も使ってわかりやすい名前空間名を命名するようにしましょう。
先ほど名前空間に属する関数を呼ぶときに japan\tokyo\chiyoda\sato\getGreeting()
と記述しました。
実はこの記述の仕方にはいくつか種類があります。
HTMLには画像へのパスを指定するときにルート相対パスやドキュメント相対パスなどの種類があります。
下層フォルダにある画像へアクセスするのか、同ディレクトリにある画像にアクセスするのか、ルートディレクトリから画像へアクセスするのかによって記述の仕方が異なります。
<img src="images/photo.jpg">
<img src="photo.jpg">
<img src="/2016/images/photo.jpg">
名前空間も画像のパスと同様に記述の仕方が変わります。
次は、この記述の仕方について見ていきましょう。
名前空間の記述について
今まで関数を呼ぶ側には、名前空間を指定しませんでした。
関数を呼ぶ側にも、namespace
を記述することが可能です。
実際に関数を呼ぶ側にも同じ名前空間を宣言して確かめてみましょう。
実際に同じ名前空間を宣言して関数を呼んで確かめる
sato.php
の名前空間名を japan\sato
にして、getGreeting()
関数を記述します。
<?php
namespace japan\sato;
function getGreeting() {
return 'おはよう';
}
call.php
でも同名の名前空間を定義し、echo japan\sato\getGreeting();
として関数を呼んでみましょう。
<?php
namespace japan\sato;
require_once 'sato.php';
echo japan\sato\getGreeting();
実行すると下記のエラーが表示されました。
Fatal error: Call to undefined function japan\sato\japan\sato\getGreeting() in C:\xampp\htdocs\call.php on line 4
Fatal error
は致命的なエラーという意味で、Call to undefined function
はコールする関数が未定義ですという意味になります。
注目すべきは次の japan\sato\japan\sato\getGreeting()
です。
japan\sato
が2回記述されています。
今回、call.php
には同じ名前空間を宣言したので、sato.php
も call.php
も同じ名前空間に属します。
ディレクトリ構造で言えば、同ディレクトリにあるのと同じです。
同ディレクトリにあるなら、階層の記述は不要です。
同ディレクトリにもあるにもかかわらず、japan\sato\getGreeting()
と記述したため、エラーが表示されました。
echo japan\sato\getGreeting();
を echo getGreeting();
に変更しましょう。
<?php
namespace japan\sato;
require_once 'sato.php';
echo getGreeting();
実行すると おはよう
と表示されます。
このようにディレクトリ構造のように階層によって指定方法が異なります。
名前空間の指定方法には
- 非修飾形式
- 修飾形式
- 完全修飾形式
の3つがあります。どのような形式なのか確認していきましょう。
非修飾形式
ディレクトリ構造で言うところの同ディレクトリ内からの指定になります。
sato.php
には tokyo\sato;
という名前空間名を定義し、getGreeting()
関数を記述します。
<?php
namespace tokyo\sato;
function getGreeting() {
return 'おはよう';
}
call.php
には sato.php
と同じ名前空間を定義します。
同じ名前空間にあるため、関数を呼ぶときは名前空間を記述しません。
<?php
namespace tokyo\sato;
require_once 'sato.php';
echo getGreeting();
このように同じ名前空間にあるため、 \
を含まない指定が非修飾形式です。
修飾形式
ディレクトリ構造で言うところのドキュメント相対パスです。
先ほどと同様に sato.php
には namespace tokyo\sato;
という名前空間名を定義し、getGreeting()
関数を記述します。
<?php
namespace tokyo\sato;
function getGreeting() {
return 'おはよう';
}
call.php
には tokyo
という名前空間を定義します。
ディレクトリ構造で言うと sato.php
の名前空間より一つ上の階層に位置します。
一つ上の階層にあるため、関数を呼ぶときは echo sato\getGreeting();
と記述します。
<?php
namespace tokyo;
require_once 'sato.php';
echo sato\getGreeting();
このように上位階層にあるため、途中に \
を含めて階層も指定するのが修飾形式です。
完全修飾形式
ディレクトリ構造で言うところのルート相対パスです。
先ほどと同様に sato.php
には namespace tokyo\sato;
という名前空間名を定義し、getGreeting()
関数を記述します。
<?php
namespace tokyo\sato;
function getGreeting() {
return 'おはよう';
}
関数を呼ぶときに最上位階層から指定するため、call.php
の名前空間はどこでも構いませんが、tokyo
とします。
関数を呼ぶときは、最初に \
を記述して最上位階層から指定します。
echo \tokyo\sato\getGreeting();
と記述します。
<?php
namespace tokyo;
require_once 'sato.php';
echo \tokyo\sato\getGreeting();
このように最初に \
を記述して最上位階層から指定するのが完全修飾形式です。
これで、それぞれの形式について理解できたかと思います。
最初の方では、関数を呼ぶ側には名前空間を定義していません。
この場合は、どのような名前空間になっているのか見ていきましょう。
名前空間を定義しない場合は?
名前空間を定義しないとグローバル名前空間に属します。
ディレクトリ構造で言うところのルートディレクトリです。
先ほど、波括弧を使って複数の名前空間を定義する方法を紹介しました。
このときに namespace
の名前空間名を省略すると、グローバル名前空間になります。
下記のように記述した場合、最後の getGreeting()
関数はグローバル名前空間に属します。
<?php
namespace takahashi {
function getGreeting() {
return 'ごきげんよう';
}
}
namespace tanaka {
function getGreeting() {
return 'Hello';
}
}
namespace {
function getGreeting() {
return 'ニーハオ';
}
}
名前空間を宣言しない場合と、namespace
の名前空間名を省略した場合は、両方ともグローバル名前空間に属するため、下記の2つは同じ名前空間に同じ関数が定義されていることになります。
<?php
function getGreeting() {
return 'ニーハオ';
}
<?php
namespace {
function getGreeting() {
return 'ニーハオ';
}
}
これで namespace
の記述については、一通り理解できたかと思います。
ただ、名前空間名が japan\tokyo\chiyoda\sato\getGreeting();
のように長いと毎回書くのが大変です。
use
キーワード使うことで、このような問題を解決できます。
use キーワードについて
use
キーワードを使うことで、名前空間などをインポートしたり、エイリアスを作成することができます。
まずは、インポートとエイリアスの意味について確認しましょう。
エイリアスとは、下記の意味を持つ英単語です。
エイリアスとは、偽名、別名、通称などの意味を持つ英単語。
インポートとは、下記の意味を持つ英単語です。
インポートとは、取り込む、取り込み、持ち込む、持ち込み、運び込む、輸入(する)、移入(する)などの意味を持つ英単語。
use
キーワードを使うことで、名前空間の記述を短くした別名または同名を作ることが可能です。
別名の場合はエイリアスと呼び、同名の場合はインポートと呼びます。
今の段階では「名前空間の記述を短くした別名または同名」というのがイメージできないと思いますが、今のところはエイリアスとインポートの定義だけ覚えておきましょう。
use
キーワードを使うことで、具体的には下記のことが可能です。
- 名前空間などのエイリアス(別名)を作成
- 名前空間の全て、または一部をインポート
- クラスをインポート
- 関数をインポート
- 定数をインポート
それぞれの方法を確認していきましょう。
名前空間などのエイリアス(別名)を作成
use
キーワードと as
キーワードを組み合わせて名前空間のエイリアス(別名)を作成することが可能です。
エイリアスを作成するには、下記のように記述します。
use 名前空間の全て、または一部 as 別名;
use
の後に記述する名前空間は完全修飾形式で記述してください。
これはエイリアスを作成するときだけではなく、use
キーワードで記述するときの決まりごとです。
完全修飾形式は、先頭に\
を付ける必要がありますが、use
に記述する名前空間は完全修飾形式として扱われるため、先頭の \
は不要です。
use
キーワードでは、先頭の \
は付けないでください。
実際に名前空間のエイリアスを作成してみましょう。
tokyo.php
には asia\japan\kanto\tokyo
という名前空間を定義して、クラス内に getPref()
メソッドを定義します。
getPref()
メソッドを呼ぶと tokyo
と表示されます。
<?php
namespace asia\japan\kanto\tokyo;
class pref {
public function getPref() {
return 'tokyo';
}
}
call.php
では use
を使ってエイリアスを作成します。
use asia\japan\kanto as area;
と記述することで、area
というエイリアスが作成されます。
これ以降、area
と記述すれば、asia\japan\kanto
として扱われます。
次の行では、area\tokyo\pref;
としてエイリアスを利用します。
<?php
require_once 'tokyo.php';
use asia\japan\kanto as area;
$a = new area\tokyo\pref;
echo $a->getPref();
実行すると tokyo
と表示されます。
今回は、名前空間のエイリアスを作成しましたが、関数、クラス、インターフェイス、定数のエイリアスを作成することも可能です。
先ほどは as
キーワードを使ってエイリアスを作成しました。
as
キーワードを省略すると、一番右にある非修飾名でインポートすることができます。
次はインポートする方法を見ていきましょう。
名前空間の全て、または一部をインポート
名前空間の全て、または一部をインポートします。
use
の後にインポートしたい名前空間の全て、または一部を記述してください。
use 完全修形式の名前空間または一部;
実際に確かめてみましょう。
tokyo.php
は先ほどと同じ記述です。
<?php
namespace asia\japan\kanto\tokyo;
class pref {
public function getPref() {
return 'tokyo';
}
}
call.php
では use asia\japan\kanto;
と記述することで、名前空間の一部をインポートします。
一番右にある非修飾名の kanto
でインポートしています。
先ほどの as
キーワードを使って表すなら use asia\japan\kanto as kanto
と同じ意味です。
今回は別名ではなく、同名ですので、名前空間の一部をインポートしています。
<?php
require_once 'tokyo.php';
use asia\japan\kanto;
$a = new kanto\tokyo\pref;
echo $a->getPref();
実行すると tokyo
と表示されました。
次はクラスをインポートする方法見ていきましょう。
クラスをインポート
先ほどの名前空間をインポートする方法と、ほぼ同じですが use
の後に先頭の \
を除いた完全修飾形式で記述したクラス名を記述してください。
use 完全修飾形式のクラス名;
実際に確かめてみましょう。
tokyo.php
は先ほどと同じ記述です。
<?php
namespace asia\japan\kanto\tokyo;
class pref {
public function getPref() {
return 'tokyo';
}
}
call.php
では use asia\japan\kanto\tokyo\pref;
と記述することで、クラスをインポートします。
一番右にある非修飾名の pref
でインポートしています。
<?php
require_once 'tokyo.php';
use asia\japan\kanto\tokyo\pref;
$b = new pref;
echo $b->getPref();
実行すると tokyo
と表示されました。
インポートするときに、use
と何回も記述するのは手間がかかります。
まとめてインポートすることも可能です。
クラスをまとめてインポート(カンマ区切り)
,
区切りで記述すれば、まとめてインポートできます。
use 完全修飾形式のクラス名, 完全修飾形式のクラス名;
use asia\japan\kanto\tokyo\pref, asia\japan\kanto\tokyo\bird, asia\japan\kanto\tokyo\flower;
例としてクラスを用いていますが、名前空間でも関数でも定数でも同様にまとめてインポートできます。
まとめてインポートできましたが、毎回長い修飾名を書くのは手間です。
PHP7.0.0から {}
を使って、より簡単にまとめてインポートすることができるようになりました。
その方法を確認しましょう。
クラスをまとめてインポート(波括弧・カンマ区切り)
{}
内に ,
区切りで記述することで、まとめてインポートできます。
use 完全修飾形式{クラス名, クラス名};
use asia\japan\kanto\tokyo\{
pref, bird, flower
};
use asia\japan\kanto\{
tokyo\pref,
chiba\bird,
kanagawa\flower
};
こちらも例としてクラスを用いていますが、名前空間でも関数でも定数でも同様にまとめてインポートできます。
PHP5.6.0から関数のインポートができるようになりました。
その方法を確認しましょう。
関数をインポート
関数をインポートするときは、use function
の後に先頭の \
を除いた完全修飾形式で関数名を記述してください。
use function 完全修飾形式の関数名;
実際に確かめてみましょう。
tokyo.php
に asia\japan\kanto\tokyo
という名前空間を定義します。
その後に getFlower()
関数を記述します。
<?php
namespace asia\japan\kanto\tokyo;
function getFlower() {
return 'someiyoshino';
}
call.php
では、use function asia\japan\kanto\tokyo\getFlower;
として関数をインポートします。
<?php
require_once 'tokyo.php';
use function asia\japan\kanto\tokyo\getFlower;
echo getFlower();
実行するとsomeiyoshino
と表示されます。
PHP5.6.0より前のバージョンでは、関数をインポートすることはできませんので、最初で紹介した名前空間をインポートする方法を利用すれば、短く記述することができます。
PHP5.6.0から定数をインポートができるようになりました。
その方法を確認しましょう。
定数をインポート
定数をインポートするときは、use const
の後に先頭の \
を除いた完全修飾形式で定数名を記述します。
use const 完全修飾形式の定数名;
tokyo.php
に asia\japan\kanto\tokyo
という名前空間を定義します。
WOOD
定数を定義します。
<?php
namespace asia\japan\kanto\tokyo;
const WOOD = 'icho';
call.php
では、use const asia\japan\kanto\tokyo\WOOD;
として定数をインポートします。
<?php
require_once 'tokyo.php';
use const asia\japan\kanto\tokyo\WOOD;
echo WOOD;
実行するとicho
と表示されます。
PHP5.6.0より前のバージョンでは、関数と同様に名前空間をインポートする方法を利用すれば、短く記述することができます。
これでインポートとエイリアスを作成する方法について理解できたかと思います。
今までインポート・エイリアスは、同じファイルの同じ名前空間から利用しました。
別の名前空間から利用できるのか、別のファイルから利用できるのか有効範囲を確認しましょう。
インポート・エイリアスの有効範囲
use
キーワードを使ってインポートまたはエイリアスを作成したものが、どこから利用できるのか有効範囲を確認してみましょう。
インポート・エイリアスを利用する場合、下記のパターンが考えられます。
- 同ファイルの同じ名前空間からインポート・エイリアスを利用
- 同ファイルの別の名前空間からインポート・エイリアスを利用
- 別ファイルの同じ名前空間からインポート・エイリアスを利用
- 別ファイルの別の名前空間からインポート・エイリアスを利用
先ほどの例では、同ファイルの同じ名前空間内から利用できたので、最初のパターンは問題ありません。
他のパターンを確認しましょう。
同ファイルの別の名前空間からインポート・エイリアスを利用
tokyo.php
に名前空間を定義して、pref
クラスと bird
クラスを定義します。
<?php
namespace asia\japan\kanto\tokyo;
/* prefクラスの定義 */
class pref {
public function getPref() {
return 'tokyo';
}
}
/* birdクラスの定義 */
class bird {
public function getBird() {
return 'yurikamome';
}
}
call.php
では、a
という名前空間でインポートとエイリアスを作成します。
b
という別の名前空間からインポートとエイリアスを利用してみます。
<?php
namespace a {
require_once 'tokyo.php';
/* 名前空間のインポート */
use asia\japan\kanto;
/* birdクラスのエイリアスを作成 */
use asia\japan\kanto\tokyo\bird as tori;
}
namespace b {
require_once 'tokyo.php';
/* インポートを利用 */
$a = new kanto\tokyo\pref;
echo $a->getPref();
/* エイリアスを利用 */
$b = new tori;
echo $b->getBird();
}
実行すると、エラーが表示されました。
Fatal error: Class 'b\kanto\tokyo\pref' not found in C:\xampp\htdocs\call.php on line 20
pref
クラスが見つからないと書いてあります。
インポートが機能していません。
インポートを利用した時点でエラーが発生し、それ以降の処理はされていないので、上述したエラー内容だけでは、エイリアスを利用した場合の結果がわかりません。
エイリアスを利用した場合の結果も確かめましたが、同様にクラスが見つからないとのエラーが表示されました。
同ファイルの別の名前空間からインポート・エイリアスを利用できませんでした。
次のパターンも確認しましょう。
別ファイルの同じ名前空間からインポート・エイリアスを利用
tokyo.php
の記述は先ほどと同様です。
<?php
namespace asia\japan\kanto\tokyo;
/* prefクラスの定義 */
class pref {
public function getPref() {
return 'tokyo';
}
}
/* birdクラスの定義 */
class bird {
public function getBird() {
return 'yurikamome';
}
}
call.php
にはcall
という名前空間を定義します。
インポートとエイリアスを作成します。
<?php
namespace call;
require_once 'tokyo.php';
/* 名前空間のインポート */
use asia\japan\kanto;
/* birdクラスのエイリアスを作成 */
use asia\japan\kanto\tokyo\bird as tori;
call2.php
にはcall.php
と同じ名前空間を定義します。
call.php
でインポート、作成したエイリアスを call2.php
で利用してみます。
<?php
namespace call;
require_once 'tokyo.php';
require_once 'call.php';
/* インポートを利用 */
$a = new kanto\tokyo\pref;
echo $a->getPref();
/* エイリアスを利用 */
$b = new tori;
echo $b->getBird();
実行すると、エラーが表示されました。
Fatal error: Class 'call\kanto\tokyo\pref' not found in C:\xampp\htdocs\call2.php on line 9
先ほどと同様に pref
クラスが見つからないと書いてあります。
インポートが機能していません。
こちらも先ほどと同様に、エイリアスを利用した場合を確かめましたが、クラスが見つからないとのエラーが表示されました。
別ファイルの同じ名前空間からインポート・エイリアスを利用できませんでした。
次のパターンも確認しましょう。
別ファイルの別の名前空間からインポート・エイリアスを利用
tokyo.php
の記述は先ほどと同様です。
<?php
namespace asia\japan\kanto\tokyo;
/* prefクラスの定義 */
class pref {
public function getPref() {
return 'tokyo';
}
}
/* birdクラスの定義 */
class bird {
public function getBird() {
return 'yurikamome';
}
}
call.php
も先ほどと同様の記述です。
<?php
namespace call;
require_once 'tokyo.php';
/* 名前空間のインポート */
use asia\japan\kanto;
/* birdクラスのエイリアスを作成 */
use asia\japan\kanto\tokyo\bird as tori;
call2.php
には call.php
とは別の名前空間を定義します。
call.php
でインポート、作成したエイリアスを call2.php
で利用してみます。
<?php
namespace call2;
require_once 'tokyo.php';
require_once 'call.php';
/* インポートを利用 */
$a = new kanto\tokyo\pref;
echo $a->getPref();
/* エイリアスを利用 */
$b = new tori;
echo $b->getBird();
実行すると、エラーが表示されました。
Fatal error: Class 'call2\kanto\tokyo\pref' not found in C:\xampp\htdocs\call2.php on line 9
先ほどと同様に pref
クラスが見つからないと書いてあります。
インポートが機能していません。
こちらも先ほどと同様に、エイリアスを利用した場合を確かめましたが、クラスが見つからないとのエラーが表示されました。
別ファイルの別の名前空間からインポート・エイリアスを利用を利用できませんでした。
検証結果としては、インポート・エイリアスの有効範囲は、同ファイルの同じ名前空間のみでした。
同じ名前空間 | 別の名前空間 | |
---|---|---|
同じファイル | ○ | × |
別のファイル | × | × |
考えてみれば、別ファイルや他の名前空間のインポート・エイリアスが有効だった場合、どこでインポートされたのか、どこでエイリアスが作成されたのか、判別するのに苦労します。
同ファイルの同じ名前空間のみというのは、納得の有効範囲ですね。
定数を使うことで、現在の名前空間名を表示することができます。
最後にその方法を確認しましょう。
現在の名前空間名を表示する
__NAMESPACE__
定数を記述すると現在の名前空間名を表示してくれます。
確かめてみましょう。
<?php
namespace call;
echo __NAMESPACE__;
実行すると call
と現在の名前空間が表示されました。
これで名前空間について一通り理解できたかと思います。
最後に
今回の記事で超初心者の理解が少しでも深まれば幸いです。
最後まで読んでいただき、ありがとうございました。
PHP関連の記事をまとめていますので、気になるものがあればご覧ください。
超入門というのは徹底入門ではなく、初学者向けに一つ一つ冗長に説明している超入門記事という意味です。
- Qiita - 【PHP超入門】式・文・構文・言語構造・制御構造について
- Qiita - 【PHP超入門】値の代入と値渡しについて
- Qiita - 【PHP超入門】参照(リファレンス)の代入について
- Qiita - 【PHP超入門】HTTP(GET・POST)について
- Qiita - 【PHP超入門】Cookieとセッションについて
- Qiita - 【PHP超入門】クラス~例外処理~PDOの基礎
- Qiita - 【PHP超入門】名前空間(namespace・use)について
note
note でも記事を公開してるので、興味がある方はご覧ください。