名前空間(namespace)とは何か
PHPでアプリケーションが大きくなってくると、クラス名や関数名が衝突する問題が起きやすくなります。たとえば、自分が書いた Logger クラスと、外部ライブラリの Logger クラスが同じプロジェクトに混在するケースです。
名前空間(namespace) はこの問題を解決するための仕組みです。クラスや関数をグループ化し、名前の衝突を防げます。ちょうどファイルシステムのディレクトリのようなイメージです。
名前空間の基本的な書き方
名前空間はファイルの先頭で namespace キーワードを使って宣言します。
<?php
// src/Logger.php
namespace App\Util;
class Logger
{
public function log(string $message): void
{
echo "[LOG] " . $message . PHP_EOL;
}
}
別ファイルで同じ Logger というクラス名を使っても、名前空間が異なれば衝突しません。
<?php
// src/Database/Logger.php
namespace App\Database;
class Logger
{
public function log(string $message): void
{
echo "[DB LOG] " . $message . PHP_EOL;
}
}
この2つは App\Util\Logger と App\Database\Logger として区別されます。
useキーワードでインポートする
完全修飾名(FQCN: Fully Qualified Class Name)を毎回書くのは煩雑です。use キーワードを使うと短い名前でクラスを参照できます。
<?php
namespace App;
use App\Util\Logger;
use App\Database\Logger as DbLogger; // 名前が衝突するときはas でエイリアスを付ける
$utilLogger = new Logger();
$utilLogger->log("アプリケーション起動");
$dbLogger = new DbLogger();
$dbLogger->log("DB接続完了");
複数のクラスをまとめてuseする
PHP 7以降では、同じ名前空間のクラスをグループ化してインポートできます。
<?php
use App\Http\{Request, Response, Router};
すっきりと書けるので積極的に活用しましょう。
グローバル名前空間のクラスを使う
PHPの組み込みクラス(Exception や DateTime など)はグローバル名前空間に属しています。名前空間の内部からこれらを使う場合、バックスラッシュを前置するか use でインポートする必要があります。
<?php
namespace App\Service;
use Exception; // useでインポートする方法
class UserService
{
public function findUser(int $id): array
{
if ($id <= 0) {
throw new Exception("IDは正の整数である必要があります"); // useしたのでOK
}
// バックスラッシュで直接グローバルを参照する方法
$now = new \DateTime();
return ['id' => $id, 'created_at' => $now->format('Y-m-d')];
}
}
use でインポートしておく方がコードが読みやすくなるのでおすすめです。
Composerのオートローディングと名前空間を連携させる
名前空間の真価が発揮されるのは、Composerのオートローディングと組み合わせたときです。composer.json に次のように設定します。
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
この設定は「App\ で始まる名前空間は src/ ディレクトリと対応する」という意味です。PSR-4という標準規約に従っています。
設定後に次のコマンドを実行してオートローダーを生成します。
composer dump-autoload
ディレクトリ構造の例
project/
├── composer.json
├── src/
│ ├── Util/
│ │ └── Logger.php # namespace App\Util;
│ ├── Database/
│ │ └── Logger.php # namespace App\Database;
│ └── Service/
│ └── UserService.php # namespace App\Service;
└── index.php
エントリポイントでオートローダーを読み込む
<?php
// index.php
require_once __DIR__ . '/vendor/autoload.php';
use App\Util\Logger;
use App\Service\UserService;
$logger = new Logger();
$logger->log("起動しました");
$service = new UserService();
$user = $service->findUser(1);
$logger->log("ユーザー取得: ID=" . $user['id']);
require_once を一行書くだけで、src/ 以下のすべてのクラスを自動で読み込んでくれます。手動で require を並べる必要はありません。
よくある間違いと注意点
名前空間の区切りはバックスラッシュ
ディレクトリの区切りにスラッシュ(/)を使いがちですが、PHPの名前空間ではバックスラッシュ(\)を使います。
// NG
use App/Util/Logger;
// OK
use App\Util\Logger;
ファイルの先頭に宣言する
namespace 宣言はファイルの最初のステートメントでなければなりません(declare を除く)。HTMLを混在させるような書き方では動作しないので注意しましょう。
まとめ
| 項目 | 内容 |
|---|---|
namespace | クラスをグループ化して名前衝突を防ぐ |
use | 完全修飾名を短縮してインポートする |
as | インポート時にエイリアスを付ける |
| PSR-4 | 名前空間とディレクトリを対応させる規約 |
composer dump-autoload | オートローダーを再生成するコマンド |
名前空間はモダンなPHP開発において欠かせない基礎知識です。Composerのオートローディングと組み合わせることで、大規模なプロジェクトでも整理されたコードを維持できます。LaravelやSymfonyなどのフレームワークも内部でこの仕組みをフル活用しているので、ぜひ理解しておきましょう。