为简单应用程序生成 PHAR

我正在尝试使用Symfony2控制台库构建CLI工具。我有一些基本的工作,现在我想把它打包成一个phar。我已经阅读了一些示例,但我看到的那些非常简单(3个文件,没有命名空间等)。

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

enter image description here

上面我有一个我执行来运行应用程序。我也有一个dir,因为我正在使用作曲家来安装依赖项。 非常简单:src/console.phpvendors/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.phpsrc/vendors/

查看 phpmaster.com 的示例代码,他们手动指定每个文件都包含在 phar 中,但我需要维护我的目录结构,以便使用 composer 的自动加载器并保持 PSR-0 目录结构。file_get_contents

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


答案 1

我建议你看看Composer的编译器(它最初是由Fabien 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组件来查找目录中的每个文件(除了这个文件和自动加载器)。src

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

在这里,Composer 迭代每个找到的文件,并将其添加到 Phar 存档中。(您可以在第 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();

(请参阅第 173 行的方法)。Phar#stopBuffering 方法停止创建 phar 并将其保存到 phar 文件中。Compiler#getStub

为了使这个故事完整,Composer 创建了一个非常简单的 CLI 编译文件来运行此命令。


答案 2

推荐