📘

【PHP/オブジェクト指向】クラスの自動ローディングについて

2023/12/24に公開

はじめに

オブジェクト指向でコーディングをしていく際には、1クラスを1ファイルで管理するべきです。1クラス1ファイルなら無駄なクラスを読みこむ必要もなく、ファイル管理という観点からも整理がしやすくなります。
ただ1クラス1ファイル方式で作成していくと、扱うクラスが増えてきた時にクラスファイル1つ1つをrequire_once命令で呼び出さなくてはなりませんし、何より記述漏れや誤りの原因になります。
そこで今回は必要なクラスファイルのみを自動でローディングする方法について解説します。

spl_autoload_register関数

まずは基本的な書き方

Autoloader.php
<?php
spl_autoload_register(function(string $name) : void {
    require_once "{$name}.php"
});

spl_autoload_register関数は、オートローダーを登録するための関数です。オートローダーとは、存在しないクラスをインスタンス化する際に呼び出し、対応するクラスファイルをインクルードするための仕組みです。

実際に使ってみる

example1.php
<?php
require_once 'Autoloader.php';

$p = new Person('太郎','山田');
$p->show();     // 結果 : 僕の名前は山田太郎です。

上記のようにrequire_onceで'Autoloader.php'を呼び出すことでPersonクラスをインスタンス化できていることがわかります。
※Personクラスを定義しているファイルの名前はPerson.phpになっていることが前提です。
このように、spl_autoload_register関数を使用することで、クラスごとにrequire_once命令を呼び出す必要がなくなるので、コードがシンプルになります。また、スクリプトの中で本当に使用するかどうかわからないクラスをインクルードしなくても済むので、効率的な処理ができます。

名前空間を指定している場合はspl_autoload_register関数の処理内容を工夫する

spl_autoload_register関数の引数(string $name)には名前空間を含んだクラス名が渡される仕組みになっています。
下記の例だと"Myclass\Person"がspl_autoload_register()内のコールバック関数の引数として渡されます。
※ここでは名前空間の使い方に関する説明は省略

example2.php
<?php
namespace MyClass; //名前空間

require_once 'Autoloader.php';

$p = new Person('太郎','山田');
$p->show();  

このまま最初に提示したspl_autoload_register関数を定義しているAutoloader.phpファイルを呼び出しても当然エラーになります。(Myclass\Person.phpというファイルは存在しないので)

そこで、下記のようにspl_autoload_register関数の処理内容を編集します。

Autoloader.php
<?php
spl_autoload_register(function(string $class) : void {
    // 名前空間とクラス名を分割
    $parts = explode('\\', $class);
    // ファイル名はクラス名と同じになる
    $filename = end($parts) . '.php';
    // ファイルを読み込む
    require_once $filename;

このように引数として受け取った名前空間とクラス名を分割して、クラス名.phpとなった文字列をファイルとして読み込んでいるという流れです。

最後に

今回は、spl_autoload_register関数を使った、クラスの自動ローディングについて解説しました。
クラスファイル1つ1つを呼び出さなくて良くなったのでだいぶ楽になったと思います。
しかし、現状だとクラスのインスタンス化をしている全てのPHPファイルでrequire_once 'Autoloader.php';を実行しないといけないのが少し面倒なので、任意のフォルダの配下に対してAutoloader.phpを呼び出せるようにしたいです。
その方法についてはまた学習した上で記事にしたいと思います。

Discussion