PSR-4 の理解

What’s PSR-4 ?

そもそもPSRって何の略だろうと調べたがそこから出てこなかった。
↓なんじゃないか、という意見あり。

  • PHP Standard Recommendation
  • PHP Specification Request

カテゴリ毎に数字が割り当てられており他にも以下が存在する。

  • PSR-0 Autoloading
  • PSR-1 Basic Coding Standard
  • PSR-2 Coding Style Guide
  • PSR-3 Logger Interface
  • PSR-4 Improved Autoloading
  • PSR-6 Chaching Interface
  • PSR-7 HTTP Message Interface

PHP-FIGという団体で取りまとめられている。http://www.php-fig.org/

PSR-4

それでは早速一次情報から漁ってみる。どのパスにどのクラスを配置するのか仕様を決めたいというのが根っこにある。決まりがあればクラスを使う側が楽だから。楽に使ってもらえるよう配布手段に規約を設ける。PSR-0(等?)と互換性がある。(PSR-0以外にもこういう決まりがあるのか?)

This PSR describes a specification for autoloading classes from file paths. It is fully interoperable, and can be used in addition to any other autoloading specification, including PSR-0. This PSR also describes where to place files that will be autoloaded according to the specification.

仕様

言葉遊び

ドキュメント内では”class”は class,interfaces,traits,それに似た構造を指すそうだ。あくまでも外部から使用する対象と配置に関する仕様だよ、ということだ。対象は何でも良い。

The term “class” refers to classes, interfaces, traits, and other similar structures.

完全修飾クラス名

完全修飾クラス名は次のような形式となるそうだ。

A fully qualified class name has the following form:

\<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>

いくつか決まり事がある。

  • The fully qualified class name MUST have a top-level namespace name, also known as a “vendor namespace”.
    • 完全修飾クラス名にはベンダーを表すユニークな名前空間が入っていないといけない
    • NamespaceNameが一意なのか、NamespaceNameとSubNamespaceNamesの合わせ技で一意なのか不明。
    • GitHubに上がってるのを見るとNamespaceNameだけで表現しているようだ。「トップレベル」って「一番最初=NamespaceName」のことか??
  • The fully qualified class name MAY have one or more sub-namespace names.
    • 補助的に名前空間を複数追加しても良い
    • 階層構造を持った複雑な名前空間も定義できるということ。
  • The fully qualified class name MUST have a terminating class name.
    • 完全修飾クラス名の最後はクラス名でなければならない
  • Underscores have no special meaning in any portion of the fully qualified class name.
    • アンスコは特別な意味を持たない。
    • アンスコを前後の識別子の接続子のように使うフレームワークが多いからね。
    • アンスコは単なる文字。
  • Alphabetic characters in the fully qualified class name MAY be any combination of lower case and upper case.
    • 大文字小文字の任意の組み合わせで良い。
    • 大文字小文字に意味を持たせるフレームワークが多いからね。
  • All class names MUST be referenced in a case-sensitive fashion.
    • 大文字小文字を区別する。
ファイルをロードする側の決まりごと
  • A contiguous series of one or more leading namespace and sub-namespace names, not including the leading namespace separator, in the fully qualified class name (a “namespace prefix”) corresponds to at least one “base directory”.
    • NamespaceNameといくつかのSubNamespaceNameを「名前空間プレフィックス」と呼ぶ
    • SubNamespaceNameが複数個あった場合その全てが「名前空間プレフィックス」になるとは読めない。
    • 完全修飾クラス名とは「名前空間プレフィックス」+(「サブ名前空間」)+「クラス名」となる。
    • 「名前空間プレフィックス」がディレクトリ名と対応している必要がある。と書いてあるがサンプルの「BaseDirectory」が名前空間プレフィックスと全然違う。意味不明。
  • The contiguous sub-namespace names after the “namespace prefix” correspond to a subdirectory within a “base directory”, in which the namespace separators represent directory separators. The subdirectory name MUST match the case of the sub-namespace names.
    • 名前空間プレフィックスに続くサブ名前空間が、BaseDirectoryに続くサブディレクトリに対応する。
    • サブ名前空間とサブディレクトリの大文字小文字は一致している必要がある。
  • The terminating class name corresponds to a file name ending in .php. The file name MUST match the case of the terminating class name.
    • 終端のクラス名は、大文字小文字が一致するphpファイルと対応する。

PSR-4の例。やはり、どうも規則性が見えない。

FULLY QUALIFIED CLASS NAME NAMESPACE PREFIX BASE DIRECTORY RESULTING FILE PATH
\Acme\Log\Writer\File_Writer Acme\Log\Writer ./acme-log-writer/lib/ ./acme-log-writer/lib/File_Writer.php
\Aura\Web\Response\Status Aura\Web /path/to/aura-web/src/ /path/to/aura-web/src/Response/Status.php
\Symfony\Core\Request Symfony\Core ./vendor/Symfony/Core/ ./vendor/Symfony/Core/Request.php
\Zend\Acl Zend /usr/includes/Zend/ /usr/includes/Zend/Acl.php

全然規則性が見えないぞ?

全然しっくりこないのでさらに調べてみた。COMPOSERがだいぶ前にPSR-4に対応したらしいのでAUTOLOADの補完ルールを色分けした。を参考にさせて頂きました。

FULLY QUALIFIED CLASS NAME NAMESPACE PREFIX BASE DIRECTORY RESULTING FILE PATH
\Acme\Log\Writer\File_Writer Acme\Log\Writer ./acme-log-writer/lib/ ./acme-log-writer/lib/File_Writer.php
\Aura\Web\Response\Status Aura\Web /path/to/aura-web/src/ /path/to/aura-web/src/Response/Status.php
\Symfony\Core\Request Symfony\Core ./vendor/Symfony/Core/ ./vendor/Symfony/Core/Request.php
\Zend\Acl Zend /usr/includes/Zend/ /usr/includes/Zend/Acl.php

訳にも書いたが、全てのサブ名前空間が名前空間プレフィックスに含まれる訳ではないことに注意。名前空間プレフィックスに含まれなかったサブ名前空間が突然ファイルパスに出現したりする。

サブ名前空間とBaseDirectoryの規則性について、サブ名前空間をハイフンで区切った一つのディレクトリと対応させる場合もあるし、階層構造まで一致させる場合もある。名前空間プレフィックスとBase Directoryの関係性は割と柔軟。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする