名前空間の基本
CoddyのPHPジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 10/91。
PHPプロジェクトが成長するにつれて、多くのクラスを作成することになります。2つのクラスが同じ名前を持っている場合、何が起こるでしょうか?
例えば、ブログ用に User クラスがあり、ショップ用にもう一つの User クラスがあるかもしれません。名前空間は、クラスを論理的なグループに整理することで、この問題を解決します。
名前空間は、クラスのためのフォルダーのようなものです。PHPファイルの先頭で、namespaceキーワードを使用して宣言します:
<?php
namespace Blog;
class User {
public $name;
public function __construct($name) {
$this->name = $name;
}
}
これで、別の名前空間に別の User クラスを持てるようになります:
<?php
namespace Shop;
class User {
public $email;
public function __construct($email) {
$this->email = $email;
}
}
名前空間付きのクラスを使用するには、バックスラッシュを使用してフルパスで参照します:
<?php
$blogUser = new \Blog\User("Alice");
$shopUser = new \Shop\User("alice@example.com");
echo $blogUser->name . "\n";
echo $shopUser->email . "\n";
出力:
Alice
alice@example.com
バックスラッシュ \ は、ファイルパスでスラッシュがフォルダを区切るのと同様に、名前空間のレベルを区切ります。また、より詳細に整理するために、App\Models\Blog のようなネストされた名前空間を作成することもできます。
重要なポイント: 名前空間は名前の衝突を防ぎ、コードを整理された状態に保ちます。ファイル内の他のどのコードよりも前に(declare 文を除いて)、常に名前空間を宣言してください。
チャレンジ
簡単同じ名前のクラス間の名前の衝突を防ぐために、名前空間(namespaces)を使用して小規模なアプリケーションを整理しましょう。
乗り物と動物の両方を扱うシステムを構築していると想像してください。どちらのドメインにも Car という名前のエンティティがあります。一方は実際の自動車を表し、もう一方は "Car" という名前のペットの猫です(はい、そのように猫に名前を付ける人もいます!)。
3つのファイルを作成します:
Vehicle/Car.php—Vehicle名前空間内にCarクラスを定義し、public $brandプロパティを持たせます。コンストラクタはブランド名を受け取り、それを設定する必要があります。"Vehicle: [brand]"を返すdescribe()メソッドを追加してください。Animal/Car.php—Animal名前空間内にCarクラスを定義します(これは Car という名前の猫です!)。public $ageプロパティを持たせる必要があります。コンストラクタは年齢を受け取り、それを設定します。"Cat named Car, age: [age]"を返すdescribe()メソッドを追加してください。main.php—require_onceを使用して両方のクラスファイルをインクルードします。完全な名前空間パスを使用して各名前空間から1つずつオブジェクトを作成し、各オブジェクトのdescribe()を呼び出した結果を(それぞれ個別の行に)出力してください。
main.php で以下を作成してください:
- ブランドが
"Toyota"のVehicle\Car - 年齢が
3のAnimal\Car
オブジェクトを作成する際は、バックスラッシュ \ を使用して、完全なパスで名前空間付きクラスを参照することを忘れないでください。
チートシート
名前空間は、クラスを論理的なグループに整理し、複数のクラスが同じ名前を共有している場合に名前の衝突を防ぎます。
PHPファイルの先頭で namespace キーワードを使用して、名前空間を宣言します:
<?php
namespace Blog;
class User {
public $name;
public function __construct($name) {
$this->name = $name;
}
}
異なる名前空間であれば、同じ名前のクラスを持つことができます:
<?php
namespace Shop;
class User {
public $email;
public function __construct($email) {
$this->email = $email;
}
}
名前空間が指定されたクラスを使用するには、バックスラッシュ \ を使用してフルパスで参照します:
<?php
$blogUser = new \Blog\User("Alice");
$shopUser = new \Shop\User("alice@example.com");
echo $blogUser->name . "\n";
echo $shopUser->email . "\n";
バックスラッシュは、フォルダのパスのように名前空間の階層を区切ります。App\Models\Blog のように、ネストされた名前空間を作成することもできます。
重要: 名前空間は、ファイル内の他のどのコード(declare 文を除く)よりも前に宣言してください。
自分で試してみよう
<?php
// クラスファイルをインクルードします
require_once 'Vehicle/Car.php';
require_once 'Animal/Car.php';
// TODO: ブランド名 "Toyota" で Vehicle\Car オブジェクトを作成してください
// バックスラッシュを使用した完全な名前空間パスを使用することを忘れないでください
// TODO: 年齢 3 で Animal\Car オブジェクトを作成してください
// バックスラッシュを使用した完全な名前空間パスを使用することを忘れないでください
// TODO: 各オブジェクトの describe() の結果を出力してください(それぞれを個別の行に)
?>このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。