PHPでは、 spl_autoload_registerとspl_autoload_unregisterは、クラスのオートローダーを管理するための強力なメカニズムを提供します。ただし、複雑なプロジェクトやフレームワークでは、オートローダーが故障したり、登録を重複させたり、予期しない削除を削除したりする場合があります。この記事では、コアの問題に焦点を当てます。
spl_autoload_register()で自動導入関数を登録する場合、これらの関数は内部関数スタックに保存されます。未定義のクラスが呼び出された場合にのみ、PHPがこれらのオートローダーを呼び出して順番にロードしようとします。
SPL_AUTOLOAD_FUNCTIONS()を使用して、現在登録されているAutoloaderリストを表示できます。
$autoloaders = spl_autoload_functions();
print_r($autoloaders);
この関数は、匿名関数、クラスメソッド(静的および非静的)などを含むすべての登録されたオートローダーをリストする配列を返します。
自動ローダーがまだあるかどうかを判断する最も直接的な方法は、spl_autoload_functions()によって返された結果と比較することです。次の登録ローダーがあるとします。
function myAutoloader($class) {
include 'classes/' . $class . '.class.php';
}
spl_autoload_register('myAutoloader');
私たちはこのように判断することができます:
$autoloaders = spl_autoload_functions();
$isRegistered = false;
foreach ($autoloaders as $loader) {
if ($loader === 'myAutoloader') {
$isRegistered = true;
break;
}
}
echo $isRegistered ? '登録済み' : '登録されていません';
ローダーが登録されていて削除したいと確信したら、 spl_autoload_unregisterを使用できます。
if ($isRegistered) {
spl_autoload_unregister('myAutoloader');
}
この関数は、ローダーが登録されていない場合に呼び出され、警告が発生します。したがって、エラーを避けるために、最初に判断してから削除するのが最善です。
クラスメソッドの登録フォーム( [className、 'methodname']など)またはオブジェクトメソッドの場合、判断方法も詳細にする必要があります。例えば:
class MyLoader {
public static function load($class) {
include 'libs/' . $class . '.php';
}
}
spl_autoload_register(['MyLoader', 'load']);
そのようなローダーが存在するかどうかを判断するには、これを行うことができます。
$autoloaders = spl_autoload_functions();
foreach ($autoloaders as $loader) {
if (is_array($loader) && $loader[0] === 'MyLoader' && $loader[1] === 'load') {
echo "MyLoader::load 登録済み";
}
}
匿名の関数は、名前がないため、従来の方法で比較することはできません。この時点で、 spl_autoload_functions()によって返されたコンテンツを使用して、閉鎖関数構造の判断を行うことができますが、それらを削除するには、通常、登録中に参照を手動で記録する必要があります。例えば:
$anonLoader = function($class) {
include 'includes/' . $class . '.php';
};
spl_autoload_register($anonLoader);
// 削除するときは元の参照が必要です
spl_autoload_unregister($anonLoader);
ローダーステータスをすばやくデバッグしたいですか?デバッグ機能を書くだけです:
function dumpAutoloaders() {
echo "<pre>";
foreach (spl_autoload_functions() as $loader) {
if (is_string($loader)) {
echo "Function: $loader\n";
} elseif (is_array($loader)) {
echo "Method: " . (is_object($loader[0]) ? get_class($loader[0]) : $loader[0]) . "::{$loader[1]}\n";
} elseif ($loader instanceof Closure) {
echo "Closure\n";
}
}
echo "</pre>";
}
たとえば、デバッグの背景に統合します。
// gitbox.net/tools/debug.php
require 'debug_tools.php';
dumpAutoloaders();
これにより、現在登録されているローダーを簡単に確認できます。
自動ローダーが存在するかどうかを判断するには、 spl_autoload_functions()によって返されたリストを使用して、それを適切な条件構造と組み合わせて正確な判断を達成できます。直接判断できない匿名の関数の場合、その後の判断またはキャンセルの登録中に参照を保存できます。合理的な使用の前提で、 SPL_AUTOLOAD_UNREGISTERは、システムの堅牢性と保守性を向上させるために、無効または競合するローダーを効果的にクリーンアップできます。