Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】Phar::ZIP定数の使い方

ZIP定数の使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

ZIP定数は、PHPのPhar拡張機能において、Pharアーカイブの圧縮形式がZIP形式であることを表す定数です。Phar拡張機能は、複数のPHPファイルや関連リソース(画像、CSS、JavaScriptなど)を一つのアーカイブファイルにまとめて、アプリケーションの配布やデプロイを容易にするための機能を提供します。

このZIP定数は、Pharアーカイブを作成する際や、既存のPharアーカイブを圧縮する際に、そのアーカイブ全体をZIP形式で圧縮したい場合に指定されます。例えば、Phar::buildFromDirectory()メソッドでディレクトリからPharアーカイブを作成する際や、Phar::compress()メソッドで既存のPharアーカイブに圧縮を適用する際に、引数としてPhar::ZIPを指定することで、内部のデータをZIP形式で効率的に圧縮できます。

ZIP形式は、広く普及している汎用的なデータ圧縮アルゴリズムであり、WindowsやmacOSなどの多くのオペレーティングシステムで標準的にサポートされています。そのため、PharアーカイブをZIP圧縮で作成することで、配布されたアプリケーションのファイルサイズを削減できるだけでなく、特別なツールを必要とせずにアーカイブの内容を扱えるという高い互換性を提供します。この定数を利用することで、開発者はPharアーカイブの圧縮方式を明確に指定し、適切なパフォーマンスと幅広い互換性を選択できるのです。

構文(syntax)

1<?php
2echo Phar::ZIP;

引数(parameters)

引数なし

引数はありません

戻り値(return)

int

Phar::ZIP は、PharアーカイブをZIP形式で扱うことを示す整数定数です。

サンプルコード

PHP PharアーカイブをZIP形式で作成する

