PHPの名前空間について

採用はこちら

PHPの名前空間とは、クラス名・関数名・定数名などの衝突を防ぐための仕組みです。

PHPでは、同じ名前のクラスや関数を同時に定義することはできません。

たとえば、自分のコードで User というクラスを作り、外部ライブラリにも User というクラスがある場合、名前が衝突してエラーの原因になります。

そこで名前空間を使い、次のようにクラスの所属を分けます。

namespace App\Models;

class User
{
}

この場合、クラス名は単なる User ではなく、正確には次の名前になります。

App\Models\User

つまり名前空間は、PHPのクラスや関数に「所属先」を与える仕組みです。

目次

名前空間が必要になる理由

クラス名や関数名の衝突を防ぐため

名前空間を使わない場合、すべてのクラスや関数は基本的にグローバル空間に置かれます。

たとえば、以下のようなクラスがあるとします。

class User
{
}

この User クラスは、どこかの名前空間に属していないため、グローバル空間に存在します。

しかし、別のファイルや外部ライブラリでも同じように User クラスが定義されていると、PHPはどちらを使えばよいのか判断できません。

class User
{
}

同じ実行環境内で同名のクラスが複数定義されると、エラーになります。

そこで、名前空間を使って次のように区別します。

namespace App\Models;

class User
{
}
namespace Admin\Models;

class User
{
}

この2つは、どちらもクラス名は User ですが、完全な名前は異なります。

App\Models\User
Admin\Models\User

そのため、同じ User という名前でも別々のクラスとして扱えます。

大規模開発や外部ライブラリ利用で重要になる

小さなPHPファイルを1つだけ書く場合は、名前空間を意識しなくても問題ないことがあります。

しかし、実務では次のような場面が多くあります。

複数人で開発する
外部ライブラリを使う
Composerを使う
Laravelなどのフレームワークを使う
WordPressプラグインを作る
クラス数が増える

このような環境では、名前の衝突を避けるために名前空間が重要になります。

たとえば、Laravelでは次のような名前空間がよく使われます。

App\Models
App\Http\Controllers
App\Services
App\Repositories

WordPressプラグインでも、モダンな書き方では次のような名前空間を使うことがあります。

MyPlugin\Admin
MyPlugin\Frontend
MyPlugin\Api

名前空間を使うことで、コードの所属や役割が分かりやすくなり、保守しやすい構造になります。

名前空間の基本的な書き方

namespace で所属を宣言する

名前空間は、PHPファイルの先頭付近で namespace キーワードを使って宣言します。

<?php

namespace App\Models;

class User
{
    public function getName(): string
    {
        return '山田太郎';
    }
}

この場合、User クラスは App\Models という名前空間に属します。

そのため、このクラスの完全な名前は次のようになります。

App\Models\User

namespace は実行コードより前に書く

namespace 宣言は、基本的にファイルの先頭付近に書きます。

正しい例は次のとおりです。

<?php

namespace App\Models;

class User
{
}

declare を使う場合は、declare の後に namespace を書けます。

<?php

declare(strict_types=1);

namespace App\Models;

class User
{
}

一方、次のように namespace の前に実行コードを書くことはできません。

<?php

echo 'Hello';

namespace App\Models;

class User
{
}

このように、echo などの処理を namespace より前に書くとエラーの原因になります。

コメントや空白は namespace の前に置ける

namespace の前に、コメントや空白を書くことは可能です。

<?php

// Userモデルを定義するファイルです。

namespace App\Models;

class User
{
}

ただし、HTML出力や echo、変数定義などの実行コードは置けません。

<html>
<?php

namespace App\Models;

class User
{
}

このようにPHPタグの外にHTMLがある場合も、出力が先にあるため注意が必要です。

名前空間の対象になるもの

クラスだけでなく関数や定数にも使える

名前空間の対象になるのは、クラスだけではありません。

主に以下の要素が名前空間の影響を受けます。

クラス
インターフェース
トレイト
Enum
関数
定数

たとえば、次のようにクラス・関数・定数を同じ名前空間内に定義できます。

<?php

namespace App\Helpers;

class Formatter
{
    public function format(): string
    {
        return 'formatted';
    }
}

function trimText(string $text): string
{
    return trim($text);
}

const DEFAULT_LENGTH = 100;

この場合、それぞれの完全な名前は次のようになります。

