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

【PHP8.x】Phar::decompress()メソッドの使い方

decompressメソッドの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

decompressメソッドは、Pharアーカイブ全体を指定された圧縮形式から圧縮解除するメソッドです。これはPHPのPharクラスに属しており、主にパッケージングされたアプリケーションやライブラリの展開に利用されます。Phar(PHP Archive)形式のファイルは、複数のファイルを一つのアーカイブにまとめ、必要に応じて圧縮することができます。このdecompressメソッドを使用することで、Gzip(Phar::GZ)またはBzip2(Phar::BZ2)形式で圧縮されたPharアーカイブを、元の非圧縮状態に戻すことが可能です。

メソッドの実行時には、元のPharアーカイブは変更されず、圧縮解除された新しいPharアーカイブが一時ファイルとして生成されます。そして、この新しい非圧縮のPharアーカイブを操作するためのPharオブジェクトが戻り値として返されます。もし圧縮解除の処理に失敗した場合、このメソッドはfalseを返します。また、無効なアーカイブ形式やサポートされていない圧縮形式が指定された場合など、特定の状況下ではPharExceptionがスローされることがありますので、エラーハンドリングを考慮して使用することが推奨されます。このメソッドは、圧縮されたPharアーカイブの内容にアクセスする前に、その内容を展開する必要がある場合に特に役立ちます。

構文(syntax)

1<?php
2$phar = new Phar('path/to/archive.phar');
3$result = $phar->decompress();
4?>

引数(parameters)

?string $extension = NULL

  • string $extension = NULL: Pharアーカイブの展開に使用する圧縮形式を指定する文字列。gzipbzip2xz、またはpharを指定できます。指定しない場合は、Pharアーカイブの拡張子から自動的に判断されます。

戻り値(return)

object|true

Phar::decompressメソッドは、Pharアーカイブを解凍し、その結果をPharオブジェクトまたは成功した場合はtrueを返します。

サンプルコード

Phar::decompressでgzip解凍する

1<?php
2
3/**
4 * このスクリプトは、Pharアーカイブのgzip圧縮と解凍の基本的な例を示します。
5 * システムエンジニアを目指す初心者向けに、Phar::decompress() メソッドの使用方法を説明します。
6 *
7 * 事前準備:
8 * PHPのphar拡張が有効になっていることを確認してください。
9 * (php.iniで 'phar.readonly = 0' に設定する必要がある場合があります)
10 */
11
12// ファイル名定義
13$sourcePharPath = 'example.phar.gz';      // 圧縮されるPharファイル名
14$decompressedPharPath = 'example.phar'; // 解凍後のPharファイル名
15$internalFilePath = 'test.txt';           // Phar内部に格納されるファイル名
16
17echo "--- Pharアーカイブの準備 (gzip圧縮) ---" . PHP_EOL;
18
19// 1. gzip圧縮されたPharアーカイブを作成
20try {
21    // Pharアーカイブを作成(既に存在する場合は上書き)
22    // 第二引数に 'w' を指定して書き込みモードで開く
23    $phar = new Phar($sourcePharPath, 0, basename($sourcePharPath));
24
25    // Pharファイルを一時的に書き込み可能にする (phar.readonly = 1 の場合でもこのPharファイルのみ許可)
26    $phar->startBuffering();
27
28    // アーカイブ内にダミーファイルを追加
29    $phar->addFromString($internalFilePath, 'これはPharアーカイブ内のテストファイルです。');
30
31    // デフォルトのスタブを設定(Pharファイルが直接実行されたときの動作を定義)
32    $phar->setStub($phar->createDefaultStub($internalFilePath));
33
34    // Pharアーカイブ全体をgzip形式で圧縮
35    // Phar::GZ はgzip圧縮を指定する定数です。
36    $phar->compress(Phar::GZ);
37
38    // バッファリングを終了し、変更をPharファイルに書き込む
39    $phar->stopBuffering();
40
41    echo "圧縮されたPharアーカイブ '{$sourcePharPath}' が作成されました。" . PHP_EOL;
42    echo "内容: phar://{$sourcePharPath}/{$internalFilePath}" . PHP_EOL;
43
44} catch (PharException $e) {
45    echo "Pharアーカイブの作成中にエラーが発生しました: " . $e->getMessage() . PHP_EOL;
46    // エラーが発生した場合は終了
47    exit(1);
48}
49
50echo PHP_EOL . "--- Pharアーカイブの解凍 ---" . PHP_EOL;
51
52// 2. Phar::decompress() メソッドを使用してアーカイブを解凍
53try {
54    // 既存の圧縮されたPharファイルを読み込みモードで開く
55    $phar = new Phar($sourcePharPath);
56
57    // decompress() メソッドを呼び出してPharアーカイブを解凍します。
58    // 引数を省略すると、元の圧縮形式(この場合はgzip)を自動的に判別し、
59    // 解凍された新しいPharアーカイブ(example.phar)を作成します。
60    // 成功すると、解凍された新しいPharオブジェクトが返されます。
61    $decompressedPhar = $phar->decompress();
62
63    if ($decompressedPhar instanceof Phar) {
64        echo "Pharアーカイブ '{$sourcePharPath}' が成功裏に解凍され、" . PHP_EOL;
65        echo "'{$decompressedPharPath}' として保存されました。" . PHP_EOL;
66
67        // 解凍されたPharアーカイブの内容を読み込む例
68        $content = file_get_contents("phar://{$decompressedPharPath}/{$internalFilePath}");
69        echo "解凍されたPhar内の '{$internalFilePath}' の内容: '{$content}'" . PHP_EOL;
70    } else {
71        echo "Pharアーカイブの解凍に失敗したか、予期せぬ値が返されました。" . PHP_EOL;
72    }
73
74} catch (PharException $e) {
75    echo "Pharアーカイブの解凍中にエラーが発生しました: " . $e->getMessage() . PHP_EOL;
76} finally {
77    echo PHP_EOL . "--- クリーンアップ ---" . PHP_EOL;
78
79    // 作成したファイルをクリーンアップ(削除)
80    if (file_exists($sourcePharPath)) {
81        unlink($sourcePharPath);
82        echo "元の圧縮されたPharファイル '{$sourcePharPath}' を削除しました。" . PHP_EOL;
83    }
84    if (file_exists($decompressedPharPath)) {
85        unlink($decompressedPharPath);
86        echo "解凍されたPharファイル '{$decompressedPharPath}' を削除しました。" . PHP_EOL;
87    }
88    echo "クリーンアップが完了しました。" . PHP_EOL;
89}
90
91?>

