我正在尝试使用Symfony2控制台库构建CLI工具。我有一些基本的工作,现在我想把它打包成一个phar。我已经阅读了一些例子,但我看到的很简单(3个文件,没有命名空间等)。
在我的src/
目录中,我有以下内容:
高于src/
我执行了console.php
来运行应用。我还有一个vendors/
目录,因为我正在使用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();
从我对构建一个phar的理解(我很少)我认为我需要将console.php
作为存根和src/
中的所有其他内容以及vendors/
中的所有依赖项。
查看phpmaster.com上的示例代码,他们使用file_get_contents
手动指定每个文件包含在phar中,但我需要维护我的目录结构才能使用composer的自动加载器并保持PSR-0目录结构。
有没有一种简单的方法来创建.phar并在其中维护我的目录结构,所以我仍然可以使用composer的自动加载器?
答案 0 :(得分:23)
我建议你看一下Composer's Compiler
(它最初是由Fabile Potencier在Silex创作的)。在该类中,您可以看到像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存档中。 (您可以在line 116上看到Compiler#addFile
方法。)
这种情况有些重复。然后在第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();
(请参阅line 173处的Compiler#getStub
方法)。 Phar#stopBuffering
方法停止创建phar并将其保存到phar文件中。
为了完成这个故事,Composer创建了一个非常简单的CLI compile file来运行此命令。