App\Helpers\Formatter
App\Helpers\trimText
App\Helpers\DEFAULT_LENGTH

名前空間はクラス整理だけの仕組みではない

名前空間というと、クラスを整理するためのものだと思われがちです。

もちろん、実務で最もよく使われるのはクラスの名前空間です。

しかし、関数や定数にも名前空間を付けられます。

たとえば、独自のヘルパー関数をまとめたい場合に、次のような名前空間を使えます。

namespace App\Helpers;

function formatPrice(int $price): string
{
    return number_format($price) . '円';
}

呼び出す側では、次のように完全な名前で呼び出せます。

echo \App\Helpers\formatPrice(1000);

完全修飾名とは

完全修飾名は「省略していない正式な名前」

名前空間を理解するうえで重要なのが、完全修飾名です。

たとえば、次のクラスがあるとします。

<?php

namespace App\Models;

class User
{
}

このクラスの完全な名前は、次のとおりです。

App\Models\User

さらに、グローバル空間から明示的に指定する場合は、先頭に \ を付けて次のように書きます。

\App\Models\User

これが完全修飾名です。

先頭の \ はグローバル空間からの指定

名前空間内でクラスを呼び出すとき、先頭に \ があるかどうかで意味が変わることがあります。

たとえば、現在の名前空間が App\Controllers の場合を考えます。

<?php

namespace App\Controllers;

$user = new App\Models\User();

この場合、PHPは次のような名前として解釈します。

App\Controllers\App\Models\User

つまり、現在の名前空間 App\Controllers を基準にしてしまいます。

もし本当に App\Models\User を使いたいなら、次のように先頭に \ を付けます。

$user = new \App\Models\User();

これにより、現在の名前空間を基準にせず、グローバル空間から見た App\Models\User を指定できます。

use によるインポート

use は長い名前を短く書くためのもの

名前空間付きのクラスを毎回フルで書くのは面倒です。

$user = new \App\Models\User();

そこで使うのが use です。

<?php

use App\Models\User;

$user = new User();

このように書くと、App\Models\User をこのファイル内では User という短い名前で使えます。

つまり、use は名前を短く書くためのインポートです。

use はファイルを読み込む命令ではない

ここは非常に重要です。

use はファイルを読み込む命令ではありません。

use App\Models\User;

これは、次のような意味です。

App\Models\User を User という短い名前で使います

一方で、以下のような意味ではありません。

App/Models/User.php を読み込みます

ファイルを読み込むのは、requireinclude、またはComposerのオートロードの役割です。

たとえば、次のコードだけではクラスファイルが読み込まれない場合があります。

<?php

use App\Models\User;

$user = new User();

Composerのオートロードを使うなら、通常は次のように vendor/autoload.php を読み込みます。

require __DIR__ . '/vendor/autoload.php';

つまり、役割を分けると次のようになります。

namespace = 自分の所属を決める
use = 名前を短く使う
autoload = ファイルを自動で読み込む
require / include = ファイルを明示的に読み込む

as による別名指定

同じクラス名を使いたいときに便利

同じ名前のクラスを複数使いたい場合は、as を使って別名を付けます。

たとえば、以下の2つのクラスがあるとします。

App\Models\User
Admin\Models\User

どちらもクラス名は User です。

このまま両方をインポートしようとすると、名前が衝突します。

use App\Models\User;
use Admin\Models\User;

このような場合は、as を使います。

<?php

use App\Models\User as FrontUser;
use Admin\Models\User as AdminUser;

$frontUser = new FrontUser();
$adminUser = new AdminUser();

これで、同じ User というクラス名でも区別できます。

実務でよくある別名の付け方

実務では、次のようにモデルとリソース、モデルとDTOなどで名前が重なることがあります。

use App\Models\User as UserModel;
use App\Http\Resources\User as UserResource;

このように別名を付けると、コード上で何を扱っているのか分かりやすくなります。

$user = new UserModel();
$resource = new UserResource($user);

別名は、単に衝突を避けるだけでなく、コードの意味を明確にする目的でも使えます。

現在の名前空間内での名前解決

new User() は現在の名前空間を基準に解釈される

名前空間内でクラス名を短く書いた場合、PHPは現在の名前空間を基準に解釈します。

たとえば、次のコードを見てください。

<?php

namespace App\Controllers;

class UserController
{
    public function show(): void
    {
        $user = new User();
    }
}

この場合、new User() は基本的に次のクラスを指します。

