【PHP】namespace(名前空間)、use の解説
はじめに
PHPの「namespace(名前空間)」と「use」について解説します。
学習するPHP機能
namespace
// 例: namespace {名前空間};
namespace App\Models;
// \App\Models\Admin クラス
class Admin {}
use
// 例: use {完全修飾名(先頭「\」は除く)} as {別名};
use App\Models\Admin as AdminModel; // 別名: AdminModel
// 例: use {完全修飾名(先頭「\」は除く)};
use App\Models\Admin; // 別名: Admin
学習の事前準備
以下について理解している前提で進みます。
- PHP
-
クラスの基礎
- クラス
- メソッド
-
クラスの基礎
PHPの名前空間とは
名前空間(namespace)とは、コード内で重複するクラス・関数を区別するための機能です。
まずは、名前空間を使わない場合について見ていきます。
例えばフレームワークなどで、既にStr
というクラスが定義されている場合、
別途、自分でStr
クラスを定義しようとすると、クラス名が重複するためエラーが発生します。
コード例
class Str{} // \Str クラス
class Arr{} // \Arr クラス
class Str{} // \Str クラス
// PHP Fatal error: Cannot declare class Str, because the name is already in use
// (名前がすでに使用されているため、クラスStrを宣言することができません。)
これを解決するのが名前空間(namespace)です。
ファイルシステムで例えると、クラスがファイル、名前空間がフォルダの役割になります。
コード例
namespace Illuminate\Support;
class Str{} // \Illuminate\Support\Str クラス
class Arr{} // \Illuminate\Support\Arr クラス
namespace My;
class Str{} // \My\Str クラス
// 完全修飾名(名前空間+クラス名)が重複しないためエラーにならない
完全修飾名
完全修飾名(かんぜんしゅうしょくめい)は、絶対パスのイメージで\
から始まり、名前空間とクラス名を\
区切りで連結した名称です。
名前空間を含めた完全名称(フルパス)を指すもので、同名のクラス名があった場合でも、完全修飾名が異なれば利用が可能になります。
例えば以下の6つのクラスは共存が可能です。
名前空間 (namespace) |
クラス名 (class) |
完全修飾名 ( \{名前空間}\{クラス名} ) |
---|---|---|
Illuminate\Support |
Str |
\Illuminate\Support\Str |
Illuminate\Support |
Arr |
\Illuminate\Support\Arr |
App |
Str |
\App\Str |
App |
Arr |
\App\Arr |
なし | Str |
\Str |
なし | Arr |
\Arr |
イメージ
コード
<?php
namespace Illuminate\Support;
class Str {}
class Arr {}
<?php
namespace App;
class Str {}
class Arr {}
<?php
class Str {}
class Arr {}
use
useはクラスや関数にエイリアス(別名)をつける機能です。
useを使う例、使わない例で見ていきましょう。
まずは、以下のStrクラスをStringUtilsクラスで使用してみましょう。
- 名前空間:
Illuminate\Support
- クラス名:
Str
- 完全修飾名:
\Illuminate\Support\Str
- StringUtilsクラスで使用するメソッド:
upper
コード
<?php
namespace Illuminate\Support;
class Str
{
public static function upper(string $value): string
{
return mb_strtoupper($value, 'UTF-8');
}
}
<?php
namespace App\Utils;
class StringUtils
{
public static function upperCase(string $value): string
{
// TODO: \Illuminate\Support\Strクラスのupperメソッドの結果を返す。
}
}
useを使わない例
以下のように完全修飾名でクラスを使用します。
\Illuminate\Support\Str
StringUtilsクラスでの使用例
<?php
namespace App\Utils;
class StringUtils
{
public static function upperCase(string $value): string
{
- // TODO: \Illuminate\Support\Strクラスのupperメソッドの結果を返す。
+ return \Illuminate\Support\Str::upper($value);
}
}
useを使う例1
以下のようにuseでエイリアス(別名)を作成し、クラスを使用します。
ここではIlluminateSupportStr
という名前で、クラス参照ができるようにします。
use
〜as
間には、完全修飾名を入れますが先頭の「\
」は除きましょう。
use Illuminate\Support\Str as IlluminateSupportStr;
IlluminateSupportStr
StringUtilsクラスでの使用例
<?php
namespace App\Utils;
+use Illuminate\Support\Str as IlluminateSupportStr;
+
class StringUtils
{
public static function upperCase(string $value): string
{
- return \Illuminate\Support\Str::upper($value);
+ return IlluminateSupportStr::upper($value);
}
}
useを使う例2
as {別名}
を省略すると、完全修飾名の末端の名称(クラス名)が別名として扱われます。
これが一般的な使い方になり、PHPマニュアルでは「インポート」と呼びます。
use Illuminate\Support\Str; // 『use Illuminate\Support\Str as Str』 と同じ
Str
StringUtilsクラスでの使用例
<?php
namespace App\Utils;
-use Illuminate\Support\Str as IlluminateSupportStr;
+use Illuminate\Support\Str;
class StringUtils
{
public static function upperCase(string $value): string
{
- return IlluminateSupportStr::upper($value);
+ return Str::upper($value);
}
}
標準クラスを使用する
名前空間を設定した場合に注意が必要なのが
「Exception
」、「DateTime
」等のPHP標準クラスを使用する場合です。
例えば namespace App
を設定したコードで「Exception
」クラスを使用する際に
そのままの名称で使用すると「Class "App\Exception" not found
」とエラーになります。
使用側のクラスが名前空間に属していた場合、そこからの相対パスとなってしまうため
存在しない\App\Exception
クラスを参照していることになります。
PHP標準クラスは名前空間なしで直接定義されているため、useするか、完全修飾名で参照する必要があります。
// 完全修飾名
$e = new \Exception();
// use を使用
use Exception;
$e = new Exception();
サンプルコード
エラーケース
<?php
namespace App;
class A
{
public static function run()
{
$e = new Exception(); // PHP Fatal error: Uncaught Error: Class "App\Exception" not found
}
}
A::run();
echo '正常終了';
完全修飾名のケース
<?php
namespace App;
class A
{
public static function run()
{
- $e = new Exception();
+ $e = new \Exception();
}
}
A::run();
echo '正常終了';
use のケース
<?php
namespace App;
+use Exception;
+
class A
{
public static function run()
{
$e = new Exception();
}
}
A::run();
echo '正常終了';
課題
課題1
課題
<?php
namespace Carbon;
class Carbon
{
}
<?php
namespace App\Http\Controllers;
use XXXX; // ← ここにに入れる名称を答えなさい。
class HomeController
{
public function run()
{
$now = new Carbon(); // 定義したクラスを使用
}
}
解答
定義したクラスが、名前空間「Carbon
」、クラス名「Carbon
」のため
完全修飾名が「\Carbon\Carbon
」になり
useを使用する場合、先頭の「\
」を除くため
「Carbon\Carbon
」が解答となる。
<?php
namespace App\Http\Controllers;
-use XXXX; // ← ここにに入れる名称を答えなさい。
+use Carbon\Carbon;
class HomeController
{
public function run()
{
$now = new Carbon(); // 定義したクラスを使用
}
}
課題2
課題
解答
課題3
課題
解答
使用側のクラスであるDatabaseSeeder
クラスには、名前空間 Database\Seeders
が設定されており
クラス使用時はAdminSeeder
と記述しており、相対参照のため完全修飾名は\Database\Seeders\AdminSeeder
となる
最後に
今回、解説したのは最低限の部分のみで、
特にuseに関しては、関数や定数のエイリアス/インポートを行うこともできます。
詳細についてはPHPマニュアルなどを参照してください。
参考
関連書籍
Discussion