2014-04-17 4 views
0

Открытый поставщик/композитор/autoload_real.php и посмотреть на этот код:Почему Composer загружает ClassLoader таким образом?

public static function loadClassLoader($class) 
{ 
    if ('Composer\Autoload\ClassLoader' === $class) { 
     require __DIR__ . '/ClassLoader.php'; 
    } 
} 

Когда:

spl_autoload_register(array('ComposerAutoloaderInitf06647a07a90b762eb34553a7bce155e', 'loadClassLoader'), true, true); 
    self::$loader = $loader = new \Composer\Autoload\ClassLoader(); 
    spl_autoload_unregister(array('ComposerAutoloaderInitf06647a07a90b762eb34553a7bce155e', 'loadClassLoader')); 

Почему Composer это сделать? И не так:

require_once __DIR__ . '/ClassLoader.php'; 
self::$loader = $loader = new \Composer\Autoload\ClassLoader(); 

ответ

2

Причина в том, что несколько автопогрузчики могут присутствовать одновременно в одном процессе, если, например, вы запускаете PHPUnit, установленный с помощью композитора, то файл начальной загрузки тест будет также включать в свой проект класса загрузчик, и поэтому, если мы сделали простой require, он переопределит класс ClassLoader и сделает фатальную ошибку. Использование require_once не будет работать, так как файл ClassLoader.php присутствует дважды (один в PHPUnit, один в проекте) с разными путями. PHP все равно будет включать каждый из них один раз, что приведет к переопределению класса.

Это может быть исправлено с помощью простого if (!class_exists()) {} вокруг требуемого, но, к сожалению, такое условное определение класса испортило APC на сайтах с высоким трафиком, поэтому нам пришлось прибегнуть к этому странному временному взлому автозагрузчика, чтобы он работал повсюду.

+0

Почему бы не использовать 'require_once' для этого? – Medvedev

+0

@Medvedev Я обновил ответ, чтобы объяснить это. – Seldaek

Смежные вопросы