プログラミングに役立つ情報をメモしています
PHP プログラミング

PHPの基本 Part 10(オートローディング)(全10回)

Javaプログラマの目線でPHPの基本をまとめています。

オートローディングの必要性

PHPのファイルはクラスごとに分けることが多い。PHPでは他のファイルに書かれたクラスや関数を使用するためには、名前空間のインポートだけでなく、それらが書かれたPHPファイルをrequireやincludeして読み込まなければならない。オートローディングを使用すると、その手間を省くことができる。PHP5以降に使用可能。

オートローディングとは

マニュアルに「PHPがエラーで止まる前にクラスをロードする最後の チャンスを与えます。」と書かれている通り、まだインクルードされていないPHPファイルに書かれたクラスを使用しようとしたときに__autoload関数が自動的にコールされる。

__autoload関数を定義しておき、クラスが書かれたPHPファイルをrequreすることで、そのクラスが必要なタイミングで読み込むことができる。まだインクルードされていない場合にのみ__autoloadがコールされるので、require_onceを使用する必要はない。マニュアルはこちら。

__autoload()関数について

spl_autoload_register()関数のほうがメリットがあるため、__autoload()は将来非推奨になり削除される可能性がある。

autoload()のデメリットは、グローバル関数でなければならないことと、処理を1つしか登録できないことである。また、5.3以前では、__autoload()内でおきた例外はキャッチできず、致命的なエラーになる。6.5.3以降は、そのクラスを使用しようとした箇所で例外をキャッチできる。そこで独自例外をthrowする場合はその例外クラスについてもautoloadが呼ばれる。

以下は__autoload(string $class)の例。

spl_autoload_register()関数について (PHP5.1.2以降)

SPLで用意されているautoloadの仕組み。

SPLが持つautoloadスタックに指定の関数を登録できる。関数はコールバック関数の形式で登録する(関数、クラスの静的メソッド、インスタンスメソッド)。クラスがロードされるまでコールバックが順番に呼び出され、最後までクラスがロードされなかった場合はFatalErrorが発生する。

spl_autoload_registerに関数を登録していると、__autoload()関数は呼ばれないことに注意。
マニュアルはこちら

class_exists()関数(PHP4,PHP5)とrequire_onceのパフォーマンスについて 

クラスが定義済みかどうかを確認する。単にclass_exists(<クラス名>)とすると、毎度auloloadスタックが呼ばれて、パフォーマンスに悪影響が出ることがある。

class_exists(<クラス名>, false)とすると、現在読み込まれているクラスの中だけで判断できる。

ここで、そもそもautoloadを使えば、class_existsはいらないのでは?という疑問がわいてくる。しかし、class_existsは普通に使われている。理由を調べてみたところ、要するにrequire_onceの処理がrequireに比べてオーバーヘッドが大きいということである。

そのため、if (class_exists("Person", false)) {  require "./Person.php";  }といったコードを書くことによってrequire_onceのオーバーヘッドを回避することがある。

また、PHPのフレームワークを使用する場合に、フレームワーク用のautoloadも登録されているautoloadスタックを使うよりも、class_existsとrequireでロードしたほうがパフォーマンスが良いという場合がある。

マニュアルはこちら