打包 PHP 个应用程序
Packaging a PHP application
我正在尝试从我的 Web 应用程序创建一个 .phar 文件。在 php documentation's example 之后,我为此尝试了以下操作。
<?php
$srcRoot = __DIR__ . "/../app";
$buildRoot = __DIR__ . "/../build";
$p = new Phar("$buildRoot/build.phar", 0, 'build.phar');
$p->buildFromIterator(
new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($srcRoot)
),
$srcRoot
);
但是我得到了以下错误。我不知道这个错误。代码有什么问题?
PHP Fatal error: Uncaught exception 'UnexpectedValueException' with message
'Iterator RecursiveIteratorIterator returned a path "D:\site\app" that is
not in the base directory "D:\site\app"'
in D:\site\tools\create-phar.php:7
Box 使从您的源文件创建 PHAR 档案变得非常容易。基本上你首先添加一个配置文件,然后你可以通过简单地在命令行上调用 box build
来创建你的 PHAR 文件。
Matthieu Moquet 在 great blog post 中描述了他如何使用 Box 来简化 PHP Cli 应用程序的分发。就个人而言,我也一直在使用 Box 作为 CLI 应用程序,但是官方的项目描述并不局限于 CLI 应用程序,而是将 Box 项目总结为:
An application for building and managing Phars.
Box 项目提供 PHAR 构建脚本并负责正确设置所有路径,因此这可能会解决您的问题。
查看 php.ini 文件以检查 phar.readonly 字段的值。
必须为 0 才能创建 phar 存档。
参考:http://php.net/manual/en/phar.configuration.php#ini.phar.readonly
问题的根源在于 RecursiveDirectoryIterator
还列出了点文件 - .
和 ..
。
当遍历 /path/to/foo
时,它还会列出 /path/to/foo/.
和 /path/to/foo/..
,它们转到父目录 - 在基本目录之外。
因此您必须防止包含“..”文件,这最容易通过 FilesystemIterator::SKIP_DOTS
作为 DirectoryIterator 的第二个参数来实现:
new RecursiveDirectoryIterator($srcRoot, FilesystemIterator::SKIP_DOTS)
(@cweiske -- 我刚刚意识到你抢先了我,下次我一定会刷新页面,我最诚挚的歉意!)
您只需稍加编辑即可跳过 unix 路径 /。和/..:[=11=]
<?php
$srcRoot = __DIR__ . "/../app";
$buildRoot = __DIR__ . "/../build";
$p = new Phar("$buildRoot/build.phar", 0, 'build.phar');
$p->buildFromIterator(
new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($srcRoot, FilesystemIterator::SKIP_DOTS)
),
$srcRoot
);
@cweiske提出的解决方案非常棒。但是,在某些情况下,您可能需要能够添加更多目录路径排除项。查看此示例,使用 FilterIterator
:
排除对 .git
目录的任何引用
// create phar
$p = new Phar($pharFile, 0, $pharFile);
// produce iteration which excludes any references to values assigned to $excludes
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS)
);
$filter = new class($iterator) extends FilterIterator {
public static $excludes = [];
public function accept()
{
$item = $this->current();
$actual = 0;
foreach (self::$excludes as $exclude) {
$actual += (int) boolval(strpos($item->getPath(), $exclude));
}
return ($actual === 0);
}
};
$filter::$excludes = ['.git'];
$p->buildFromIterator($filter, $path);
我正在尝试从我的 Web 应用程序创建一个 .phar 文件。在 php documentation's example 之后,我为此尝试了以下操作。
<?php
$srcRoot = __DIR__ . "/../app";
$buildRoot = __DIR__ . "/../build";
$p = new Phar("$buildRoot/build.phar", 0, 'build.phar');
$p->buildFromIterator(
new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($srcRoot)
),
$srcRoot
);
但是我得到了以下错误。我不知道这个错误。代码有什么问题?
PHP Fatal error: Uncaught exception 'UnexpectedValueException' with message
'Iterator RecursiveIteratorIterator returned a path "D:\site\app" that is
not in the base directory "D:\site\app"'
in D:\site\tools\create-phar.php:7
Box 使从您的源文件创建 PHAR 档案变得非常容易。基本上你首先添加一个配置文件,然后你可以通过简单地在命令行上调用 box build
来创建你的 PHAR 文件。
Matthieu Moquet 在 great blog post 中描述了他如何使用 Box 来简化 PHP Cli 应用程序的分发。就个人而言,我也一直在使用 Box 作为 CLI 应用程序,但是官方的项目描述并不局限于 CLI 应用程序,而是将 Box 项目总结为:
An application for building and managing Phars.
Box 项目提供 PHAR 构建脚本并负责正确设置所有路径,因此这可能会解决您的问题。
查看 php.ini 文件以检查 phar.readonly 字段的值。 必须为 0 才能创建 phar 存档。
参考:http://php.net/manual/en/phar.configuration.php#ini.phar.readonly
问题的根源在于 RecursiveDirectoryIterator
还列出了点文件 - .
和 ..
。
当遍历 /path/to/foo
时,它还会列出 /path/to/foo/.
和 /path/to/foo/..
,它们转到父目录 - 在基本目录之外。
因此您必须防止包含“..”文件,这最容易通过 FilesystemIterator::SKIP_DOTS
作为 DirectoryIterator 的第二个参数来实现:
new RecursiveDirectoryIterator($srcRoot, FilesystemIterator::SKIP_DOTS)
(@cweiske -- 我刚刚意识到你抢先了我,下次我一定会刷新页面,我最诚挚的歉意!)
您只需稍加编辑即可跳过 unix 路径 /。和/..:[=11=]
<?php
$srcRoot = __DIR__ . "/../app";
$buildRoot = __DIR__ . "/../build";
$p = new Phar("$buildRoot/build.phar", 0, 'build.phar');
$p->buildFromIterator(
new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($srcRoot, FilesystemIterator::SKIP_DOTS)
),
$srcRoot
);
@cweiske提出的解决方案非常棒。但是,在某些情况下,您可能需要能够添加更多目录路径排除项。查看此示例,使用 FilterIterator
:
.git
目录的任何引用
// create phar
$p = new Phar($pharFile, 0, $pharFile);
// produce iteration which excludes any references to values assigned to $excludes
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS)
);
$filter = new class($iterator) extends FilterIterator {
public static $excludes = [];
public function accept()
{
$item = $this->current();
$actual = 0;
foreach (self::$excludes as $exclude) {
$actual += (int) boolval(strpos($item->getPath(), $exclude));
}
return ($actual === 0);
}
};
$filter::$excludes = ['.git'];
$p->buildFromIterator($filter, $path);