ホームページ  >  記事  >  バックエンド開発  >  PHP の圧縮とアーカイブ - Phar

PHP の圧縮とアーカイブ - Phar

伊谢尔伦
伊谢尔伦オリジナル
2016-11-22 09:45:471124ブラウズ

Phar アーカイブの概念は、Java™ テクノロジーの JAR アーカイブに由来しており、これにより、アプリケーションの実行に必要なものがすべて含まれた単一のファイルでアプリケーションをパッケージ化できます。このファイルは、実際にはコンパイルされたアプリケーションではなくアーカイブ ファイルであるという点で、通常 C などのプログラミング言語によって生成される単一の実行可能ファイルとは異なります。したがって、JAR ファイルには実際にはアプリケーションを構成するファイルが含まれていますが、セキュリティ上の理由からこれらのファイルは慎重に区別されていません。 Phar 拡張機能も同様の概念に基づいていますが、主に PHP の Web 環境向けに設計されています。また、JAR アーカイブとは異なり、Phar アーカイブは PHP 自体で処理できるため、作成または使用するために追加のツールは必要ありません。

Phar 拡張機能は、PHP にとって新しい概念ではありません。これはもともと PHP で書かれ、2005 年に PEAR ライブラリに追加される前は PHP_Archive という名前でした。ただし、実際には、この問題に対する純粋な PHP ソリューションは非常に遅かったため、2007 年に純粋な C 言語拡張機能として書き直され、SPL の ArrayAccess オブジェクトを使用した Phar アーカイブの走査のサポートが追加されました。それ以来、Phar アーカイブのパフォーマンスを向上させるために多くの作業が行われてきました。

Phar の作成

Phar ファイルの作成にはいくつかの手順が必要です。アーカイブを作成するためのスタンドアロン ツールがないため、作成を完了するにはすべての手順で何らかの形式の PHP コマンドが必要です。さらに、Phar ファイルを作成および変更するには、php.ini 設定 phar.readonly を 0 に設定する必要があります。 PHP の Phar アーカイブ内のファイルを開いて参照する場合、この設定は必要ありません。

アプリケーションの駆動に使用できる Phar ファイルの作成に必要な手順を見てみましょう。アプリケーションは、Web ブラウザーまたはコマンド プロンプトから直接ロードされるように設計されています。最初のステップは Phar ファイルを作成することなので、リスト 1 に示す Phar オブジェクトを作成します。オブジェクト参照を使用すると、Phar アーカイブのあらゆる側面を制御できます。

例 1. Phar オブジェクトを作成する

$p = new Phar('/path/to/my.phar', CURRENT_AS_FILEINFO | KEY_AS_FILENAME, 'my.phar');
$p->startBuffering();

コンストラクターの最初のパラメーターは、Phar ファイルが保存される場所を示します。 2 番目のパラメーターは、すべてのパラメーターを RecursiveDirectoryIterator 親クラスに渡します。 3 番目のパラメーターは、ストリーム コンテキストで Phar アーカイブを参照するエイリアスです。したがって、リスト 1 では、phar://my.phar を使用して、この Phar アーカイブ内のファイルを参照できます。 Phar::startBuffering() メソッド呼び出しを発行して、Phar::stopBuffering() コマンドが発行されるまでアーカイブへの変更をバッファリングすることもできます。上記を実行する必要はありませんが、これを実行すると、スクリプトでアーカイブが変更されるたびに変更を保存する必要がなくなるため、アーカイブの作成または変更のパフォーマンスが向上します。

デフォルトでは、作成された Phar はネイティブの Phar ベースのアーカイブ形式を使用します。リスト 2 に示すように、形式を ZIP 形式に変換することで、Phar ファイルで ZIP または TAR 形式を使用することもできます。
例 2. 保存形式を ZIP 形式に変換する

$p = $p->convertToExecutable(Phar::ZIP);


アーカイブ形式の変換には長所と短所があります。主な利点は、ZIP または TAR ファイルを処理するツールを使用してアーカイブの内容を表示できることです。ただし、Phar アーカイブがネイティブの Phar ベースのアーカイブ形式を使用しない場合は、ZIP または TAR 形式を使用する Phar アーカイブで必要となる、アーカイブのロードに Phar 拡張機能を使用する必要はありません。

次に、ファイル スタブを定義する必要があります。これは、Phar ファイルをロードするときに最初に呼び出されるコードです。

