【PHP】namespaceとは? – 名前空間で命名の重複を回避する。

名前空間と呼ばれる仕組みがあります。

クラス名や関数名など何かに名前を付けるとき、通常は固有の名前にする必要があり、名前が被るとエラーになりますが、名前空間の仕組みを使うことで、同じ名前のクラスや関数を作ることができるようになります。

ここでは名前空間について解説します。

★ 目的

  • 名前空間について理解する。
  • 名前空間を使えるようになる。

名前空間とは

名前空間は項目をカプセル化するときに使用する仕組みです。

カプセル化はオブジェクト指向の考え方の1つで、簡単に説明するとプログラムのグループ化のようなものです。

名前空間はnamespace(ネームスペース)とも呼ばれ、プログラムのグループ名を定義します。

そして、異なるグループであれば同じ名前のクラスや関数を作ることができるようになります。

基本構文

名前空間の使い方は2パターンあります。

1つ目はブロック(波括弧{})ありのパターン、2つ目はブロックなしのパターンです。

ブロックありのパターン

<?php

namespace ネームスペース名 {
    // コードを記述・・・
}

?>

ブロックなしのパターン

<?php

namespace ネームスペース;

?>

どちらの記述方法でも同じ動作になりますが、注意点が2つあります。

  • namespaceはファイルの先頭(phpタグの次)に記述する必要がある。
  • ブロックありのパターンの場合、ブロックの外にコードを記述できない。

ここでは、比較的多く使われているブロックなしのパターンで解説を進めていきます。

サンプルコード

次のサンプルコードをご覧ください。

ソースコード

<?php

namespace Program1;

// クラス
class Person {
    
    // 名前
    public $name;
    
    // コンストラクタ
    public function __construct( $name ) {
        $this->name = $name;
    }
    
    // プロフィールを出力する
    public function profile() {
        echo "私の名前は".$this->name."です。\n";
    }
    
}

$watanabe = new Person('Watanabe You');
$watanabe->profile();

namespace Program2;

// クラス
class Person {
    
    // 名前
    public $name;
    
    // コンストラクタ
    public function __construct( $name ) {
        $this->name = $name;
    }
    
    // プロフィールを出力する
    public function profile() {
        echo "My name is ".$this->name.".\n";
    }
    
}

$watanabe = new Person('Watanabe You');
$watanabe->profile();

?>

実行結果

私の名前はWatanabe Youです。
My name is Watanabe You.

2つの名前空間(Program1とProgram2)を定義しています。

名前空間の範囲はnamespaceで宣言した行より下のコードになりますが、途中で別のnamespaceがある場合は、その直前の行までになります。

そのため、Program1の範囲は3行目〜25行目、Program2の範囲は26行目以降となります。

そして、コード上にはPersonクラスが2つありますが、これらは名前空間が違うため、エラーになりません。

それぞれのインスタンスを生成し、profileメソッドを実行していますが、各名前空間のPersonクラスで定義したメソッドが実行されていることが実行結果から分かります。

名前の衝突について

上記サンプルコードで名前空間の宣言がない場合は次のようになります。

ソースコード

<?php

// クラス
class Person {
    
    // 名前
    public $name;
    
    // コンストラクタ
    public function __construct( $name ) {
        $this->name = $name;
    }
    
    // プロフィールを出力する
    public function profile() {
        echo "私の名前は".$this->name."です。\n";
    }
    
}

$watanabe = new Person('Watanabe You');
$watanabe->profile();

// クラス
class Person {
    
    // 名前
    public $name;
    
    // コンストラクタ
    public function __construct( $name ) {
        $this->name = $name;
    }
    
    // プロフィールを出力する
    public function profile() {
        echo "My name is ".$this->name.".\n";
    }
    
}

$watanabe = new Person('Watanabe You');
$watanabe->profile();

?>

実行結果

私の名前はWatanabe Youです。
PHP Fatal error:  Cannot declare class Person, because the name is already in use in /source-code/sample.php on line 25

Fatal error: Cannot declare class Person, because the name is already in use in /source-code/sample.php on line 25

実行結果でエラーが出力されていますが、これはPersonクラスが2つあるため発生しているエラーです。

このように名前が被ってしまうことを名前の衝突と呼びます。

まとめ

名前空間(namespace)はカプセル化するための仕組みです。カプセル化はオブジェクト指向の知識を必要としますが、簡単な解釈としてはグループ化を行うと覚えておけば良いでしょう。