名前空間
PHPを勉強しているので, それをまとめてみた.
PHPの公式マニュアルを読んで, それをまとめています.
自分なりの解釈がめっちゃ入っているので, 間違えていればコメントで教えてください, お願いします.
参考文献
公式ドキュメントnamaespace
環境
PHPの環境(php -v
の出力)
PHP 7.2.5-0ubuntu0.18.04.1 (cli) (built: May 9 2018 17:21:02) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.2.5-0ubuntu0.18.04.1, Copyright (c) 1999-2018, by Zend Technologies
windows 10 proで, Ubuntu18.04を動かして, そこで動作確認しています.
名前空間とは
名前空間(namespace)について, ざっくり説明してみましょう.
PHPに限らず, 一般的な説明をするなら,
名前空間とは, ものをカプセル化することです.
(ここでは, オブジェクト指向のカプセル化とは別の意味でつかわれています)
はっきり言って意味が分かりません.
もっと具体的に話をしてみましょう.
例えば, 田中 花子
という人がいたとしましょう.
その子は, 田中家ではもちろん田中 花子
は, 花子と呼ばれていると思います(は?そんなことない, 親から苗字, or フルネームで呼ばれてるわ!って人がいたら教えてください).
しかし, 学校に行くと, もう一人佐藤 花子
がいるとしましょう.
そうすると, 学校では, 花子と呼ぶとどちらの花子なのかわかりません.
そうすると, もう花子と学校で呼ぶことはできません.
そこで, 苗字と合わせて呼ぶことで, どちらの花子を呼んでいるか判別できます.
家族の中にいるときは, 田中 花子
は, 花子
と呼ばれても識別されます.
一度外(学校)に行くと, 花子
では, 識別できません.
しかし, 苗字を付けることで, 識別されます.
なので, 家族が違えば, 同じ名前を付けても問題は起こらない.
これがカプセル化です.
苗字(家族)というカプセルを作って, その中でなら, 田中 花子
は花子と呼ぶことができる.
違うカプセル(ここでは, 佐藤)の中ならば, 違う個体(言い方悪い)でも, 同じ名前を使うことができます.
そして, カプセルの外では, 苗字をつけて, カプセル内では, 同じ名前だけれど, 別々の個体を, 識別することができます(田中 花子
と佐藤 花子
)
ほかにも, ファイルシステムでも, 名前空間は使われています.
例えば, 同じフォルダ(ディレクトリ)には, 同じ名前のファイルは作れません.
これは, 上の例でいう 学校では, 田中 花子
と佐藤 花子
を花子と呼ぼうとしている状態です.
違うフォルダならば, 同名のファイルを作ることができます.
これは, 佐藤
という家族(ファイルシステムでは, フォルダ. 抽象的には, カプセル)と田中
という家族では, 花子と呼べるということと同じです.
なんとなく雰囲気がつかめたところで, PHPの名前空間(Namespace)について, 話をしましょう.
(一般の名前空間の話はここで, 終わり)
そもそも, なぜPHPには, 名前空間が必要か?
phpの公式ドキュメントでは, 二つの問題を解決するためと書かれています.
- Name collisions between code you create, and internal PHP classes/functions/constants or third-party classes/functions/constants.
- Ability to alias (or shorten) Extra_Long_Names designed to alleviate the first problem, improving readability of source code.
1の言っていることは, 自分の作ったコードと, PHPの内部のコード(PHPをインストールしたら勝手についてくる便利なコード)のクラスや関数, また, 外部ライブラリのクラスや関数やらの名前がぶつかってしまい, どっちが呼び出されるのか分からなくなる現象(Name collisions, 日本語は知らない)が起きてしまうのを防ぐ.
2は, 1の問題を和らげるために, 別名をつけるための仕組みとして機能している.
さて, 実際にコードを試しながら, PHPの名前空間をどう使っているのか見ていきます.
PHPの名前空間宣言のsyntax
versionは, php 5.3以上 or php7で動作するらしいです(accroding to 公式ドキュメント).
PHPで, 名前空間を宣言するには, namespace
キーワードを使います.
いきなりですが, コードを見てみましょう.
<?php
namespace MyProject;
const CONNECT_OK = 1;
const CONNECT_FAIL = 0;
class Connection()
{
/* .... */
}
function connect()
{
/* ..... */
}
一行目のnamespace
というキーワードの後に, 名前空間の名前を裸のまま("
とか'
とかつけないで)宣言します.
この上の例では, MyProject
というカプセルができたことになります.
他のコードで, Connection
やconnect
などの名前を使っても大丈夫なことになります.
ここで, いくつか注意点があります.
namespaceの宣言は, コードの一番最初にしなければいけません.
namespace MyProject
の前の行に, <?php
以外の文字があると以下のようなerrorになります.
PHP Fatal error: Namespace declaration statement has to be the very first statement or after any declare call in the script
公式ドキュメントには,
The only code construct allowed before a namespace declaration is the declare statement, for defining encoding of a source file.
In addition, no non-PHP code may precede a namespace declaration, including extra whitespace:
とあるので, <?php
の上に何か文字を入れてもエラーになります(ならない環境があるのか不明).
つまり, htmlファイルの中に埋め込まれているphpは, namespace
の宣言は使えないことになります.
実は例外が一つだけあり, declare
だけは, namespace
の前においてもエラーになりません.
これは, declare
が, コンパイラ中に処理されるからだと思われます.
次は, サブ名前空間についてです.