PHPのパッケージマネージャであるComposerには、インストールしたパッケージのオートロード機能が用意されています。
"vendor/autoload.php"をrequireするだけでパッケージ内のクラスをnew出来るのは非常に便利ですが、自作したパッケージを利用する場合、インストールしたパッケージが自動でnew出来ない場合があります。問題の原因は大抵スペルミスだったり自作したパッケージのcomposer.jsonの定義ミスだったりするのですが、自動で処理してくれる分、問題の切り分けが難しいです。
このような場合、Composerが提供するautoloaderに対してログを出力させることで解決の手助けになります。
実は、composerのautoload.phpはrequire文の戻り値としてクラスローダーオブジェクト(Composer\Autoload\ClassLoader)をリターンしてくれます。下記のコードでComposer\Autoload\ClassLoaderオブジェクトが取得できます。
$autoloader = require "vendor/autoload.php";
あるクラスが、どのファイルからロードされるかを確認する
findFile()メソッドを指定すると、指定したファイルがどのディレクトリからロードしようとするか確認できます。下記のコードはMonolog\Loggerクラスがautoload出来るかをチェックするためのプログラムです。
$autoloader = require "vendor/autoload.php";
$result = $autoloader->findFile('Monolog\Logger');
echo json_encode($result) . "\n";
実行結果は下記のような形式で、キーがネームスペース、値がディレクトリ名となる連想配列が集まった配列が取得できます。
> php .\index.php
"C:\\work\\vendor\\composer\/..\/monolog\/monolog\/src\/Monolog\\Logger.php"
Composerのロード先フォルダマッピング一覧をダンプ
たいていの場合、composerでインストールしたパッケージはPSR-4準拠かと思います。下記のコードでPSR-4準拠の各クラスに対して、各クラスがロードされるディレクトリの場所を確認できます。
$autoloader = require "vendor/autoload.php";
echo json_encode($autoloader->getPrefixesPsr4(), JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
実行結果は下記の通りです。
{
"Psr\\Http\\Message\\": [
"C:\\work\\vendor\\composer/../psr/http-message/src"
],
"GuzzleHttp\\Psr7\\": [
"C:\\work\\vendor\\composer/../guzzlehttp/psr7/src"
],
"GuzzleHttp\\Promise\\": [
"C:\\work\\vendor\\composer/../guzzlehttp/promises/src"
],
"GuzzleHttp\\": [
"C:\\work\\vendor\\composer/../guzzlehttp/guzzle/src"
]
}
コマンドラインからワンライナーで確認する
コマンドラインからワンライナーで確認したい場合は、下記のコマンドで出力できます。
php -r "echo json_encode((require 'vendor/autoload.php')->getPrefixesPsr4(), JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);"
ClassLoaderから取得できる全情報をダンプする
ロードするフォルダだけでなく、composerのClassLoaderから取得できるすべての情報をダンプしたい場合は、下記の関数を使用すればよいです。
$autoloader = require "vendor/autoload.php";
dumpAutoloader($autoloader);
function dumpAutoloader( $autoloader ) {
$opt = JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES;
echo "-----------------------------------------\n";
echo "# Autoloader setting\n";
echo "- class name\n";
echo get_class($autoloader) . "\n\n";
echo "## getPrefixes\n";
$results = $autoloader->getPrefixes();
echo json_encode($results, $opt) . "\n\n";
echo "## getPrefixesPsr4\n";
$results = $autoloader->getPrefixesPsr4();
echo json_encode($results, $opt) . "\n\n";
echo "## FallbackDir\n";
$results = $autoloader->getFallbackDirs();
echo json_encode($results, $opt) . "\n\n";
echo "## FallbackDirPsr4\n";
$results = $autoloader->getFallbackDirsPsr4();
echo json_encode($results, $opt) . "\n\n";
echo "## ClassMap\n";
$results = $autoloader->getClassMap();
echo json_encode($results, $opt) . "\n\n";
echo "## isClassMapAuthoritative\n";
$results = $autoloader->isClassMapAuthoritative();
echo json_encode($results, $opt) . "\n\n";
echo "## UseIncludePath\n";
$results = $autoloader->getUseIncludePath();
echo json_encode($results, $opt) . "\n\n";
echo "## ApcuPrefix\n";
$results = $autoloader->getApcuPrefix();
echo json_encode($results, $opt) . "\n\n";
}
PSR-4対応準拠のmonologをインストールした環境で上記のコードを実行すると、以下のログが出力されます。
-----------------------------------------
# Autoloader setting
- class name
Composer\Autoload\ClassLoader
## getPrefixes
[]
## getPrefixesPsr4
{
"Psr\\Log\\": [
"C:\\work\\vendor\\composer/../psr/log/Psr/Log"
],
"Monolog\\": [
"C:\\work\\vendor\\composer/../monolog/monolog/src/Monolog"
]
}
## FallbackDir
[]
## FallbackDirPsr4
[]
## ClassMap
[]
## isClassMapAuthoritative
false
## UseIncludePath
false
## ApcuPrefix
null
次はPearパッケージであるHTTP_Request2がインストールされた環境での出力です。先ほどの出力とは異なりgetPrefixesとClassMapに設定が表示されていることが分かります。
HTTP_Request2のインストール
composer require pear/http_request2
HTTP_Request2インストール環境での出力結果
-----------------------------------------
# Autoloader setting
- class name
Composer\Autoload\ClassLoader
## getPrefixes
{
"PEAR": [
"C:\\work\\vendor\\composer/../pear/pear_exception"
],
"HTTP_Request2": [
"C:\\work\\vendor\\composer/../pear/http_request2"
]
}
## getPrefixesPsr4
[]
## FallbackDir
[]
## FallbackDirPsr4
[]
## ClassMap
{
"Net_URL2": "C:\\work\\vendor\\composer/../pear/net_url2/Net/URL2.php"
}
## isClassMapAuthoritative
false
## UseIncludePath
false
## ApcuPrefix
null
4 thoughts on “[PHP]ComposerでAutoload出来ない時の確認方法”