あっぽログ
← 記事一覧に戻る

PHPの名前空間を完全理解する:namespace・use・オートローディングの基本から実践まで

名前空間(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\LoggerApp\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の組み込みクラス(ExceptionDateTime など)はグローバル名前空間に属しています。名前空間の内部からこれらを使う場合、バックスラッシュを前置するか 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などのフレームワークも内部でこの仕組みをフル活用しているので、ぜひ理解しておきましょう。

← 記事一覧に戻る