2

Is there anyway to use a custom autoloader with Composer?

I have some libraries with many hundreds of classes, they are laid out in the directory structure as per PSR-0.

However they also include a static contructor (similar to Java's static initializer).

My autoloader I was using before composer would:

if (method_exists($class, '__static')) {
    call_user_func(array($class, '__static'));
}

So is there anyway to extend Composers default autoloader to also do this?

4

3 に答える 3

5

ハッキング作曲家

これをサポートするために Composer のオートローダーをハックして、以下を変更することができますClassLoader.php(vendor ディレクトリ内にあります):

public function loadClass($class)
{
    if ($file = $this->findFile($class)) {
        include $file;

        // Added your custom code:
        if (method_exists($class, '__static')) {
            call_user_func(array($class, '__static'));
        }

        return true;
    }
}

ただし、このファイルは実行するたびに更新されますcomposer update(ソースは 内に含まれていますcomposer.phar)。この変更を「永続的」にする方法が必要です。

私が考えることができる2つの方法があります:

Composer 自体の変更

この解決策には の変更が含まcomposer.pharれます。つまり、次のことを意味します。

  • 変更が実行されると、ハッキングは追加の設定なしで常に有効になります
  • 実行composer self-updateすると、変更された Composer ソースが最新の公式バージョンで上書きされ、ハックが取り消されます

Composer ソースでターゲットを絞った検索/置換を実行する短い PHP スクリプトを作成しました。対象となる正確なコードのみを変更します。つまり、変更されていないバージョンの Composer で毎回実行する必要があります (既に変更されたバージョンに触れることは拒否されます)。

<?php

if (!Phar::canWrite()) {
    die ('The config setting phar.readonly must be set to 0 in php.ini');
}

$phar = new Phar('composer.phar');
$fileName = 'src/Composer/Autoload/ClassLoader.php';

try {
    $source = file_get_contents($phar[$fileName]);
}
catch (BadMethodCallException $e) {
    echo $e->getMessage();
    die;
}

$find = <<<'END_ORIGINAL'
    public function loadClass($class)
    {
        if ($file = $this->findFile($class)) {
            include $file;

            return true;
        }
    }
END_ORIGINAL;

$replaceWith = <<< 'END_REPLACEMENT'
    public function loadClass($class)
    {
        if ($file = $this->findFile($class)) {
            include $file;

            // Add your custom code here!
            return true;
        }
    }
END_REPLACEMENT;

$find = preg_replace('/\s+/', '\\s+', preg_quote($find));
$modified = preg_replace('/'.$find.'/', $replaceWith, $source);

if ($source == $modified) {
    echo 'Could not find replacement target, aborting';
    die;
}

file_put_contents($phar[$fileName], $modified);
echo 'Replacement done, file saved';

更新後スクリプトの使用

Composer では、ルート パッケージにスクリプトを添付できます。変更する更新後スクリプトClassLoader.phpは、Composer のソースをそのまま残しながら、更新間で変更を保持するための良い方法です。

これを行うために、前のセクションのコードを適応させるのは非常に簡単です。スクリプトは静的な PHP クラス メソッドであることが理想ですが、これを行うには、Composer の PSR-0 オートローダーを使用して自動ロードする新しい Composer パッケージを作成する必要があります。これは、クラスを自動ロードする必要があり、現在、 classmap を使用してクラスを自動ロードすることができないためです。 Composer の更新プロセス中。

于 2013-01-16T09:35:31.167 に答える
0

私がやったことは次のとおりです。

  • 変更するvendor/composer/ClassLoader.php
  • プロジェクトにロードされた変更されたクラスをコミットします (ただし、ベンダー ディレクトリの残りの部分は無視します)。
  • git checkout vendor/composer/ClassLoader.phpcomposer update
于 2013-01-16T23:16:20.267 に答える