App\Controllers\User

つまり、App\Models\User ではありません。

App\Models\User を使いたい場合は、次のように use を書きます。

<?php

namespace App\Controllers;

use App\Models\User;

class UserController
{
    public function show(): void
    {
        $user = new User();
    }
}

または、完全修飾名で直接書きます。

<?php

namespace App\Controllers;

class UserController
{
    public function show(): void
    {
        $user = new \App\Models\User();
    }
}

実務では、可読性を考えて use を使うことが多いです。

グローバル名前空間とは

名前空間を宣言していない場所はグローバル空間

名前空間を宣言していないコードは、グローバル名前空間に属します。

<?php

class User
{
}

この User は、グローバル空間の User です。

名前空間内からグローバル空間のクラスを使いたい場合は、先頭に \ を付けます。

<?php

namespace App\Services;

class ErrorHandler
{
    public function handle(): void
    {
        throw new \Exception('エラーが発生しました');
    }
}

標準クラスを使うときは注意する

名前空間内で次のように書くと、PHPは現在の名前空間内の Exception を探します。

<?php

namespace App\Services;

throw new Exception('エラー');

この場合、PHPは次のクラスを探そうとします。

App\Services\Exception

標準の Exception を使いたい場合は、次のように書くと安全です。

throw new \Exception('エラー');

または、use を使います。

<?php

namespace App\Services;

use Exception;

throw new Exception('エラー');

DateTimePDO など、PHP標準のクラスを使う場合も同じです。

$date = new \DateTime();

または、

use DateTime;

$date = new DateTime();

と書けます。

関数と定数の名前空間

関数は use function でインポートする

名前空間付きの関数を短く使いたい場合は、use function を使います。

まず、関数を定義する側です。

<?php

namespace App\Helpers;

function formatPrice(int $price): string
{
    return number_format($price) . '円';
}

呼び出す側では、完全修飾名で次のように書けます。

echo \App\Helpers\formatPrice(1000);

短く書きたい場合は、次のように use function を使います。

<?php

use function App\Helpers\formatPrice;

echo formatPrice(1000);

定数は use const でインポートする

定数も名前空間の対象になります。

<?php

namespace App\Helpers;

const TAX_RATE = 0.1;

完全修飾名で呼び出す場合は、次のように書きます。

echo \App\Helpers\TAX_RATE;

短く使いたい場合は、use const を使います。

<?php

use const App\Helpers\TAX_RATE;

echo TAX_RATE;

クラス・関数・定数の use は、それぞれ書き方が違います。

use App\Models\User;
use function App\Helpers\formatPrice;
use const App\Helpers\TAX_RATE;

クラス・関数・定数の名前解決の違い

クラスはグローバル空間へ自動フォールバックしない

名前空間内でクラス名を書いた場合、PHPは現在の名前空間を基準に解釈します。

<?php

namespace App;

$date = new DateTime();

この場合、PHPは基本的に次のクラスを探します。

App\DateTime

グローバル空間の DateTime を使いたい場合は、次のように書きます。

$date = new \DateTime();

または、

use DateTime;

$date = new DateTime();

と書きます。

関数と定数はグローバル空間へフォールバックする

一方で、関数や定数は少し挙動が異なります。

<?php

namespace App;

echo strlen('hello');

この場合、PHPはまず App\strlen() を探します。

もし App\strlen() が存在しなければ、グローバル関数の strlen() を呼び出します。

つまり、関数はグローバル空間へフォールバックします。

定数も同様に、名前空間内に該当する定数がなければ、グローバル定数を探します。

ただし、実務では意図を明確にするために、グローバル関数を明示して次のように書くこともあります。

echo \strlen('hello');

特にライブラリ開発では、次のような書き方を見かけることがあります。

\count($items);
\is_array($value);
\strlen($text);

サブ名前空間とは

名前空間は階層的に書ける

名前空間は、次のように階層的に書けます。

namespace App\Http\Controllers;

これは、App の中の Http の中の Controllers のように見える構造です。

たとえば、Laravelでは以下のような名前空間がよく使われます。

App\Models
App\Http\Controllers
App\Http\Requests
App\Services
App\Repositories

WordPressプラグインでも、次のように役割ごとに分けることがあります。

MyPlugin\Admin
MyPlugin\Frontend
MyPlugin\Api
MyPlugin\Shortcodes

名前空間はフォルダそのものではない

