> > > [PHP] PSRでのnamespaceのつけ方とautoloading

[PHP] PSRでのnamespaceのつけ方とautoloading

2016-06-20 15:33 - NozawaTakeshi

こんにちわ。開発担当の野澤です。
先日に引き続きPHP関係のネタを。

PSRで定めているnamespaceの使い方や動きがイマイチ分かりにくかったのでまとめてみました。
今回は以下の3つについて見ていきたいと思います。

  • autoloaderとは?
  • namespaceとは?
  • PSRで規定されているネームスペースの付け方

弊社ではCakePHPを使ってアプリケーション開発をすることが比較的多いのですが、
ControllerやComponent、Modelのどれにも収まらないプログラムが結構あったりしませんでしょうか?

最近はそういったプログラムはVendorディレクトリ配下に収めることにしています。

アプリケーション本体とは個別にgitレポジトリを設けて、そこで再利用可能なライブラリとして開発し、
開発したライブラリはサブモジュールとしてVendor配下にデプロイされるような構成です。

なおCakePHPのVendor配下はサードパーティのライブラリを収めるところとして定義されています。

autoloading

ところで、ライブラリも充実してくるとファイル数が多くなってきてrequireするのも大変です。
いつ、どこから、何をrequireするのかとか二重requireを避けるとか、
そういったことを設計するのは結構面倒だったりします。

PHPの__autload()関数を使えば、クラスを呼び出した時にだけ
必要なファイルをrequireするような仕組みを構築することができます。
これがいわゆる「オートーローディング」ですが、
現在ではspl_autoload_register()関数の使用が推奨されていますね。

このオートローディングを構造的に使いやすくするために
namespaceが使われます。

namespace

namespaceはクラス名の重複を防ぐために、クラスが属する
グループ(スペース)を定義する機能です。
namespaceを使えばクラス名が同じであっても、
属するスペースが違ったら別のクラスと見なすことができます。

例えば以下の二つのクラスは別物です。

クラス名は同じですが、そのまえにnamespaceが宣言されており
それぞれ属するnamespaceが違っています。
ひとつめは”Hoge”というネームスペースに属するfooクラスで、
ふたつめは”Piyo”というネームスペースに属するfooクラスです。

これはディレクトリ構造と同じで、/hoge/foo.txtと/piyo/foo.txtが別物として
取り扱えるのと一緒です。
ただし、それぞれhogeディレクトリやpiyoディレクトリに入ってしまえば、フルパスを指定しなくても
foo.txtだけで取り扱うことができますよね。

上記のクラスはこのように呼び出すことが可能です。

またこのように呼び出すこともできます。

PSR

PHPのMVCフレームワークの開発者などが共同で作ったコーディング規約やコーディングガイドである
PSR(PHP Standard Recommendations)では、このネームスペースの付け方が定められています。

PSRのうち、AutoloadingについてまとめられているPSR-4では「ネームスペースとディレクトリ構造を一致させましょう」と定められています。こうしておけば、PSRに準拠しているオートローダー であれば、ネームスペースを辿って、必要なファイルをrequireできるようになります。

具体的には下記のようにすべきとあります。

いくつかのサイトでは「3階層にしなければならない」と解釈されている方もおられましたが
必ずしも3階層内で構成しなければならないわけではなく、
あいだのSubNamespaceNamesは何階層になっていても大丈夫なようです。

※Closure Exampleだけですが、PSR-4標準のオートローダーで確認済みです(パスを指定するところは修正が必要ですのでそのままは使えないので注意してください)。

次回は引き続きPSRかPHPUnitかについて書こうと思います。