とぎぷろべい

包丁研ぎとプログラミングと米国株投資についてのなんやかんや

ネームスペースについて(PHP)

f:id:feci:20210727001932j:plain

PHP7

 

PHP7.4.1におけるネームスペースについて

 

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

ネームスペースはクラスを分類するための機能です。

なので今回はこの機能を説明するために3つのファイルを使っていきます。

 

①実行ファイル(php\sample.php

<?php
declare(strict_types=1);           //requireの下行に書くとErrorが出る
require_once 'html2/a/ab/Ab.php';  //ファイル名の頭文字を大文字にしないとErrorが出る
require_once 'html2/a/ac/Ab.php';  //上行と同じようにファイルパスを記述

$ab = new a\ab\Cab();              //ネームスペース\メソッド名としないとErrorが出る
echo $ab->getIa(), "\n";           //ここの記述は通常時と同じでOK

use a\ab\Cab;                      //この記述があればインスタンス作成時の記述が省略可
//use a\ac\Cab;                    //namespaceが違っても同じクラス名だとErrorが出る
use a\ac\Cab as Cab2;              //a\acのCabメソッドをCab2に改名した

$ab2 = new Cab();                  //use文のおかげでこの記述でもインスタンスが作れる
echo $ab2->getIa(), "\n";          //100

$ac = new Cab2();                  //これなら問題なくインスタンスを生成できる
echo $ac->getIa(), "\n";           //50

 

 

②ネームスペースa\abファイル(php/html2/a/ab/ab.php

<?php
namespace a\ab;  //このファイルで定義したクラスはa\abに分類される

class Cab {
  protected int $ia;

 public function getIa(): int {
    return 100;
  }
}

 

 

③ネームスペースa\acファイル(php/html2/a/ac/ab.php

<?php
namespace a\ac;  //このファイルで定義したクラスはa\acに分類される

class Cab {
  protected int $ia;

 public function getIa(): int {
    return 50;
  }
}

②と③はそれぞれ別ファイルです。

namespace ネームスペース名; とファイルの先頭に記述することで、そのファイル内で定義したクラスをすべてnamespaceで記述したネームスペース名に分類することができます。

 

namespaceが宣言できるのは、1ファイルにつき1回限りです。

なので同一のPHPファイル内で2つ以上の異なるnamespaceに分類したいクラスを定義することはできません。

 

 

namespaceの準備ができたら、あとは実行ファイルでそれをrequireしてインスタンス化して実行するだけです。

require_once '読み込みたいファイルの実行ファイルの位置から見た相対パス'; と記述して、当該のファイルをrequireします。

 

このときの相対パスに書くファイル名は、必ず頭文字を大文字にしてください。

フォルダ名はそのままでいいですが、ファイル名の先頭を大文字にしないとなぜかファイルを読み込めずにErrorが出ます。

 

なおこのときにもし declare(strict_types=1); を記述するのであれば、この記述は必ずrequire_onceの記述よりも上の行に記述してください。

なぜかは分かりませんが、require_once文よりも下の行にこれを書くと問答無用でErrorが出ます。

 

 

さてrequireができたらあとはそのクラスをインスタンス化して実行するだけです。

しかしnamespaceが与えられたクラスは通常の $〇〇 = new 〇〇; という記述だけではクラスのインスタンスを作成することができません。

 

namespaceが与えられたクラスのインスタンスを作るには、 $〇〇 = new ネームスペース名\クラス名(引数1, …); と記述する必要があります。

インスタンスを作ったあとのメソッドの呼び出し方は、通常どおりの方法で大丈夫です。

 

またこの長ったらしいインスタンス生成時の記述がめんどうなのであれば、use文を使うことでインスタンス生成時の記述を通常どおりの new クラス名; だけで済ませられるようにもできます。

 

この場合のuse文には use ネームスペース名\クラス名; と書きます。

この記述以降の行では、通常どおりのnew クラス名だけの記述でそのクラスのインスタンスを作成することができるようになります。

 

 

また、場合によっては同じ名前のクラスをあつかわなくてはならないパターンというのもあるかもしれません。

この場合は上記のようなuse文は使えません。

たとえネームスペース名が違ったとしても、クラス名が同じだと問答無用でErrorが出ます。

 

このような場合はuse文を使わずにインスタンスを生成するのも1つの方法でしょうし、なんだったらuse-as文を使ってどっちかのクラス名を改名して使用するという方法もあります。

この場合のuse-as文では、上記のuse文の記述につなげて as 改名後のクラス名; と記述します。

 

これで、これ以降の行でのこのクラスのインスタンスの生成時には $〇〇 = new 改名後のクラス名; と記述するだけで、問題なくそのクラスのインスタンスを作ることができます。

 

 

以上です。