名前空間は、見た目としてはフォルダ構造に似ています。

しかし、厳密には名前空間とディレクトリは別物です。

たとえば、次のクラスがあります。

<?php

namespace Foo\Bar;

class User
{
}

このクラスが必ず次の場所に置かれていなければならない、というわけではありません。

Foo/Bar/User.php

PHPの言語仕様上、名前空間はあくまで論理的な名前の分類です。

ただし、ComposerのPSR-4オートロードを使う場合は、名前空間とディレクトリ構造を対応させるのが一般的です。

Composerのオートロードとの関係

名前空間とautoloadは別物

名前空間を実務で使うとき、ほぼ必ず関係するのがComposerのオートロードです。

ただし、名前空間とオートロードは同じものではありません。

名前空間 = クラスの論理的な名前
autoload = クラス名からファイルを探して読み込む仕組み

たとえば、composer.json に次のように書いたとします。

{
  "autoload": {
    "psr-4": {
      "App\\": "src/"
    }
  }
}

これは、次の意味です。

App\ で始まるクラスは src/ ディレクトリ以下にある

たとえば、次のクラスがあるとします。

App\Models\User

Composerは通常、次のファイルを探します。

src/Models/User.php

Composerを使った構成例

プロジェクト構成は次のようになります。

project/
├─ composer.json
├─ public/
│  └─ index.php
├─ src/
│  └─ Models/
│     └─ User.php
└─ vendor/

composer.json

{
  "autoload": {
    "psr-4": {
      "App\\": "src/"
    }
  }
}

src/Models/User.php

<?php

namespace App\Models;

class User
{
    public function getName(): string
    {
        return '山田太郎';
    }
}

public/index.php

<?php

require __DIR__ . '/../vendor/autoload.php';

use App\Models\User;

$user = new User();

echo $user->getName();

ここで重要なのは、次の1行です。

require __DIR__ . '/../vendor/autoload.php';

この記述によって、Composerのオートローダーが有効になります。

そのうえで、use App\Models\User; によって、App\Models\UserUser と短く書けるようになります。

PSR-4と名前空間

PSR-4では名前空間とディレクトリを対応させる

現代的なPHP開発では、ComposerのPSR-4オートロードを使うことが多いです。

PSR-4では、名前空間とディレクトリ構造を対応させます。

たとえば、以下のような対応です。

App\Models\User
src/Models/User.php
App\Services\MailService
src/Services/MailService.php
App\Http\Controllers\HomeController
src/Http/Controllers/HomeController.php

この対応関係によって、Composerはクラス名からファイルの場所を推測できます。

composer dump-autoload が必要な場合もある

composer.json のautoload設定を変更した場合は、次のコマンドが必要になることがあります。

composer dump-autoload

特に、autoload設定を新しく追加したときや、クラスマップを更新したいときに使います。

名前空間やファイルパスが正しいのに Class not found が出る場合は、autoload設定や composer dump-autoload を確認するとよいです。

Laravelでの名前空間の例

Laravelでは名前空間が多用される

Laravelでは、ほぼすべてのクラスで名前空間が使われます。

たとえば、コントローラーは次のようになります。

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function show(int $id)
    {
        $post = Post::findOrFail($id);

        return view('posts.show', [
            'post' => $post,
        ]);
    }
}

このコードでは、

namespace App\Http\Controllers;

によって、PostControllerApp\Http\Controllers に属していることを示しています。

また、

use App\Models\Post;

によって、App\Models\PostPost と短く書けるようにしています。

さらに、

use Illuminate\Http\Request;

によって、Laravelが提供する Request クラスを使えるようにしています。

namespaceuse を読むと依存関係が分かる

Laravelのファイルを読むときは、まず上部の namespaceuse を見ると理解しやすくなります。

namespace App\Http\Controllers;

use App\Models\Post;
use App\Services\PostService;
use Illuminate\Http\Request;

これを見るだけで、次のことが分かります。

このクラスは App\Http\Controllers に所属している
Postモデルを使っている
PostServiceを使っている
LaravelのRequestを使っている

ファイル上部の namespaceuse は、そのクラスの立ち位置と依存関係を把握するための重要な情報です。

WordPressでの名前空間の使い方

WordPressでは関数名の衝突に注意する

WordPressでは、テーマやプラグインが同じ環境で動作します。

