コンテンツにスキップ

PHP/名前空間

出典: フリー教科書『ウィキブックス(Wikibooks)』
< PHP

名前空間の基本概念

[編集]

名前空間は、PHPで大規模なアプリケーションを開発する際に不可欠な機能です。異なるライブラリやコードベース間での名前の衝突を防ぎ、コードの整理と管理を容易にします。

以下のような状況を考えてみましょう:

app/Database/Connection.php
<?php
namespace App\Database;

class Connection 
{
    public function connect() 
    {
        return "データベース接続を確立しました";
    }
}
app/Network/Connection.php
<?php
namespace App\Network;

class Connection 
{
    public function connect() 
    {
        return "ネットワーク接続を確立しました";
    }
}

この例では、同じConnectionという名前のクラスを、異なる目的のために定義しています。名前空間を使用することで、これらのクラスは互いに干渉することなく共存できます。

名前空間の定義と使用

[編集]

名前空間は、PHPファイルの先頭で宣言する必要があります。ただし、declare文がある場合は、その後に記述します:

<?php
declare(strict_types=1);

namespace MyApp\Services;

class UserService 
{
    public function createUser(string $name) 
    {
        return "ユーザー {$name} を作成しました";
    }
}

名前空間の階層構造

[編集]

名前空間は、ディレクトリ構造に似た階層を持つことができます:

<?php
namespace App\Services\User\Authentication;

class LoginService 
{
    public function authenticate(string $username, string $password) 
    {
        // 認証ロジック
        return true;
    }
}

名前空間内のクラスの使用

[編集]

他の名前空間のクラスを使用する方法には、主に3つのアプローチがあります:

完全修飾名(FQCN)の使用

[編集]
<?php
namespace App\Controllers;

class UserController 
{
    public function login() 
    {
        $service = new \App\Services\User\Authentication\LoginService();
        $result = $service->authenticate('username', 'password');
        return $result;
    }
}

use文による名前空間のインポート

[編集]
<?php
namespace App\Controllers;

use App\Services\User\Authentication\LoginService;
use App\Models\User;
use App\Database\Connection;

class UserController 
{
    private LoginService $loginService;
    private Connection $db;

    public function __construct() 
    {
        $this->loginService = new LoginService();
        $this->db = new Connection();
    }
}

エイリアスの使用

[編集]
<?php
namespace App\Controllers;

use App\Services\User\Authentication\LoginService as AuthService;
use App\Models\User as UserModel;

class UserController 
{
    public function register() 
    {
        $auth = new AuthService();
        $user = new UserModel();
    }
}

グローバル名前空間

[編集]

名前空間を指定しない場合、そのコードはグローバル名前空間に属します。また、バックスラッシュを使用してグローバル名前空間の要素を参照できます:

<?php
namespace App\Services;

class FileService 
{
    public function readFile(string $path) 
    {
        // グローバル関数の使用
        return \file_get_contents($path);
    }
    
    public function getDateTime() 
    {
        // グローバルクラスの使用
        return new \DateTime();
    }
}

名前空間と関数・定数

[編集]

名前空間は、クラスだけでなく関数や定数にも適用できます:

<?php
namespace App\Utilities;

const APP_VERSION = '1.0.0';

function formatCurrency(float $amount): string 
{
    return "¥" . number_format($amount);
}

class StringHelper 
{
    public static function truncate(string $text, int $length): string 
    {
        return mb_substr($text, 0, $length) . '...';
    }
}

// 別のファイルでの使用
namespace App\Controllers;

use App\Utilities;

class ProductController 
{
    public function getProductInfo() 
    {
        $price = Utilities\formatCurrency(1000);
        $version = Utilities\APP_VERSION;
        return "製品価格: {$price} (v{$version})";
    }
}

複数の名前空間のインポート

[編集]

大規模なアプリケーションでは、多くの名前空間をインポートする必要があることがあります。この場合、グループ化して記述できます:

<?php
namespace App\Controllers;

use App\Models\{
    User,
    Product,
    Order,
    Payment
};
use App\Services\{
    UserService,
    PaymentService
};
use App\Exceptions\{
    ValidationException,
    DatabaseException
};

class OrderController 
{
    public function createOrder() 
    {
        $user = new User();
        $product = new Product();
        $order = new Order();
        $payment = new Payment();
        
        try {
            $userService = new UserService();
            $paymentService = new PaymentService();
            // 注文処理のロジック
        } catch (ValidationException $e) {
            // バリデーションエラーの処理
        } catch (DatabaseException $e) {
            // データベースエラーの処理
        }
    }
}

ベストプラクティス

[編集]
  1. 名前空間は、プロジェクトのディレクトリ構造と一致させることをお勧めします:
    プロジェクトディレクトリ
    src/
      └── App/
          ├── Controllers/
          │   └── UserController.php
          ├── Models/
          │   └── User.php
          └── Services/
              └── UserService.php
    
    src/App/Controllers/UserController.php
    <?php
    namespace App\Controllers;
    
    use App\Models\User;
    use App\Services\UserService;
    
    class UserController 
    {
        private UserService $userService;
        
        public function __construct() 
        {
            $this->userService = new UserService();
        }
        
        public function index() 
        {
            return $this->userService->getAllUsers();
        }
    }
    
  2. オートローディングを活用するために、PSR-4の規約に従った名前空間の構造を採用することをお勧めします:
    {
        "autoload": {
            "psr-4": {
                "App\\": "src/App/"
            }
        }
    }
    

この章で説明した名前空間の概念と使用方法を理解することで、大規模なPHPアプリケーションの開発において、整理された、保守性の高いコードを書くことができます。