【PHP】名前空間(namespace) - プログラムのグループ化

【PHP】名前空間(namespace) - プログラムのグループ化

PHPには名前空間と呼ぶ仕組みがあります。

名前空間を使うことによって、同名のクラスや関数を作ることが可能です。

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

検証環境

名前空間

名前空間は“プログラムをグループ化する仕組み”です。

クラスや関数など命名が必要なモノは固有の名前を付ける必要がありますが、異なる名前空間であれば同じ名前を使用できます。

1つのプログラムに複数の名前空間を作ることができ、オブジェクト指向プログラミングではカプセル化で使用します。

また、名前空間は『ネームスペース』とも呼ばれます。

基本構文

名前空間の基本構文はブロック(波括弧{})を使うパターンと使わないパターンの2種類あります。

ブロック利用

namespace ネームスペース名 {
    処理
}

ブロック未利用

namespace ネームスペース名;


いずれの構文でも同じ動作になりますが、2つの注意点があります。

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

本ドキュメントでは、比較的多く使われるブロック未利用のパターンで解説します。

サンプル

<?php

___ih_hl_start
namespace Program1;
___ih_hl_end

// 人間クラス
class Person {
    
    // 名前
    public $name;
    
    // コンストラクタ
    public function __construct( $name ) {
        $this->name = $name;
    }
    
    // あいさつ
    public function greeting() {
        echo "Hello.\n";
        echo "My name is ".$this->name.".\n";
    }
    
}

$person = new Person('TANAKA');
$person->greeting();

___ih_hl_start
namespace Program2;
___ih_hl_end

// 人間クラス
class Person {
    
    // 名前
    public $name;
    
    // コンストラクタ
    public function __construct( $name ) {
        $this->name = $name;
    }
    
    // あいさつ
    public function greeting() {
        echo "Hey.\n";
        echo "I'm ".$this->name.".\n";
    }
    
}

$person = new Person('SUZUKI');
$person->greeting();

?>
$ php sample.php
Hello.
My name is TANAKA.
Hey.
I'm SUZUKI.

3行目と27行目で2つの名前空間Program1Program2を定義しています。

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

そのため、Program1の範囲は3〜26行目、Program2の範囲は27行目以降です。

このサンプルにはPersonクラスがありますが、名前空間が異なるため、エラーは発生しません。

実行結果から各オブジェクトののgreetingメソッドが各名前空間のPersonクラスの処理になっていることが分かります。

名前の重複

同じ名前空間でクラスや関数などの名前が重複することを、『名前の衝突』や『名前の競合』と呼びます。

上記サンプルで名前空間の宣言をしないと、次のようにエラーが発生します。

<?php

___ih_diff_start
-namespace Program1;
___ih_diff_end

// 人間クラス
class Person {
    
    // 名前
    public $name;
    
    // コンストラクタ
    public function __construct( $name ) {
        $this->name = $name;
    }
    
    // あいさつ
    public function greeting() {
        echo "Hello.\n";
        echo "My name is ".$this->name.".\n";
    }
    
}

$person = new Person('TANAKA');
$person->greeting();

___ih_diff_start
-namespace Program2;
___ih_diff_end

// 人間クラス
class Person {
    
    // 名前
    public $name;
    
    // コンストラクタ
    public function __construct( $name ) {
        $this->name = $name;
    }
    
    // あいさつ
    public function greeting() {
        echo "Hey.\n";
        echo "I'm ".$this->name.".\n";
    }
    
}

$person = new Person('SUZUKI');
$person->greeting();

?>
$ php sample.php
Hello.
My name is TANAKA.
PHP Fatal error:  Cannot declare class Person, because the name is already in use in sample.php on line 30

Fatal error: Cannot declare class Person, because the name is already in use in sample.php on line 30

このエラーはPersonクラスの名前が重複したことによるものです。

演習問題

問題1

次の実行結果になるプログラムを作成してください。
なお、下記条件を満たすものとします。

  • 名前空間のAdditionとMultiplicationを定義する
  • 各名前空間にexecute関数を定義する
  • 名前空間Additionのexecute関数は次のとおりとする
    引数 : 数値1、数値2
    処理 : 数値1と数値2の合計値を出力
  • 名前空間Multiplicationのexecute関数は次のとおりとする
    引数 : 数値1、数値2
    処理 : 数値1と数値2の乗算値を出力
====    Addition    ====
3 + 5 = 8
==== Multiplication ====
7 * 9 = 63

問題2

次の実行結果になるプログラムを作成してください。
なお、下記の条件を満たすものとします。

  • 名前空間のDriverとShopを定義する
  • 各名前空間にCarクラスを定義し、内容は次の表の通りとする
名前空間 クラス フィールド メソッド
Driver Car ・accel()
『加速』を出力する
brake()
『減速』を出力する
Shop Car $price
(値段)
・コンストラクタ
$priceの初期値を設定する
display_price()
値段($price)を出力する
==== Driver ====
加速
減速
====  Shop  ====
料金 : 3500000円