PHPのPhar::decompress()メソッドは、gzipやbzip2などで圧縮されたPhar(PHPアーカイブ)ファイルを解凍するために使用されます。このメソッドは、配布されたソフトウェアパッケージの圧縮を解除し、内容にアクセスできるようにする際に役立ちます。

サンプルコードでは、まずPhar::compress(Phar::GZ)でgzip形式に圧縮されたPharアーカイブを作成し、その後にdecompress()メソッドでこれを解凍する一連の流れを示しています。

decompress()メソッドの引数$extensionはオプションで、解凍後のファイルに付ける拡張子を指定できます。この引数を省略(NULL)した場合、元のPharファイル名に付いている圧縮形式を示す拡張子(例:.gz)を自動的に認識して取り除き、その名前で解凍された新しいPharファイルが生成されます。

メソッドが正常に完了すると、解凍された新しいPharアーカイブを指し示すPharオブジェクトが戻り値として返されます。これにより、解凍されたアーカイブ内部のファイルにアクセスし、内容を読み出すことが可能になります。これは、システムのデプロイや更新において、圧縮されたアプリケーションパッケージを安全に展開する基本的な手法として重要です。

Phar::decompress()メソッドを使用する際は、PHPのphar拡張が有効であり、書き込み操作のためphar.readonly設定が適切にされているか事前確認が必要です。このメソッドは、元の圧縮形式を自動判別し、新しいPharファイルとして解凍します。引数を省略すると、元のファイル名から圧縮拡張子を除いた名前で新しいPharファイルが作成され、解凍されたPharオブジェクトが戻り値として返されます。処理中に問題が発生した場合はPharExceptionがスローされるため、try-catchブロックで必ずエラーを捕捉し、適切に処理してください。また、テスト実行後に生成されたファイルをクリーンアップし、環境を清潔に保つ習慣をつけることが大切です。

Phar::decompressでPharアーカイブを解凍する

