2013-04-01 52 views
22

我正在尝试使用Symfony2控制台库构建CLI工具。我有一些基本的工作,现在我想把它打包成一个phar。我读过几个例子,但我见过的例子非常简单(3个文件,没有名称空间等)。为简单应用程序生成PHAR

在我src/目录中,我有以下:

enter image description here

以上src/我有一个console.php,我执行运行应用程序。我还有一个vendors/ dir,因为我使用composer来安装依赖项。 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(); 

从什么(小),我了解构建药业我想我需要包括console.php作为存根,一切都在src/其他再加上我在vendors/所有的依赖。

综观上phpmaster.com示例代码,他们指定的每个文件手动将包含在使用file_get_contents中药业,但我必须保持我的目录结构,以使用作曲家的自动加载,并保持到PSR-0的目录结构。

是否有一种简单的方法来创建.phar并在其中维护我的目录结构,这样我仍然可以使用composer的自动加载器?

回答

22

我建议你看看Composer's Compiler(它最初是由Silex的Fabien Potencier创建的)。在该课程中,您可以看到Composer等大型控制台应用程序如何创建.phar文件。


一些有趣的部分:

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

$phar->startBuffering(); 

Phar#startBuffering开始药业文件的创建。

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

这里,作曲家使用Symfony2 Finder Component找到在src目录中的所有文件(除该文件和自动加载磁带机)。

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

在这里,Composer遍历每个找到的文件并将其添加到Phar存档。 (您可以在line 116上看到Compiler#addFile方法)。

这会重复一些。然后在线93中,作曲家自动加载机用于:

$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文件和作曲自动装载机仍然能够加载类。

然后,在结束时,短截线,并将该缓冲停止:

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

$phar->stopBuffering(); 

(见line 173Compiler#getStub方法)。Phar#stopBuffering方法停止创建phar并将其保存到phar文件。

为了完成这个故事,Composer创建了一个非常简单的CLI compile file,它运行此命令。

+2

谢谢!看起来完全像我需要的:) – Bendihossan

+8

@Bendihossan我还建议你看看[Box](https://github.com/kherge/box) - 一个专用于构建phars的小工具。它支持我们在Composer编译器中的许多相同的东西,然后支持一些。 – Seldaek