そのため、名前空間を使わない場合は、関数名の衝突を避けるために接頭辞を付けることがよくあります。

function my_plugin_register_post_type()
{
}

これは、他のテーマやプラグインの関数と名前が重ならないようにするためです。

モダンなWordPress開発では、名前空間を使って整理することもあります。

<?php

namespace MyPlugin\PostTypes;

function registerBookPostType(): void
{
    register_post_type('book', [
        'label' => 'Books',
        'public' => true,
    ]);
}

WordPressのフックでは名前空間付き関数名を明示する

WordPressで名前空間を使う場合、add_action()add_filter() のコールバック指定に注意が必要です。

たとえば、次のように名前空間内で関数を定義します。

<?php

namespace MyPlugin;

function setup(): void
{
    // 初期化処理
}

この関数の完全な名前は次のとおりです。

MyPlugin\setup

そのため、フックに登録する場合は次のように書きます。

add_action('init', 'MyPlugin\setup');

または、__NAMESPACE__ を使って次のように書けます。

add_action('init', __NAMESPACE__ . '\setup');

注意したいのは、名前空間内だからといって、次のように書いても自動的に MyPlugin\setup にはならないことです。

namespace MyPlugin;

add_action('init', 'setup');

この場合、文字列として 'setup' を渡しているだけです。

WordPress側は通常、グローバル関数の setup を探すような形になるため、意図通りに動かないことがあります。

クラスメソッドをフックに登録する場合

インスタンスメソッドをフックに登録する場合は、次のように書けます。

<?php

namespace MyPlugin\Admin;

class SettingsPage
{
    public function register(): void
    {
        add_options_page(
            'My Plugin',
            'My Plugin',
            'manage_options',
            'my-plugin',
            [$this, 'render']
        );
    }

    public function render(): void
    {
        echo '<h1>My Plugin</h1>';
    }
}

静的メソッドを登録する場合は、次のように書けます。

add_action('init', [\MyPlugin\Setup::class, 'init']);

WordPressで名前空間を使う場合は、特に文字列コールバックの扱いに注意が必要です。

namespaceuse の違い

namespace は自分の所属を決める

namespace は、そのファイルで定義するクラスや関数の所属を決めます。

namespace App\Controllers;

class UserController
{
}

この場合、UserController の完全な名前は次のようになります。

App\Controllers\UserController

つまり、namespace は「自分がどこに所属するか」を決めるものです。

use は他の名前を短く使う

一方、use は別の名前空間のクラスなどを短く書くためのものです。

use App\Models\User;

これは、App\Models\User をこのファイル内で User と書けるようにする宣言です。

まとめると、次のようになります。

namespace = 自分の所属
use = 他のクラスや関数を短く使うための指定

例を見ると分かりやすいです。

<?php

namespace App\Controllers;

use App\Models\User;

class UserController
{
    public function show(): void
    {
        $user = new User();
    }
}

このコードは、次のように読めます。

UserControllerはApp\Controllersに所属する
App\Models\UserをUserという名前で使う

__NAMESPACE__ とは

現在の名前空間を文字列で取得できる

__NAMESPACE__ は、現在の名前空間名を表すマジック定数です。

<?php

namespace MyPlugin\Admin;

echo __NAMESPACE__;

この場合、出力は次のようになります。

MyPlugin\Admin

WordPressのフック登録で便利

__NAMESPACE__ は、WordPressのフック登録などで便利です。

<?php

namespace MyPlugin;

function setup(): void
{
    // 初期化処理
}

add_action('init', __NAMESPACE__ . '\setup');

このように書くと、現在の名前空間と関数名を結合して、正しいコールバック名を作れます。

名前空間名を変更した場合でも、修正箇所を減らせるというメリットがあります。

namespace\ キーワードとは

現在の名前空間を基準に呼び出す書き方

PHPには、namespace\ という書き方もあります。

<?php

namespace App\Helpers;

function format(): string
{
    return 'format';
}

echo namespace\format();

この場合、次の関数を呼び出していることになります。

App\Helpers\format()

つまり、namespace\ は「現在の名前空間を基準にする」という意味です。

ただし、実務では namespace\ よりも、use や完全修飾名を使うことの方が多いです。

複数の名前空間を1ファイルに書けるか

PHPの仕様上は可能

PHPでは、1つのファイルに複数の名前空間を書くこともできます。

<?php

namespace App\Models;

class User
{
}

namespace App\Services;