1<?php
2
3// Phar拡張が有効になっていることを確認します
4if (!extension_loaded('phar')) {
5    echo "Phar拡張が有効になっていません。PHPの設定を確認してください。\n";
6    exit(1);
7}
8
9// Pharアーカイブの書き込み操作には phar.readonly=0 の設定が必要です。
10// php.iniで 'phar.readonly = Off' にするか、
11// コマンドラインで `php -d phar.readonly=0 your_script.php` のように実行してください。
12if (ini_get('phar.readonly') == 1) {
13    echo "Pharアーカイブへの書き込みには `phar.readonly=0` が必要です。\n";
14    echo "スクリプトを実行する前に設定を変更してください。\n";
15    exit(1);
16}
17
18/**
19 * Phar::decompress メソッドを使用して、圧縮されたPharアーカイブを解凍するサンプルコードです。
20 *
21 * この関数は以下の手順で動作します。
22 * 1. 一時ディレクトリ内に非圧縮のPharアーカイブ (.phar) を作成します。
23 * 2. 作成したPharアーカイブをGZIP形式で圧縮します (.phar.gz)。
24 *    この際、元の非圧縮Pharアーカイブは自動的に削除されます。
25 * 3. 圧縮されたPharアーカイブ (.phar.gz) をPhar::decompressメソッドで解凍します。
26 *    この際、圧縮されたPharアーカイブは自動的に削除され、非圧縮のPharアーカイブ (.phar) が再作成されます。
27 *
28 * 注: Phar::decompress は、Pharアーカイブファイル自体がgzipやbzip2などで圧縮されている場合、
29 * そのアーカイブ全体の「コンテナ圧縮」を解除するために使用されます。
30 * 一般的なZIPファイルの解凍には `ZipArchive` クラスを使用します。
31 * キーワード「zip」は、Pharアーカイブが内部でZIP形式を使用できることに関連しますが、
32 * このメソッドはアーカイブ「ファイル全体」の圧縮形式を扱います。
33 */
34function decompressPharArchiveExample(): void
35{
36    // 一時ディレクトリを準備
37    $tempDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid('phar_decompress_example_', true);
38    if (!mkdir($tempDir, 0777, true) && !is_dir($tempDir)) {
39        echo "エラー: 一時ディレクトリの作成に失敗しました: " . $tempDir . "\n";
40        return;
41    }
42
43    // 各Pharアーカイブのベース名と完全なパスを定義
44    $baseArchiveName = $tempDir . DIRECTORY_SEPARATOR . 'my_app';
45    $pharOriginalPath = $baseArchiveName . '.phar';        // 非圧縮Pharの初期パス
46    $pharCompressedPath = $pharOriginalPath . '.gz';    // GZIP圧縮Pharのパス
47    $pharDecompressedPath = $baseArchiveName . '.phar'; // 解凍後の非圧縮Pharのパス
48
49    try {
50        // --- 1. 非圧縮のPharアーカイブを作成する ---
51        echo "ステップ1: 非圧縮Pharアーカイブを作成します: " . $pharOriginalPath . "\n";
52
53        // 新しいPharオブジェクトを作成し、スタブとファイルを追加
54        $phar = new Phar($pharOriginalPath);
55        $phar->setStub("<?php __HALT_COMPILER(); ?>"); // Pharアーカイブには必須のスタブ
56        $phar->addFromString('index.php', '<?php echo "Hello from Phar!";');
57        $phar->addFromString('config.txt', 'application_name=PharExample');
58        
59        // ファイルシステムへの書き込みを確定させるため、Pharオブジェクトを破棄します。
60        // これを行わないと、ファイルが完全に作成されない場合があります。
61        unset($phar); 
62
63        echo "  作成された初期Pharアーカイブのファイルサイズ: " . filesize($pharOriginalPath) . "バイト\n";
64
65        // --- 2. 作成したPharアーカイブをGZIP形式で圧縮する ---
66        echo "\nステップ2: PharアーカイブをGZIP形式で圧縮します...\n";
67        
68        // 既存の非圧縮Pharをインスタンス化
69        $pharToCompress = new Phar($pharOriginalPath);
70        // compress() メソッドは、新しい圧縮されたPharオブジェクトを返します。
71        // この際、元の非圧縮Pharファイル ($pharOriginalPath) は自動的に削除されます。
72        $compressedPhar = $pharToCompress->compress(Phar::GZ);
73
74        if ($compressedPhar === false) {
75             throw new Exception("Pharアーカイブの圧縮に失敗しました。");
76        }
77
78        // 圧縮されたPharオブジェクトから実際のパスを取得
79        $actualCompressedPath = $compressedPhar->getPath();
80        echo "  圧縮されたPharアーカイブが作成されました: " . $actualCompressedPath . "\n";
81        echo "  圧縮されたファイルのサイズ: " . filesize($actualCompressedPath) . "バイト\n";
82        
83        // 元の非圧縮Pharが削除されていることを確認
84        if (!file_exists($pharOriginalPath)) {
85            echo "  (元の非圧縮Pharアーカイブは圧縮時に削除されました)\n";
86        }
87        
88        // --- 3. 圧縮されたPharアーカイブをPhar::decompressで解凍する ---
89        echo "\nステップ3: 圧縮されたPharアーカイブを解凍します...\n";
90        
91        // 解凍対象の圧縮Pharをインスタンス化
92        $pharToDecompress = new Phar($actualCompressedPath);
93        
94        // decompress() メソッドを呼び出します。
95        // 引数 $extension を NULL にすると、元の圧縮拡張子 (.gz) を除去した名前で解凍されます。
96        // このメソッドも新しい非圧縮Pharオブジェクトを返し、元の圧縮Pharファイル ($actualCompressedPath) は自動的に削除されます。
97        $decompressedPhar = $pharToDecompress->decompress();
98
99        if ($decompressedPhar === false) {
100            throw new Exception("Pharアーカイブの解凍に失敗しました。");
101        }
102
103        // 解凍されたPharオブジェクトから実際のパスを取得
104        $actualDecompressedPath = $decompressedPhar->getPath();
105        echo "  Pharアーカイブが正常に解凍されました: " . $actualDecompressedPath . "\n";
106        echo "  解凍されたファイルのサイズ: " . filesize($actualDecompressedPath) . "バイト\n";
107
108        // 圧縮されたPharが削除されていることを確認
109        if (!file_exists($actualCompressedPath)) {
110            echo "  (圧縮されたPharアーカイブは解凍時に削除されました)\n";
111        }
112        
113        // 解凍後のPharアーカイブからファイルを取り出して内容を確認(オプション)
114        // 例: 'phar://my_app.phar/index.php' の内容を読み込む
115        $extractedContent = file_get_contents('phar://' . $actualDecompressedPath . '/index.php');
116        echo "  解凍されたPhar内の 'index.php' の内容: " . $extractedContent . "\n";
117
118    } catch (Exception $e) {
119        echo "エラーが発生しました: " . $e->getMessage() . "\n";
120    } finally {
121        // --- クリーンアップ ---
122        echo "\n一時ファイルをクリーンアップしています...\n";
123        // 最終的に残っている可能性のあるファイルを削除します
124        if (file_exists($pharCompressedPath)) {
125            unlink($pharCompressedPath);
126        }
127        if (file_exists($pharDecompressedPath)) {
128            unlink($pharDecompressedPath);
129        }
130        // 作成した一時ディレクトリを削除します
131        if (is_dir($tempDir)) {
132            rmdir($tempDir);
133        }
134        echo "クリーンアップが完了しました。\n";
135    }
136}
137
138// サンプル関数の実行
139decompressPharArchiveExample();