1<?php
2
3/**
4 * PHPアプリケーションをZIP形式のPharアーカイブとしてパッケージ化するサンプル関数です。
5 *
6 * Pharアーカイブは、複数のPHPファイルや関連アセットを単一のファイルにまとめ、
7 * 配布や実行を容易にするためのPHPの機能です。
8 * ここでは、Phar::ZIP定数を使用して、Pharアーカイブの内部形式がZIP形式に準拠するように指定します。
9 *
10 * 注意事項:
11 * 1. この処理を実行するには、php.ini設定で 'phar.readonly = 0' となっている必要があります。
12 *    セキュリティ上の理由から、本番環境では 'phar.readonly = 1' が推奨されます。
13 *    開発環境で一時的に設定を変更するか、ini_set()関数を試すこともできます
14 *    (ただし、ini_set()が常に動作するとは限りません)。
15 * 2. このPhar::ZIP定数は、PHPアプリケーションをパッケージ化するPharクラスの文脈で使用されます。
16 *    一般的なファイル群をZIP形式で圧縮・解凍する用途(例: Windowsのエクスプローラーで扱うようなZIPファイル)
17 *    であれば、ZipArchiveクラスを使用するのが適切です。
18 *    `Phar::ZIP`はPharアーカイブ内部のファイル構造がZIPフォーマットに準拠することを意味します。
19 *
20 * @param string $archivePath 作成するPharアーカイブの完全なファイルパス (例: '/path/to/my_app.phar')
21 * @param string $sourceDir パッケージ化するファイルが含まれるソースディレクトリのパス
22 * @return bool 成功した場合true、失敗した場合falseを返します。
23 */
24function createZipPharArchive(string $archivePath, string $sourceDir): bool
25{
26    // 'phar.readonly = 0' が設定されているか確認するヒント
27    if (ini_get('phar.readonly') === '1') {
28        echo "警告: php.iniで 'phar.readonly = 0' に設定されていないため、Pharアーカイブの作成に失敗する可能性があります。\n";
29        echo "ini_set('phar.readonly', '0'); を試すか、php.iniを修正してください。\n";
30        // ini_set('phar.readonly', '0'); // 環境によっては動作しない場合があります
31    }
32
33    // ソースディレクトリが存在しない、または空の場合はエラー
34    if (!is_dir($sourceDir) || empty(glob($sourceDir . '/*'))) {
35        echo "エラー: ソースディレクトリが存在しないか、空です: {$sourceDir}\n";
36        return false;
37    }
38
39    // 既存のPharアーカイブがあれば削除し、再作成を可能にする
40    $possibleExtensions = ['', '.gz', '.bz2']; // 圧縮されたPharアーカイブの可能性も考慮
41    foreach ($possibleExtensions as $ext) {
42        if (file_exists($archivePath . $ext)) {
43            unlink($archivePath . $ext);
44        }
45    }
46
47    try {
48        // Pharクラスのインスタンスを作成
49        // 第1引数: 作成するPharアーカイブのパス
50        // 第2引数: フラグ (0は通常のPhar)
51        // 第3引数: エイリアス名 (オプション、アーカイブ内で参照される名前)
52        $phar = new Phar($archivePath, 0, basename($archivePath));
53
54        // 実行可能なスタブを設定(Pharアーカイブが直接実行されるためのコード)
55        $phar->setStub($phar->createDefaultStub('index.php'));
56
57        // 指定されたディレクトリからファイルをPharアーカイブに追加
58        $phar->buildFromDirectory($sourceDir);
59
60        // Phar::GZ 定数を使用して、アーカイブ内のファイルをGZIP圧縮(オプションの最適化)
61        $phar->compressFiles(Phar::GZ);
62
63        echo "Pharアーカイブ '{$archivePath}' をZIP形式の定義で作成しました。\n";
64        echo "アーカイブ内のファイル一覧:\n";
65        foreach ($phar as $file) {
66            echo "  - " . $file->getFilename() . "\n";
67        }
68        return true;
69
70    } catch (PharException $e) {
71        echo "Pharアーカイブの作成に失敗しました: " . $e->getMessage() . "\n";
72        return false;
73    } catch (Exception $e) {
74        echo "予期せぬエラーが発生しました: " . $e->getMessage() . "\n";
75        return false;
76    }
77}
78
79// --- サンプル実行 ---
80$archiveName = 'my_application.phar'; // 作成するPharアーカイブの名前
81$sourceDirectory = __DIR__ . '/my_app_source'; // パッケージ化するソースファイルのディレクトリ
82
83// パッケージ化するダミーのソースファイルを作成
84if (!is_dir($sourceDirectory)) {
85    mkdir($sourceDirectory);
86}
87file_put_contents($sourceDirectory . '/index.php', '<?php echo "Hello from packaged application!";');
88file_put_contents($sourceDirectory . '/config.txt', 'app_version=1.0.0');
89
90echo "Pharアーカイブ作成を開始します...\n";
91if (createZipPharArchive(__DIR__ . '/' . $archiveName, $sourceDirectory)) {
92    echo "アーカイブ作成が完了しました。\n";
93    echo "このアーカイブを実行するには、コマンドラインで 'php " . $archiveName . "' と入力してください。\n";
94} else {
95    echo "アーカイブ作成に失敗しました。\n";
96}
97
98// --- 後処理 ---
99// 作成したダミーのソースディレクトリとファイルを削除
100if (is_dir($sourceDirectory)) {
101    $files = glob($sourceDirectory . '/*');
102    foreach ($files as $file) {
103        if (is_file($file)) {
104            unlink($file);
105        }
106    }
107    rmdir($sourceDirectory);
108}
109// 作成したPharアーカイブとその圧縮ファイルを削除
110$archivePath = __DIR__ . '/' . $archiveName;
111$possibleExtensions = ['', '.gz', '.bz2'];
112foreach ($possibleExtensions as $ext) {
113    if (file_exists($archivePath . $ext)) {
114        unlink($archivePath . $ext);
115    }
116}
117
118?>

PHPのPhar::ZIP定数を利用した、アプリケーションのパッケージ化に関するサンプルコードです。このコードは、複数のPHPファイルや関連アセットを単一のファイルにまとめる「Pharアーカイブ」の作成方法を示しています。特にPhar::ZIP定数に焦点を当てており、この定数はPharアーカイブの内部構造を一般的なZIP形式に準拠させるためのものであることを意味します。Pharクラスは、複数のPHPファイルや関連リソースを一つのファイルにまとめ、配布や実行を容易にするPHPの機能です。Phar::ZIPint型の定数であり、PharアーカイブがZIP形式の構造を持つことを定義する際に用いられます。

createZipPharArchive関数は、指定されたソースディレクトリの内容をまとめ、$archivePathで指定されたファイルパスにPharアーカイブを作成します。引数$archivePathは作成するPharアーカイブの完全なファイルパスを、$sourceDirはパッケージ化するファイルが含まれるソースディレクトリのパスを指定します。この関数は、アーカイブの作成に成功すればtrueを、失敗すればfalseを戻り値として返します。

Pharアーカイブの作成には、PHPの設定ファイル(php.ini)でphar.readonly0に設定する必要があります。また、Phar::ZIPはPharアーカイブ内部の構造形式を示すものであり、一般的なファイル群をZIP形式で圧縮・解凍する用途にはZipArchiveクラスを使用するのが適切です。サンプルコード内では、アーカイブ内のファイルを個別にGZIP形式で圧縮するためにPhar::GZ定数が使用されていますが、これはPhar::ZIPが示すアーカイブ全体の基盤となる構造とは異なる、ファイル単位の圧縮方式です。

