PHP 命名空間 (Namespace)
命名空間用來組織程式碼,避免類別、函數和常數的名稱衝突。當你的專案規模成長,或引入第三方套件時,很可能會遇到不同來源的類別有相同名稱的問題(例如兩個套件都有 User 類別)。命名空間讓你可以將程式碼分組,就像檔案系統中的資料夾一樣,確保即使名稱相同也不會衝突。
定義命名空間
使用 namespace 關鍵字定義命名空間。它必須是檔案中的第一行 PHP 程式碼(在 <?php 之後,任何其他程式碼之前)。
<?php
// File: src/Models/User.php
namespace App\Models;
class User {
public function __construct(
public string $name
) {}
}
?>
<?php
// File: src/Controllers/UserController.php
namespace App\Controllers;
class User { // 不會和 App\Models\User 衝突
public function index(): void {
echo "User Controller";
}
}
?>
使用命名空間
有三種方式可以引用命名空間中的類別:
完整名稱
使用完整的命名空間路徑(以 \ 開頭表示從全域開始):
<?php
$user = new \App\Models\User("Alice");
?>
use 語句
使用 use 語句匯入類別,之後可以直接使用類別名稱:
<?php
use App\Models\User;
$user = new User("Alice");
?>
別名
當需要使用相同名稱的多個類別時,可以用 as 指定別名:
<?php
use App\Models\User as UserModel;
use App\Controllers\User as UserController;
$model = new UserModel("Alice");
$controller = new UserController();
?>
群組匯入
<?php
// 群組匯入相同命名空間的類別
use App\Models\{User, Post, Comment};
// 或
use App\Models\User;
use App\Models\Post;
use App\Models\Comment;
?>
函數和常數
<?php
namespace App\Utils;
const VERSION = '1.0.0';
function helper(): string {
return "Helper function";
}
class Utility {
public static function format(): string {
return "Formatted";
}
}
?>
<?php
use App\Utils\Utility;
use function App\Utils\helper;
use const App\Utils\VERSION;
echo VERSION; // 1.0.0
echo helper(); // Helper function
echo Utility::format();
?>
全域命名空間
PHP 內建的類別和函數(如 DateTime、Exception、date() 等)都在全域命名空間中。當你在一個有命名空間的檔案中使用它們時,需要加上前綴 \ 來明確指定是全域命名空間:
<?php
namespace App\Services;
class DateService {
public function now(): \DateTime {
return new \DateTime(); // PHP 內建類別
}
public function format(): string {
return \date('Y-m-d'); // PHP 內建函數
}
}
?>
命名空間慣例
PSR-4 自動載入標準:
App\ → src/
App\Models\User → src/Models/User.php
App\Controllers\Home → src/Controllers/Home.php
實際範例
<?php
// src/Models/User.php
namespace App\Models;
class User {
public function __construct(
public int $id,
public string $name,
public string $email
) {}
}
?>
<?php
// src/Repositories/UserRepository.php
namespace App\Repositories;
use App\Models\User;
class UserRepository {
private array $users = [];
public function find(int $id): ?User {
return $this->users[$id] ?? null;
}
public function save(User $user): void {
$this->users[$user->id] = $user;
}
}
?>
<?php
// src/Services/UserService.php
namespace App\Services;
use App\Models\User;
use App\Repositories\UserRepository;
class UserService {
public function __construct(
private UserRepository $repository
) {}
public function createUser(string $name, string $email): User {
$user = new User(
id: random_int(1, 1000),
name: $name,
email: $email
);
$this->repository->save($user);
return $user;
}
}
?>