PHPの名前空間とクラス名のエイリアス、オートロードWeb業界で働くためのPHP入門(終)(2/3 ページ)

» 2018年08月01日 05時00分 公開

名前空間の使い方

 名前空間とは何か、名前空間の必要性を理解したところで、実際に名前空間を使っていきましょう。

名前空間の定義

 まず、作成したクラスを名前空間に入れておく方法です。サンプルから紹介します。以下のMainControllerクラスを作成してください。

<?php
namespace atmarkit\phplesson\chap20\classes;  // (1)
 
class MainController
{
    public function __construct()
    {
        print("MainControllerがnewされました<br>");
    }
}
リスト4 phplesson/chap20/classes/MainController.php

 こちらのクラスの処理内容も何でも構わないので、コンストラクタのみを記述しています。リスト4の(1)の記述が名前空間を定義している部分です。名前空間は、「namespace」に続けて名前空間を表す文字列を記述します。記述する場所は、クラスが記述されたファイルの一番初め(<?phpを除く)です。構文としては以下のようになります。

構文「名前空間」

namespace 名前空間;

class クラス名

{

  :

}


 名前空間を表す文字列で階層構造を表す場合はバックスラッシュで区切ります(Windowsでは半角¥マーク)。その際、最初の一区切りはこのシステムを作成している会社や組織などの名前(これをベンダー名といいます)を採用するのが普通です。リスト4の(1)では「atmarkit」としています。

 最初がベンダー名であれば、それ以降は自由に付けていいことになっていますが、通常は、そのクラスファイルのドキュメントルート以下のパスと階層構造と一致させます。例えば、リスト4だと、パスが「phplesson/chap20/classes」なので、名前空間は「atmarkit\phplesson\chap20\classes」となります。この理由については後述します。

注意!「同一ファイルに複数の名前空間」

 PHPの仕様としては、同一ファイル内に複数の名前空間の記述が可能です。例えば、以下のようなコードです。

<?php
namespace atmarkit\phplesson\chap20\classes\dao;
class HogeDao
{
 :
}
namespace atmarkit\phplesson\chap20\classes\controller;
class BowController
{
 :
}

 あるいは、名前空間の範囲をはっきりさせるために、以下のように半角波かっこでくくることもあります。

<?php
namespace atmarkit\phplesson\chap20\classes\dao {
    class HogeDao {
     :
    }
}
namespace atmarkit\phplesson\chap20\classes\controller {
    class BowController {
     :
    }
}

 ただ、このように同一ファイル内に複数の名前空間を記述するのは、ソースコードの可読性や管理の上で極力避けてください。


グローバル空間

 最初に説明したように、名前空間はPHP 5.3で導入されたものなので、それ以前からあるクラスは名前空間が定義されていません。

 例えば、PHPにはデータベースに接続するためのクラスとして「PDO」がPHP 5.1から存在します。バージョン番号から分かるように、このPDOクラスは名前空間が定義されていません。

 このような名前空間が定義されていないクラスは、全て「グローバル空間」という名前空間に所属することになっています。そして、そのグローバル空間は、「\」で表します。

クラスの3種の表し方

 グローバル空間が登場したところで、名前空間を含めた上でのクラスの表し方をまとめておきます。それは以下の3種になります。ここでは、「atmarkit\phplesson\chap20\classes」直下のクラスからあるクラスを利用する場合を例として説明します。

【1】完全修飾名

 グローバル名前空間から全てを記述する場合です。例えば、下記のようになります。

new \atmarkit\phplesson\chap20\classes\controller\MakeController();

 これが、このクラスの本来のクラス名ということになります。

【2】修飾名

 自分自身から相対的な名前空間を付与したクラス名を記述する場合です。例えば、下記のようになります。

new dao\Dept();

 この場合、このDeptクラスの完全修飾名は、「\atmarkit\phplesson\chap20\classes\dao\Dept」となります。

【3】非修飾名

 単にクラス名だけを記述する場合です。例えば、下記のようになります。

new Change();

 この場合は、自分自身と同一名前空間に属するクラス、つまり、「\atmarkit\phplesson\chap20\classes\Change」クラスを指します。

 なお、上の説明から分かるように、先のPDOのようにグローバル空間に所属するクラスの完全修飾名は「\PDO」となります。

名前空間のあるクラスの利用方法

 名前空間が定義されたクラスを利用する場合、require_onceでそのファイルを読み込んだ後、上の【1】〜【3】のいずれかの方法でクラス名を記述する必要が出てきます。別の名前空間にあるクラスを単に非修飾名で記述すると、エラーとなります。

 例えば、以下のようなコードです。

<?php
require_once("classes/MainController.php");
$controller = new MainController();

 確かに、リスト4で記述したMainControllerクラスファイルをrequire_onceしていますが、このコードを実行すると以下のようなエラーとなります。

Fatal error: Uncaught Error: Class 'MainController' not found in C:\xampp\htdocs\phplesson\chap20\useMainController.php:6 Stack trace: #0 {main} thrown in C:\xampp\htdocs\phplesson\chap20\useMainController.php on line 6

 この場合、一番安全なのは完全修飾名をいちいち記述することですが、それも手間です。そこで、通常は、名前空間が定義されたクラスを利用する場合は以下のようにします。このphpファイルを作成し、実行してください。

<?php
require_once("classes/MainController.php");
use atmarkit\phplesson\chap20\classes\MainController;  // (1)
$controller = new MainController();
リスト5 phplesson/chap20/classes/useMainController.php

 実行結果は以下の通りです。

MainControllerがnewされました

 今度は無事実行できました。

 リスト5で追加されているコードは(1)です。(1)では「use」に続けて、完全修飾名の最初の\がないクラス名が記述されています。あらかじめこのような記述をしておくことで、クラスを利用する場面では単にクラス名を記述するだけで済みます。構文としてまとめておきます。

構文「名前空間付クラスの利用」

use クラスの完全修飾名から最初の\を除いたもの;


コラム「名前空間付き関数と定数」

 ここまで解説してきた名前空間は、実はクラスにだけ付与するものではなく、関数や定数の定義にも付与できます。そして、これら関数や定数も名前空間が付与されていないものはグローバル空間に属します。

 関数や定数における名前空間の扱いと、クラスにおける名前空間の扱いには、大きな違いがあります。クラスの場合は、useを行わずに同一名前空間にないクラスを利用しようとするとエラーとなりましたが、関数や定数の場合はエラーとはならず、グローバル空間を探しにいってくれるというものです。この機能のおかげで、名前空間が付与されたPHPコード内で通常の関数を利用しようとしてもエラーとならずに済みます。


Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。