このサンプルコードは、PHPアプリケーションをPharアーカイブとしてパッケージ化するものです。特に注意すべき点は、Phar::ZIP定数がPharアーカイブ内部のファイル形式を指定するものであり、一般的なZIP圧縮・解凍を行うZipArchiveクラスとは用途が全く異なるという点です。混同しないようご注意ください。また、Pharアーカイブの作成にはPHP設定ファイル(php.ini)でphar.readonly = 0を有効にする必要があります。しかし、本番環境ではセキュリティ上の理由からphar.readonly = 1に戻すことが強く推奨されます。サンプルコードではPhar::ZIP定数に言及していますが、実際の圧縮処理にはPhar::GZ定数を使用しています。Phar::ZIPで圧縮する場合は$phar->compressFiles(Phar::ZIP);のように変更が必要です。

PHP Phar::ZIP を使った ZIP 解凍

1<?php
2
3/**
4 * Phar::ZIP 定数を利用して、ZIP形式のPharアーカイブを作成し、そこからファイルを解凍するサンプルコード。
5 *
6 * システムエンジニアを目指す初心者向けに、Pharアーカイブの基本的な作成と展開(解凍)の手順を示します。
7 * Phar::ZIP 定数は、Pharアーカイブの形式としてZIPを指定する際に使用されます。
8 */
9function demonstratePharZipExtraction(): void
10{
11    // 一時ファイルとディレクトリの準備
12    // ソースとなるファイル群を置くディレクトリ
13    $sourceDir = __DIR__ . '/_temp_source';
14    // 作成するPharアーカイブのファイル名(ZIP形式を想定)
15    $pharArchiveName = 'my_application.zip';
16    // Pharアーカイブのフルパス
17    $pharFile = __DIR__ . '/' . $pharArchiveName;
18    // 解凍したファイルを置くディレクトリ
19    $extractDir = __DIR__ . '/_temp_extracted';
20
21    // クリーンアップ関数: 実行後に一時ファイルやディレクトリを削除します。
22    $cleanup = function() use ($sourceDir, $pharFile, $extractDir) {
23        if (file_exists($pharFile)) {
24            unlink($pharFile);
25        }
26        // ソースディレクトリ内のファイルを削除してからディレクトリを削除
27        if (is_dir($sourceDir)) {
28            $files = glob("$sourceDir/*");
29            if (is_array($files)) {
30                array_map('unlink', $files);
31            }
32            rmdir($sourceDir);
33        }
34        // 解凍先ディレクトリ内のファイルを削除してからディレクトリを削除
35        if (is_dir($extractDir)) {
36            $files = glob("$extractDir/*");
37            if (is_array($files)) {
38                array_map('unlink', $files);
39            }
40            rmdir($extractDir);
41        }
42    };
43
44    // 以前の実行で残ったファイルをクリーンアップ
45    $cleanup();
46
47    echo "--- ソースファイルとディレクトリの準備 ---\n";
48    // ソースディレクトリの作成
49    mkdir($sourceDir);
50    // サンプルファイルの作成
51    file_put_contents("$sourceDir/index.php", "<?php echo 'Hello from index!';");
52    file_put_contents("$sourceDir/config.txt", "setting=value");
53    echo "ソースディレクトリ '$sourceDir' にサンプルファイルを作成しました。\n";
54
55    echo "\n--- ZIP形式のPharアーカイブの作成 ---\n";
56    try {
57        // Pharファイルの書き込みを可能にするため、'phar.readonly'を一時的にオフにします。
58        // 注意: 本番環境では、セキュリティ上の理由からこの設定変更は避け、
59        // CLIツールなどでPharアーカイブを作成するのが一般的です。
60        $oldReadonly = ini_get('phar.readonly');
61        if ((bool)$oldReadonly === true) {
62            ini_set('phar.readonly', '0');
63            echo "phar.readonly を一時的に '0' に設定しました。\n";
64        }
65
66        // 新規Pharオブジェクトを作成します。
67        // 第一引数: 作成するPharアーカイブのパス
68        // 第二引数: フラグ (0はデフォルト)
69        // 第三引数: アーカイブのエイリアス (必須ではありませんが、Phar::mapPhar()などで使われます)
70        $phar = new Phar($pharFile, 0, $pharArchiveName);
71
72        // ソースディレクトリの内容をPharアーカイブにビルドします。
73        $phar->buildFromDirectory($sourceDir);
74        // アーカイブの実行スタブ(入口となるスクリプト)を設定します。
75        $phar->setStub($phar->createDefaultStub('index.php'));
76
77        // ここでPharアーカイブをZIP形式に変換します。
78        // Phar::ZIP 定数を直接使用しています。この定数はint値を返します。
79        // convertToExecutable() は、現在のアーカイブを新しい形式で書き換えます。
80        // 第二引数: コンテンツの圧縮形式 (Phar::NONEは無圧縮を意味します)
81        $phar->convertToExecutable(Phar::ZIP, Phar::NONE);
82        echo "Pharアーカイブ '$pharFile' を作成し、Phar::ZIP 形式に変換しました。\n";
83
84        // 'phar.readonly'設定を元の値に戻します。
85        if ((bool)$oldReadonly === true) {
86            ini_set('phar.readonly', $oldReadonly);
87            echo "phar.readonly を元の値に戻しました。\n";
88        }
89        
90        // --- ZIP形式のPharアーカイブからのファイル解凍処理 ---
91        echo "\n--- ZIP形式のPharアーカイブからファイルを解凍 ---\n";
92
93        // 作成されたZIP形式のPharファイルを再度開きます。
94        // これが解凍の対象となるPharアーカイブです。
95        $openedPhar = new Phar($pharFile);
96
97        // Pharアーカイブの形式を確認します (Phar::ZIP 定数を利用)。
98        if ($openedPhar->getFormat() === Phar::ZIP) {
99            echo "Pharの形式はZIPであることが確認されました (定数値: " . Phar::ZIP . ").\n";
100            // 解凍先のディレクトリを作成します。
101            mkdir($extractDir);
102            // 指定したディレクトリにアーカイブの内容を展開(解凍)します。
103            $openedPhar->extractTo($extractDir);
104            echo "ファイルを '$extractDir' に解凍しました。\n";
105
106            // 解凍されたファイルの内容を確認
107            if (file_exists("$extractDir/index.php")) {
108                echo "解凍された index.php の内容: '" . file_get_contents("$extractDir/index.php") . "'\n";
109            }
110            if (file_exists("$extractDir/config.txt")) {
111                echo "解凍された config.txt の内容: '" . file_get_contents("$extractDir/config.txt") . "'\n";
112            }
113        } else {
114            echo "エラー: Pharの形式がZIPではありませんでした。検出された形式: " . $openedPhar->getFormat() . "\n";
115        }
116
117    } catch (PharException $e) {
118        echo "Pharエラー: " . $e->getMessage() . "\n";
119        // エラー発生時も元の設定に戻す
120        if (isset($oldReadonly) && (bool)$oldReadonly === true) {
121            ini_set('phar.readonly', $oldReadonly);
122        }
123    } catch (Exception $e) {
124        echo "一般エラー: " . $e->getMessage() . "\n";
125        // エラー発生時も元の設定に戻す
126        if (isset($oldReadonly) && (bool)$oldReadonly === true) {
127            ini_set('phar.readonly', $oldReadonly);
128        }
129    } finally {
130        // 全ての処理が終了した後、一時ファイルとディレクトリをクリーンアップします。
131        $cleanup();
132        echo "\n--- クリーンアップ完了 ---\n";
133    }
134}
135
136// 関数の実行
137demonstratePharZipExtraction();
138
139?>

