【问题标题】:Generating a PHAR for a simple application为简单的应用程序生成 PHAR
【发布时间】:2016-10-04 01:29:40
【问题描述】:

我正在尝试使用 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 的自动加载器?

【问题讨论】:

    标签: php packaging composer-php phar symfony-components


    【解决方案1】:

    我建议你看看Composer's Compiler(它最初是由 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 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 来运行这个命令。

    【讨论】:

    • 谢谢!看起来完全像我需要的:)
    • @Bendihossan 我还建议您查看Box - 一个专门用于构建 phars 的小实用程序。它支持我们在 Composer 编译器中拥有的大部分相同的东西,然后还有一些。
    猜你喜欢
    • 2011-04-04
    • 2012-08-01
    • 2014-09-12
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    • 2018-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多