Phar ファイル スタブ

ファイル スタブは、Phar ファイルがロードされたときに最初に実行されるコードのほんの一部であり、常に __HALT_COMPILER() タグで終わります。リスト 3 は、典型的なファイル スタブを示しています。
例 3. Phar ファイル スタブ

<?php
    Phar::mapPhar();
    include &#39;phar://myphar.phar/index.php&#39;;
    __HALT_COMPILER();

上記の Phar::mapPhar() メソッド呼び出しは、マニフェスト ファイルを読み取ることによって Phar アーカイブを初期化します。アーカイブ内のファイルを参照する前に、phar:// ストリーム ラッパーを使用して初期化を実行する必要があります。最初にロードされるファイルは、アプリケーションが最初にロードされるときのファイルです。この場合は、index.php です。

このファイル スタブ Phar を Phar アーカイブに追加する方法は、使用されるアーカイブの形式によって異なります。 Phar ベースのアーカイブの場合は、Phar::setStub() メソッドを使用します。このメソッドは、PHP コードの単一の引数を受け入れ、それを文字列としてスタブに入れます。リスト 4 は、このアプローチを示しています。
例 4. Phar::setStub() を使用してファイル スタブを作成する

$p->setStub(&#39;<?php Phar::mapPhar(); 
include &#39;phar://myphar.phar/index.php&#39;; __HALT_COMPILER(); ?>&#39;);

操作を完了するために、index.php ページにリダイレクトする代わりにスタブを使用する場合は、ヘルパー メソッド Phar::createDefaultStub( ) ファイルスタブを構築します。したがって、ファイル スタブに含めたいファイルの名前を渡すだけです。リスト 5 では、ヘルパー メソッドを使用するために Phar::setStub() メソッド呼び出しがオーバーライドされています。

例 5. Phar::createDefaultStub() を使用してファイル スタブを作成する

$p->setStub($p-> createDefaultStub(&#39;index.php&#39;));


    如果从 Web 服务器加载 Phar,Phar::createDefaultStub() 方法的第二个可选参数允许包含一个不同的文件。这对于设计用于命令行或 Web 浏览器上下文的应用程序非常方便。

对于基于 ZIP 和 TAR 的实现,将以上存根的内容存储到 .phar/stub.php 文件内,而不是使用 setStub() 命令。

将文件添加到归档

Phar 对象使用 ArrayAccess SPL 对象,允许以数组的形式访问归档内容,因此提供了许多方法来向归档添加文件。最简单的方法是直接使用 ArrayAccess 接口。
示例 6. 向归档添加文件

$p[&#39;file.txt&#39;] = &#39;This is a text file&#39;;
$p[&#39;index.php&#39;] = file_get_contents(&#39;index.php&#39;);

    示例 6 表明文件名被指定为数组键,将内容指定为值。可以使用 file_get_contents() 函数获得现有文件的内容,然后将内容设为值。这样可以更加灵活地向归档添加文件,可以通过引用现有文件或动态构建文件实现。后一种方法可以作为应用程序构建脚本的一部分。

如果存储在 Phar 归档中的文件非常大,可以分别通过 PharFileInfo::setCompressedGZ() 或PharFileInfo::setCompressedBZIP2() 方法使用 gzip 或 bzip2 压缩有选择地压缩归档中的文件。在清单 7 中,您将使用 bzip2 压缩文件。
示例 7. 使用 bzip2 压缩 Phar 归档中的文件

$p[&#39;big.txt&#39;] = &#39;This is a big text file&#39;;
$p[&#39;big.txt&#39;]->setCompressedBZIP2();

    要压缩文件或使用包含压缩文件的归档,必须在 PHP 安装中支持 bzip2 或 zlib(用于 gz 压缩文件)扩展。

假设您需要将许多文件加入到归档中。使用 ArrayAccess 接口逐一添加文件是一项非常单调的工作,因此可以使用一些便捷的方法。一种方法就是使用 Phar::buildFromDirectory() 方法,该方法将遍历指定的目录并添加其中的文件。它还支持对添加的文件进行过滤,方法是使用文件的正则表达式模式传递第二个参数,以匹配文件并添加到归档中。清单 8 展示了这一过程。
示例 8. 使用 Phar::buildFromDirectory() 向归档添加文件

$p->buildFromDirectory(&#39;/path/to/files&#39;,&#39;./\.php$/&#39;);


    示例 8 将指定目录中的 PHP 文件添加到 Phar 归档。如果需要对添加的文件执行任何修改,比如将文件压缩,那么可以使用ArrayAccess 接口返回。

可以使用一个迭代器(iterator)通过 Phar::buildFromIterator() 方法添加文件。支持两种风格的迭代器:一种是将 Phar 中的文件名映射到磁盘文件的名称,另一种是返回 SplFileInfo 对象。RecursiveDirectoryIterator 是一种兼容的迭代器,下面展示如何使用它向归档添加目录文件。
示例 9. 使用 Phar::buildFromIterator() 向归档添加目录文件

$p->buildFromIterator(new RecursiveIteratorIterator
(new RecursiveDirectoryIterator(&#39;/path/to/files&#39;)),&#39;/path/to/files&#39;);

    Phar::buildFromIterator() 方法接受迭代器对象本身作为惟一的参数。在上例中,您已经使用RecursiveIteratorIterator 对象包装了 RecursiveDirectoryIterator 对象,RecursiveIteratorIterator 对象提供了Phar::buildFromIterator() 方法所需的兼容型迭代器。

我们现在已经创建了一个 Phar 归档,它可以用于任何 PHP 应用程序。让我们看一看如何方便地使用这个归档。

使用 Phar 归档

Phar 归档的一个优点就是可以非常方便地集成到任何应用程序中。如果使用的是原生的基于 Phar 的归档格式,这一点尤其明显。在这种情况下,您甚至不需要安装 Phar 扩展,因为 PHP 天生就可以加载文件并提取文件内容。基于 ZIP 和 TAR 的归档需要加载 Phar 扩展。

Phar 归档在设计时被包括到应用程序中,跟普通的 PHP 文件一样,这使得已经熟悉如何包含其他第三方代码的应用程序开发人员可以非常方便地使用 Phar 归档。让我们看一看在应用程序中集成 Phar 有多么容易。

在应用程序中集成 Phar 归档代码

在 Phar 归档中集成代码的最简单方法就是包含 Phar 归档,然后在 Phar 文件中包含需要使用的文件。phar:// 流包装器可以用来访问已加载 Phar 归档中的文件,如下所示。
示例 10. 在 Phar 归档中加载代码

include &#39;myphar.phar&#39;;  
include &#39;phar://myphar.phar/file.php&#39;;

    第一个 include 将加载 myphar.phar 归档,包含文件存根中指定的代码。第二个 include 使用流包装器打开 Phar 归档并且仅在归档中包括指定的文件。注意在归档中包含文件之前,您不需要包含 Phar 归档本身,如清单 10 所示。

从 Phar 归档运行 PHP 应用程序

Phar アーカイブの優れた機能は、単一の Phar アーカイブを使用してアプリケーション全体をパッケージ化し、公開できることです。このアプローチの利点は、パフォーマンスを犠牲にすることなくアプリケーションのデプロイメントを簡素化できることであり、主に PHP V5.3 で追加されたいくつかの Phar 拡張機能の恩恵を受けることができます。ただし、Phar で実行するアプリケーションを設計するときは、次の点を考慮する必要があります:

構成ファイルなど、作成する必要があるアプリケーション インスタンス固有のファイルはアーカイブに含めることができないため、ファイルに書き込む必要があります。離れていますが、アクセス可能な場所にあります。アプリケーションが拡張機能を構成するキャッシュ ファイルを作成する場合、それらのファイルにも同じことが当てはまります。

最大限の柔軟性を得るには、常に Phar ベースのアーカイブ形式を使用し、アーカイブ内のファイルを圧縮しないでください。 ZIP および TAR ベースのアーカイブでは、Phar 拡張機能を PHP にインストールする必要がありますが、Phar ベースのアーカイブは、Phar 拡張機能がインストールされていなくても使用できます。

前のセクションで示したように、アプリケーション内のファイル参照は、phar:// ストリーム ラッパーとアーカイブ名の両方を使用するように変更する必要があります。

PHPMyAdmin は、Phar を使用してパッケージ化された人気の PHP アプリケーションであり、Phar アーカイブの使いやすさを示しています。 Phar アーカイブから実行するように設計されていますが、Phar アーカイブの外部に構成ファイルを保存することもできます。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。