このPHPサンプルコードは、Phar::ZIP定数を利用して、ZIP形式のPharアーカイブを作成し、そこからファイルを解凍する一連の手順を、システムエンジニアを目指す初心者向けに分かりやすく解説しています。Phar::ZIPは、PharアーカイブのフォーマットとしてZIP形式を指定するために使用される定数で、引数はなく、その形式を示す整数値(int)を返します。

コードでは、まず一時的なソースファイルとディレクトリを用意し、これらをアーカイブ化する準備を行います。次に、Pharクラスのインスタンスを作成し、buildFromDirectory()でソースファイル群をPharアーカイブに追加します。この際、convertToExecutable()メソッドの第一引数にPhar::ZIP定数を渡すことで、生成されるPharアーカイブの形式をZIPに指定し、変換を実行しています。これにより、ファイル群がZIP形式で圧縮された実行可能なPharファイルが作成されます。

その後、作成されたZIP形式のPharアーカイブを再び開き、getFormat()でその形式がPhar::ZIPであることを確認します。最後に、extractTo()メソッドを使って、アーカイブ内の全てのファイルを指定された解凍先ディレクトリへ展開(解凍)し、内容を確認しています。この例を通して、Phar::ZIP定数がPharアーカイブの形式を制御し、アプリケーションのパッケージ化と展開を行う上でどのように機能するかを学ぶことができます。

Phar::ZIP定数は、Pharアーカイブの形式をZIPと指定する整数値です。このコードで最も注意すべきは、phar.readonly設定を一時的に無効化する点です。これはセキュリティリスクが高いため、本番環境ではスクリプト内での設定変更は避け、CLIツールでPharアーカイブを作成してください。一時的に変更した場合は、処理後に必ず元の値に戻す必要があります。Pharアーカイブは単なるZIPではなく、PHPの実行可能なパッケージ形式であると理解しておきましょう。

関連コンテンツ