class UserService
{
}

また、波括弧を使って書くこともできます。

<?php

namespace App\Models {
    class User
    {
    }
}

namespace App\Services {
    class UserService
    {
    }
}

実務では1ファイル1クラスが基本

仕様上は複数の名前空間を書けますが、実務ではあまりおすすめされません。

理由は、可読性や保守性が下がるためです。

ComposerのPSR-4オートロードを使う場合も、基本的には次のような構成が分かりやすいです。

1ファイル = 1クラス
名前空間 = ディレクトリ構造に対応

たとえば、

App\Models\User

であれば、

src/Models/User.php

に置くような形です。

use キーワードの複数の意味

名前空間の use

名前空間における use は、クラスや関数などをインポートするために使います。

use App\Models\User;

これは、App\Models\UserUser と短く書くためのものです。

トレイトの use

PHPでは、トレイトを使うときにも use を使います。

class User
{
    use HasProfile;
}

この use は、名前空間のインポートではありません。

クラスの中でトレイトを取り込むためのものです。

クロージャの use

クロージャでも use が使われます。

$name = '山田';

$fn = function () use ($name) {
    echo $name;
};

この use は、外側の変数をクロージャ内で使うためのものです。

同じ use というキーワードでも、文脈によって意味が違います。

ファイル上部の use = 名前空間のインポート
クラス内の use = トレイトの利用
クロージャの use = 外側の変数を取り込む

実務でよくある構成例

小規模なPHPアプリの例

小さなPHPアプリでも、名前空間を使うとコードを整理しやすくなります。

project/
├─ composer.json
├─ public/
│  └─ index.php
├─ src/
│  ├─ Controllers/
│  │  └─ HomeController.php
│  ├─ Models/
│  │  └─ User.php
│  └─ Services/
│     └─ MailService.php
└─ vendor/

composer.json

{
  "autoload": {
    "psr-4": {
      "App\\": "src/"
    }
  }
}

src/Models/User.php

<?php

namespace App\Models;

class User
{
    public function __construct(
        private string $name
    ) {
    }

    public function getName(): string
    {
        return $this->name;
    }
}

src/Services/MailService.php

<?php

namespace App\Services;

use App\Models\User;

class MailService
{
    public function sendWelcomeMail(User $user): void
    {
        echo $user->getName() . 'さんにメールを送信しました。';
    }
}

src/Controllers/HomeController.php

<?php

namespace App\Controllers;

use App\Models\User;
use App\Services\MailService;

class HomeController
{
    public function index(): void
    {
        $user = new User('山田太郎');

        $mailService = new MailService();
        $mailService->sendWelcomeMail($user);
    }
}

public/index.php

<?php

require __DIR__ . '/../vendor/autoload.php';

use App\Controllers\HomeController;

$controller = new HomeController();
$controller->index();

このように、名前空間を使うと、モデル・サービス・コントローラーなどの役割を整理しやすくなります。

よくあるエラーと対処法

Class not found が出る

名前空間まわりでよくあるエラーが、Class not found です。

Fatal error: Uncaught Error: Class "App\Models\User" not found

主な原因は以下です。

namespace の指定が間違っている
use の指定が間違っている
ファイルパスがPSR-4の規則と一致していない
vendor/autoload.php を読み込んでいない
composer dump-autoload を実行していない
クラス名とファイル名の大文字小文字が一致していない

たとえば、クラス側が次のようになっているとします。

namespace App\Model;

しかし、呼び出し側で次のように書いていると、名前が一致しません。

use App\Models\User;

ModelModels が違うため、クラスが見つからない原因になります。

use を書いたのに読み込まれない

次のように use を書いても、

use App\Models\User;

クラスファイルが読み込まれるわけではありません。

use は名前を短くするだけです。

Composerを使っているなら、通常は次の読み込みが必要です。

require __DIR__ . '/vendor/autoload.php';

また、autoload設定を変更した場合は、次のコマンドも確認します。

composer dump-autoload

標準クラスが見つからない

名前空間内で次のように書くと、意図しないエラーになることがあります。

<?php

namespace App;

$date = new DateTime();

この場合、PHPは App\DateTime を探します。

標準の DateTime を使いたい場合は、次のように書きます。

$date = new \DateTime();

または、

use DateTime;

$date = new DateTime();

とします。

名前空間の命名ルール

プロジェクト名やベンダー名を使う

