2013-04-01 27 views
22

Eksperymentuję w tworzeniu narzędzi CLI przy użyciu biblioteki konsoli Symfony2. Mam coś podstawowego, a teraz chcę go spakować jako phara. Czytałem kilka przykładów, ale te, które widziałem, są bardzo proste (3 pliki, bez przestrzeni nazw itp.).Generowanie pliku PHAR dla prostej aplikacji

W moim katalogu src/ mam następujące:

enter image description here

Przede src/ Mam console.php że mogę wykonać, aby uruchomić aplikację. Posiadam także katalog vendors/, ponieważ używam programu composer do instalowania zależności. console.php jest bardzo prosta:

#!/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(); 

Z tego, co (mały) Rozumiem o budowie Phar Chyba trzeba dołączyć console.php jako odgałęzienie i wszystkiego innego w src/ powiększonej wszystkich moich uzależnień w vendors/.

Patrząc na kod przykład na phpmaster.com one określić każdy plik ręcznie, które należy uwzględnić w Phar wykorzystaniem file_get_contents, ale muszę utrzymać moją strukturę katalogów w celu wykorzystania autoloadery kompozytora i zachować do PSR-0 Katalogu struktury.

Czy istnieje prosty sposób na utworzenie .phar i utrzymanie w nim struktury katalogów, abym mógł nadal korzystać z autoloadera kompozytora?

Odpowiedz

22

Proponuję, abyś spojrzał na Composer's Compiler (początkowo został stworzony przez Fabien Potencier w Silex). W tej klasie można zobaczyć, jak duża aplikacja konsolowa, taka jak Composer, tworzy plik .phar.


Kilka ciekawych części:

// line 49 
$phar = new \Phar($pharFile, 0, 'composer.phar'); 
$phar->setSignatureAlgorithm(\Phar::SHA1); 

$phar->startBuffering(); 

Phar#startBuffering rozpoczyna tworzenie pliku Phar.

// Line 54 
$finder = new Finder(); 
$finder->files() 
    ->ignoreVCS(true) 
    ->name('*.php') 
    ->notName('Compiler.php') 
    ->notName('ClassLoader.php') 
    ->in(__DIR__.'/..') 

Tutaj Kompozytor wykorzystuje Symfony2 Finder Component znaleźć każdy plik w katalogu src (oprócz tego pliku i autoloaderze).

// Line 63 
foreach ($finder as $file) { 
    $this->addFile($phar, $file); 
} 

Tutaj kompozytor wykonuje iteracje po każdym znalezionym pliku i dodaje go do archiwum Phara. (możesz zobaczyć metodę Compiler#addFile na line 116).

Powtarza się to kilka razy. A następnie w wierszu 93, Autoloader Kompozytor stosuje się:

$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')); 

Ponieważ Phar jest strumień, struktura katalogów są przechowywane w pliku Phar i autoloader Kompozytor nadal jest w stanie załadować klas.

Następnie, na koniec, czopów i całość buforujący zatrzymane:

$phar->setStub($this->getStub()); 

$phar->stopBuffering(); 

(patrz metoda Compiler#getStub w line 173).Metoda Phar#stopBuffering zatrzymuje tworzenie phara i zapisuje go w pliku phara.

Aby uprościć tę historię, Composer tworzy bardzo prosty CLI compile file, który uruchamia to polecenie.

+2

Dzięki! Wygląda dokładnie tak, jak tego potrzebuję :) – Bendihossan

+8

@ Bendihossan Chciałbym również doradzić ci spojrzenie na [Box] (https://github.com/kherge/box) - małe narzędzie przeznaczone do budowania fars. Obsługuje wiele z tych samych rzeczy, które mamy w kompilatorze Composer, a niektóre z nich. – Seldaek