PHP Conference Japan 2024

Phar::buildFromIterator

(PHP 5 >= 5.3.0, PHP 7, PHP 8, PECL phar >= 2.0.0)

Phar::buildFromIterator从迭代器构建 phar 归档

描述

public Phar::buildFromIterator(Traversable $iterator, ?string $baseDirectory = null): array

注意:

此方法需要 php.ini 设置 phar.readonly0 才能对 Phar 对象生效。否则,将抛出 PharException 异常。

从迭代器填充 phar 归档。支持两种类型的迭代器:一种将 phar 中的文件名映射到磁盘上文件的名称,另一种像 DirectoryIterator 一样返回 SplFileInfo 对象。对于返回 SplFileInfo 对象的迭代器,需要第二个参数。

参数

iterator

任何迭代器,它要么关联地将 phar 文件映射到位置,要么返回 SplFileInfo 对象。

baseDirectory

对于返回 SplFileInfo 对象的迭代器,在添加到 phar 归档时要移除的每个文件的完整路径的部分。

返回值

Phar::buildFromIterator() 返回一个关联数组,将文件的内部路径映射到文件系统上文件的完整路径。

错误/异常

当迭代器返回不正确的值(例如,整数键而不是字符串)时,此方法返回 UnexpectedValueException;当传递基于 SplFileInfo 的迭代器但没有 baseDirectory 参数时,返回 BadMethodCallException;如果保存 phar 归档时出错,则返回 PharException

变更日志

版本 描述
8.1.0 Phar::buildFromIterator() 不再返回 false
8.0.0 baseDirectory 现在可以为空。

示例

示例 #1 使用 SplFileInfo 的 Phar::buildFromIterator()

对于大多数 phar 归档,归档将反映实际的目录布局,第二种样式是最有用的。例如,要创建包含此示例目录布局中文件的 phar 归档

/path/to/project/
                 config/
                        dist.xml
                        debug.xml
                 lib/
                     file1.php
                     file2.php
                 src/
                     processthing.php
                 www/
                     index.php
                 cli/
                     index.php

此代码可用于将这些文件添加到 "project.phar" phar 归档中

<?php
// 使用别名 "project.phar" 创建
$phar = new Phar('project.phar', 0, 'project.phar');
$phar->buildFromIterator(
new
RecursiveIteratorIterator(
new
RecursiveDirectoryIterator('/path/to/project')),
'/path/to/project');
$phar->setStub($phar->createDefaultStub('cli/index.php', 'www/index.php'));
?>

然后可以立即使用文件 project.phar。Phar::buildFromIterator() 不会设置压缩、元数据等值,这可以在创建 phar 归档后完成。

有趣的是,Phar::buildFromIterator() 也可用于复制现有 phar 归档的内容,因为 Phar 对象继承自 DirectoryIterator

<?php
// 使用别名 "project.phar" 创建
$phar = new Phar('project.phar', 0, 'project.phar');
$phar->buildFromIterator(
new
RecursiveIteratorIterator(
new
Phar('/path/to/anotherphar.phar')),
'phar:///path/to/anotherphar.phar/path/to/project');
$phar->setStub($phar->createDefaultStub('cli/index.php', 'www/index.php'));
?>

示例 #2 使用其他迭代器的 Phar::buildFromIterator()

第二种形式的迭代器可以与任何返回键=>值映射的迭代器一起使用,例如 ArrayIterator

<?php
// 使用别名 "project.phar" 创建
$phar = new Phar('project.phar', 0, 'project.phar');
$phar->buildFromIterator(
new
ArrayIterator(
array(
'internal/file.php' => dirname(__FILE__) . '/somefile.php',
'another/file.jpg' => fopen('/path/to/bigfile.jpg', 'rb'),
)));
$phar->setStub($phar->createDefaultStub('cli/index.php', 'www/index.php'));
?>

参见

添加注释

用户贡献的注释 2 条注释

cweiske at php dot net
9 年前
您必须在 RecursiveDirectoryIterator 上设置一个标志,因为默认情况下,当前目录(".")和父目录("..")包含在列表中。这会导致类似于“返回的路径“..”不在基目录中”的错误消息。

要解决此问题,请使用“SKIP_DOTS”

<?php
new RecursiveDirectoryIterator(
$srcRoot, FilesystemIterator::SKIP_DOTS
);
?>
M8
7 年前
从迭代器创建的 Phar(不像从目录创建的)没有完整的目录结构。例如,像 opendir() 这样的函数会失败,尽管 fopen() 不会。
To Top