为简单的应用程序生成 PHAR
我正在尝试使用 Symfony2 控制台库构建 CLI 工具.我有一些基本的工作,现在我想把它打包成一个 phar.我已经阅读了一些示例,但我看到的示例非常简单(3 个文件,没有命名空间等).
I'm experimenting in building CLI tools using the Symfony2 console library. I've got something basic working and now I want to package it as a phar. I've read a few examples but the ones I've seen are very simple (3 files, no namespaces, etc).
在我的 src/
目录中,我有以下内容:
In my src/
directory I have the following:
在 src/
之上我有一个 console.php
我执行以运行应用程序.我也有一个 vendors/
目录,因为我正在使用 composer 安装依赖项.console.php
很简单:
Above src/
I have a console.php
that I execute to run the app. I also have a vendors/
dir as I'm using composer to install dependencies. console.php
is very simple:
#!/usr/bin/env php
<?php
set_time_limit(0);
$loader = require 'vendor/autoload.php';
use SymfonyComponentConsoleApplication;
use BendihossanPinfoCommandEnvironmentCommand;
use BendihossanPinfoCommandExtensionsCommand;
use BendihossanPinfoCommandRunAllCommand;
$console = new Application();
$console->add(new RunAllCommand());
$console->add(new EnvironmentCommand);
$console->add(new ExtensionsCommand);
$console->run();
根据我对构建 phar 的了解(很少),我认为我需要包含 console.php
作为存根以及 src/
中的所有其他内容以及我的所有依赖项在 vendors/
中.
From what (little) I understand about build a phar I think I need to include console.php
as the stub and everything else in src/
plus all my dependencies in vendors/
.
查看 phpmaster.com 上的示例代码,他们指定了每个文件使用 file_get_contents
手动将其包含在 phar 中,但我需要维护我的目录结构以使用 composer 的自动加载器并保持 PSR-0 目录结构.
Looking at the example code on phpmaster.com they specify every file manually to be included in the phar using file_get_contents
, but I need to maintain my directory structure in order to use the composer's autoloader and keep to PSR-0 directory structure.
有没有一种简单的方法可以创建 .phar 并在其中维护我的目录结构,以便我仍然可以使用 composer 的自动加载器?
推荐答案
建议你看看Composer 的 Compiler
(最初由 Fabien Potencier 在 Silex 创建).在该课程中,您可以看到像 Composer 这样的大型控制台应用程序如何创建 .phar
文件.
一些有趣的部分:
// line 49
$phar = new Phar($pharFile, 0, 'composer.phar');
$phar->setSignatureAlgorithm(Phar::SHA1);
$phar->startBuffering();
Phar#startBuffering
开始创建phar文件.
Phar#startBuffering
starts the creation of the phar file.
// Line 54
$finder = new Finder();
$finder->files()
->ignoreVCS(true)
->name('*.php')
->notName('Compiler.php')
->notName('ClassLoader.php')
->in(__DIR__.'/..')
在这里,Composer 使用 Symfony2 Finder 组件 来查找 src<中的每个文件/code> 目录(除了这个文件和自动加载器).
Here, Composer uses the Symfony2 Finder Component to find every file in the src
directory (except this file and the autoloader).
// Line 63
foreach ($finder as $file) {
$this->addFile($phar, $file);
}
在这里,Composer 遍历每个找到的文件并将其添加到 Phar 存档中.(您可以在 Compiler#addFile 方法>第 116 行).
Here, Composer iterates over every found file and adds it to the Phar archive. (you can see the Compiler#addFile
method on line 116).
这会重复几次.然后在第 93 行,使用了 Composer 自动加载器:
This is repeated some times. And then at line 93, the Composer autoloader is used:
$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 自动加载器仍然能够加载类.
Because Phar is a stream, the directory structure is kept in the phar file and the Composer autoloader is still able to load the classes.
然后,最后,添加存根并停止缓冲:
Then, at the end, the stubs are added and the buffering stopped:
$phar->setStub($this->getStub());
$phar->stopBuffering();
(请参阅 Compiler#getStub 方法)">第 173 行).Phar#stopBuffering
方法停止创建 phar 并将其保存到 phar 文件中.
(see the Compiler#getStub
method at line 173). The Phar#stopBuffering
method stops the creation of the phar and saves it to the phar file.
为了完成这个故事,Composer 创建了一个非常简单的 CLI 编译文件 来运行它命令.
To make this story complete, Composer creates a very simple CLI compile file which runs this command.
相关文章