Подтвердить что ты не робот

Создание PHAR для простого приложения

Я экспериментирую в создании инструментов CLI с помощью библиотеки консоли Symfony2. У меня есть что-то основное, и теперь я хочу упаковать его как phar. Я прочитал несколько примеров, но те, которые я видел, очень просты (3 файла, не пространства имен и т.д.).

В моем каталоге src/ у меня есть следующее:

enter image description here

Выше src/ У меня есть console.php, который я запускаю для запуска приложения. У меня также есть vendors/ dir, поскольку я использую компоновщик для установки зависимостей. console.php очень просто:

#!/usr/bin/env php
<?php

set_time_limit(0);
$loader = require 'vendor/autoload.php';

use Symfony\Component\Console\Application;
use Bendihossan\Pinfo\Command\EnvironmentCommand;
use Bendihossan\Pinfo\Command\ExtensionsCommand;
use Bendihossan\Pinfo\Command\RunAllCommand;

$console = new Application();

$console->add(new RunAllCommand());
$console->add(new EnvironmentCommand);
$console->add(new ExtensionsCommand);

$console->run();

От чего (мало) я понимаю о создании phar. Думаю, мне нужно включить console.php в качестве заглушки и все остальное в src/ плюс все мои зависимости в vendors/.

Посмотрев пример кода на phpmaster.com, он укажет каждый файл вручную для включения в phar с помощью file_get_contents, но мне нужно для поддержки моей структуры каталогов для использования автозагрузчика композитора и сохранения структуры каталогов PSR-0.

Есть ли простой способ создать .phar и поддерживать структуру каталогов внутри него, поэтому я все еще могу использовать автозагрузчик композитора?

4b9b3361

Ответ 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 файл компиляции, который выполняет эту команду.