为简单的应用程序生成PHAR

Ben*_*san 24 php packaging phar composer-php symfony-components

我正在尝试使用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();
Run Code Online (Sandbox Code Playgroud)

从我对构建一个phar的理解(我很少)我认为我需要将其console.php作为存根和其他所有内容src/添加到我的所有依赖项中vendors/.

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

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

Wou*_*r J 23

我建议你看一看作曲家Compiler(它最初是由法比安斯基Potencier在Silex的创建).在该类中,您可以看到像Composer这样的大型控制台应用程序如何创建该.phar文件.


一些有趣的部分:

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

$phar->startBuffering();
Run Code Online (Sandbox Code Playgroud)

Phar#startBuffering 开始创建phar文件.

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

在这里,作曲家使用Symfony2的搜索组件找到在每个文件src目录(除该文件和自动加载磁带机).

// Line 63
foreach ($finder as $file) {
    $this->addFile($phar, $file);
}
Run Code Online (Sandbox Code Playgroud)

在这里,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'));
Run Code Online (Sandbox Code Playgroud)

由于Phar是一个流,因此目录结构保存在phar文件中,而Composer自动加载器仍然可以加载类.

然后,最后,添加存根并停止缓冲:

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

$phar->stopBuffering();
Run Code Online (Sandbox Code Playgroud)

(参见第173行Compiler#getStub方法).该方法停止创建phar并将其保存到phar文件.Phar#stopBuffering

为了完成这个故事,Composer创建了一个非常简单的CLI 编译文件,它运行此命令.

  • @Bendihossan我还建议你看看[Box](https://github.com/kherge/box) - 一个专门用于构建phars的小工具.它支持我们在Composer编译器中使用的大部分内容,然后是一些. (9认同)
  • 谢谢!看起来完全像我需要:) (2认同)