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.readonly 設為 0 才能作用於 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 現在可以為 null。

範例

範例 #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 物件繼承自 DirectoryIteratorPhar::buildFromIterator() 也可用於複製現有 Phar 封存的內容。

<?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 沒有完整的目錄結構。例如,即使 fopen() 可以運作, opendir() 之類的函式也會失敗。
To Top