【PHP】Composerを使用してクラスのオートロードを行う

Composerによるautoload

PHPで使用したいクラスファイルの読み込みを簡単に行えるオートロードの使用方法についてメモします。
オートロードの仕組みを利用すると、クラスの読み込みの際にrequire_once関数などを都度使用する必要がなく、
記述がシンプルになり管理も簡単になります。

環境: Mac 10.13.6, PHP 7.4.2, Composer version 1.9.1

Composerを使用する

PHPのパッケージマネージャ、Composerを使用してオートロードに必要なライブラリをプロジェクトに導入していきます。
(開発環境にComposerをインストールしておく必要があります。)

Composer公式ドキュメント

オートロードを利用しない場合の記述

(例)実行ファイルindex.php内からrequire_once文を使用して必要なクラスファイルを複数読み込んでいる。

<?php
require_once('Animal.php');
require_once('model/Dog.php');
require_once('model/Cat.php');

$dog = new Dog();
$cat = new Cat();

print $dog -> bark()."<br>";
print $cat -> bark()."<br>";

?>

ディレクトリ構成

.
├── Animal.php
├── index.php
└── model
    ├── Cat.php
    └── Dog.php

オートロードを利用する

1. composer.jsonを作成する

composer.jsonというファイルをプロジェクト内に作成します。
手動、もしくはプロジェクトのパスでコマンド composer init を実行すると作成されます。

$ composer init

(Enterを押して行けば作成完了)

.
├── Animal.php
├── composer.json
├── index.php
└── model
    ├── Cat.php
    └── Dog.php

作成したcomposer.jsonに下記の記述を行います。

{

    "autoload": {
        "psr-4": {
            "app\\": "./"
        }
    }

}

任意の記述箇所は5行目

名前空間を指定\\”: “(名前空間が指定される)ディレクトリ

上記の例の場合、※composer.jsonと同じ階層配下を「app」という名前空間に指定しています。

※ 「./」 でカレントを表す

composer.jsonのより下の階層、例えば「src」というディレクトリに名前空間を指定する場合は

“app\\”: “src/”

のように記述する。

.
├── Animal.php
├── composer.json
├── index.php
├── src

2. composer dump-autoloadを実行

コマンド composer dump-autoloadを実行して必要な依存ライブラリを作成します。

$ composer dump-autoload

実行後にオートロードを実現するために必要なライブラリと、vendorという新しいディレクトリが自動的に作成されています。

.
├── Animal.php
├── composer.json
├── index.php
├── model
│   ├── Cat.php
│   └── Dog.php
└── vendor
    ├── autoload.php
    └── composer
        ├── ClassLoader.php
        ├── LICENSE
        ├── autoload_classmap.php
        ├── autoload_namespaces.php
        ├── autoload_psr4.php
        ├── autoload_real.php
        └── autoload_static.php

3. クラスに名前空間を指定する

オートロードで読み込む対象となるクラスファイルの先頭にnamespace句を使って名前空間を指定する必要があります。

各ファイルの名前空間

Animal.php
→ app (composer.jsonと同じ階層)

<?php
    namespace app;

    interface Animal {
        public function bark();
    }
?>

Dog.php
Cat.php
→ app\model (名前空間appから一つ下の階層modelに存在する)

(注意)
実装するインターフェース名(implements文の後ろ)に名前空間を指定出来ないので、
use句でAnimalインターフェースの名前空間を明示しています。
(クラスの継承を表すextends文の場合も同様)

<?php
    namespace app\model;
    use app\Animal;

    class Dog implements Animal {        
        public function bark(){
            print "bow!";
        }
    }
?>

4. オートロードでクラスファイルを読み込む

vendor/autoload.phpを実行ファイルから読み込むだけでクラスファイルを使用出来るようになります。
1. ソース内で使用しているDogクラス、Catクラスの前に名前空間を記述します。

<?php

require_once('vendor/autoload.php');

$dog = new app\model\Dog();
$cat = new app\model\Cat();

print $dog -> bark()."<br>";
print $cat -> bark()."<br>";

?>

2. use句に名前空間を記述する

use句に名前空間を指定する事で、クラス名のみでの利用が可能となります。

use 名前空間\クラス名

<?php

require_once('vendor/autoload.php');

use app\model\Dog;
use app\model\Cat;

$dog = new Dog();
$cat = new Cat();

print $dog -> bark()."<br>";
print $cat -> bark()."<br>";

?>

オートロードが効かない時

オートロードの仕組みが期待通りに有効にならない時は
以下の点に注意して確認します。

・実行ファイルできちんと「vendor/autoload.php」を読み込んでいる事
require_once(‘vendor/autoload.php’)

・名前空間を設定、または変更した場合「composer dump-autoload」コマンドを都度実行する。

Follow me!