名前空間には、プロジェクト名やベンダー名を使うのが一般的です。

ライブラリなら、次のような形です。

VendorName\PackageName

アプリケーションなら、次のように App を使うことが多いです。

App\Models
App\Services
App\Controllers

WordPressプラグインなら、プラグイン名を使うと分かりやすくなります。

MyPlugin\Admin
MyPlugin\Frontend
MyPlugin\Api

役割ごとに名前空間を分ける

実務では、役割ごとに名前空間を分けると管理しやすくなります。

App\Models          データやDBに関するクラス
App\Controllers     リクエストを受けるクラス
App\Services        ビジネスロジック
App\Repositories    データ取得や保存処理
App\Http\Requests   入力検証用クラス
App\Helpers         補助関数や補助クラス

名前空間を整理すると、ファイル上部を見ただけで、そのクラスの役割や位置づけが分かりやすくなります。

名前空間を使うメリット

名前の衝突を避けられる

最大のメリットは、同じ名前のクラスや関数を安全に扱えることです。

App\Models\User
Admin\Models\User
Vendor\Package\User

このように、同じ User という名前でも、名前空間が違えば別のクラスとして扱えます。

コードの構造が分かりやすくなる

名前空間を使うと、クラスがどの役割に属しているのか分かりやすくなります。

App\Http\Controllers\PostController
App\Models\Post
App\Services\PostService

このように名前を見るだけで、クラスの役割をある程度推測できます。

Composerと相性がよい

ComposerのPSR-4オートロードを使うと、名前空間からファイルを自動的に読み込めます。

これにより、毎回 require を書く必要が少なくなります。

require __DIR__ . '/../vendor/autoload.php';

この1行を読み込んでおけば、Composerが必要なクラスファイルを自動で探してくれます。

名前空間を使うときの注意点

use とautoloadを混同しない

名前空間まわりで最も多い誤解が、use とautoloadの混同です。

use App\Models\User;

これはファイル読み込みではありません。

ファイルを読み込むには、Composerのautoloadや require が必要です。

先頭の \ の有無に注意する

名前空間内では、先頭に \ があるかどうかで意味が変わります。

new App\Models\User();

new \App\Models\User();

は、名前空間内では同じ意味にならない場合があります。

ルートから完全な名前で指定したい場合は、先頭に \ を付けます。

WordPressでは文字列コールバックに注意する

WordPressで名前空間付き関数をフックに登録する場合は、関数名を明示する必要があります。

add_action('init', __NAMESPACE__ . '\setup');

名前空間内だからといって、文字列 'setup' が自動的に MyPlugin\setup に変換されるわけではありません。

PHPの名前空間で覚えるべきポイント

namespace は自分の所属

namespace App\Models;

これは、このファイルで定義するクラスや関数が App\Models に属することを示します。

use は名前を短くする

use App\Models\User;

これは、App\Models\UserUser と短く書けるようにするものです。

autoload はファイルを読み込む

Composerを使う場合は、次のようにautoloadを読み込みます。

require __DIR__ . '/vendor/autoload.php';

このautoloadによって、必要なクラスファイルが自動で読み込まれます。

まとめ

PHPの名前空間は、クラス・関数・定数などの名前の衝突を防ぎ、コードを整理しやすくするための仕組みです。

特に重要なのは、次の3つの違いです。

namespace = 自分の所属を決める
use = 他の名前空間の名前を短く使う
autoload = ファイルを読み込む

名前空間を使えば、同じ User というクラス名でも、

App\Models\User
Admin\Models\User
Vendor\Package\User

のように区別できます。

また、ComposerのPSR-4オートロードと組み合わせることで、名前空間とディレクトリ構造を対応させ、クラスファイルを自動で読み込めるようになります。

一方で、次の点には注意が必要です。

use はファイル読み込みではない
名前空間内のクラスはグローバル空間へ自動フォールバックしない
関数と定数はグローバル空間へフォールバックする
WordPressの文字列コールバックでは名前空間付きの関数名を明示する
名前空間はフォルダに似ているが、厳密にはディレクトリそのものではない

PHPの名前空間は、最初は少し分かりにくいですが、Laravel、Composer、WordPressプラグイン開発、外部ライブラリ利用では非常に重要です。

特に実務では、namespaceuse・autoloadの違いを理解しておくことで、Class not found などのエラー原因を見つけやすくなります。

以上、PHPの名前空間についてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次