Phar::decompressメソッドは、PHPのPhar(PHP Archive)拡張機能の一部で、GZIPやBZIP2などの形式で「ファイル全体が圧縮された」Pharアーカイブのコンテナ圧縮を解除するために使用されます。このサンプルコードでは、最初に非圧縮のPharアーカイブを作成し、それをGZIP形式で圧縮した後、decompressメソッドを用いて元の非圧縮状態に戻す一連の流れを示しています。

このメソッドの引数$extensionNULLを指定すると、解凍後のPharアーカイブは元の圧縮拡張子(例: .gz)が取り除かれたファイル名で作成されます。戻り値は、解凍されたPharアーカイブを表すPharオブジェクト、または成功時にtrueを返します。解凍が成功すると、元の圧縮されたPharファイルは自動的に削除される挙動があります。

Pharアーカイブの作成や変更といった書き込み操作を行うには、PHPの設定でphar.readonly=0が必要であり、サンプルコードではその確認も行っています。

キーワードの「zip」に関してですが、Phar::decompressはPharアーカイブ「ファイル自体」の圧縮形式を解除するもので、アーカイブ内部に保存されている個別のファイルをZIP形式で圧縮・解凍する機能ではありません。一般的なZIPファイルの解凍にはZipArchiveクラスを使用しますので、混同しないようにしてください。本メソッドは、Pharとしてパッケージングされたアプリケーション全体の配布サイズを最適化する際に有用です。

Phar::decompressは、Pharアーカイブファイル自体がGZIPやbzip2などで「コンテナ圧縮」されている場合に、その圧縮を解除するメソッドです。一般的なZIPファイルを解凍し、ファイル群をフォルダに展開する機能とは異なりますので、通常のZIPファイルを扱う場合はZipArchiveクラスを使用してください。Pharアーカイブの作成や変更には、PHP設定でphar.readonly = 0にする必要があります。また、このメソッドは成功すると、処理対象の元の圧縮Pharファイルを自動的に削除し、新しく非圧縮のPharファイルを作成します。元のファイルが不要であることを確認してから実行してください。成功時には新しいPharオブジェクトが返されます。

関連コンテンツ

【PHP8.x】Phar::decompress()メソッドの使い方 | いっしー@Webエンジニア