[PHP]ComposerでAutoload出来ない時の確認方法

カテゴリ: composer

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


Modern PHP

こちらもおススメ

4 thoughts on “[PHP]ComposerでAutoload出来ない時の確認方法

  1. ピンバック: Saba note

コメントを残す

メールアドレスが公開されることはありません。