Ответ 1
Я предлагаю вам взглянуть на Composer Compiler
(он был первоначально создан Фабием Потеньером в Силексе). В этом классе вы можете увидеть, как большое консольное приложение, например Composer, создает файл .phar
.
Некоторые интересные части:
// line 49
$phar = new \Phar($pharFile, 0, 'composer.phar');
$phar->setSignatureAlgorithm(\Phar::SHA1);
$phar->startBuffering();
Phar#startBuffering
начинает создание файла phar.
// Line 54
$finder = new Finder();
$finder->files()
->ignoreVCS(true)
->name('*.php')
->notName('Compiler.php')
->notName('ClassLoader.php')
->in(__DIR__.'/..')
Здесь Composer использует Symfony2 Finder Component, чтобы найти каждый файл в каталоге src
(кроме этого файла и автозагрузчика).
// Line 63
foreach ($finder as $file) {
$this->addFile($phar, $file);
}
Здесь Composer выполняет итерацию по каждому найденному файлу и добавляет его в архив Phar. (вы можете увидеть метод Compiler#addFile
на строке 116).
Это повторяется несколько раз. А затем на линии 93 используется автозагрузчик Composer:
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/autoload.php'));
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_namespaces.php'));
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_classmap.php'));
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_real.php'));
Поскольку Phar - это поток, структура каталогов хранится в файле phar, а автозагрузчик Composer все еще может загружать классы.
Затем в конце добавляются заглушки и останавливается буферизация:
$phar->setStub($this->getStub());
$phar->stopBuffering();
(см. метод Compiler#getStub
на строке 173). Метод Phar#stopBuffering
останавливает создание phar и сохраняет его в файле phar.
Чтобы сделать эту историю полной, Composer создает очень простой CLI файл компиляции, который выполняет эту команду.