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

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

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

作成日: 更新日:

基本的な使い方

compressFilesメソッドは、PHPのPharDataオブジェクトが管理するデータアーカイブ内のファイルを、指定された圧縮形式で再圧縮するメソッドです。このメソッドは、アーカイブ全体を一つの形式で圧縮するのではなく、アーカイブ内に含まれる個々のファイルに対して、GZIP(Phar::GZ)またはBZIP2(Phar::BZ2)といった圧縮アルゴリズムを適用します。

この機能の主な目的は、既に存在するデータアーカイブのファイルサイズを最適化し、ストレージ容量の節約や、ネットワークを介したデータ転送の効率化を図ることです。例えば、大量の画像ファイルやドキュメントがまとめられた.tarアーカイブの中身を、より小さなサイズに圧縮し直したい場合に利用できます。

メソッドを使用する際には、引数として圧縮方式を指定し、必要に応じて、圧縮後に元の非圧縮ファイルをアーカイブから削除するかどうかを設定できます。これにより、アーカイブ内のコンテンツ管理を柔軟に行うことが可能です。

注意点として、このメソッドは実行可能なPharアーカイブ(通常、.phar拡張子を持つ)ではなく、データアーカイブ(例えば、.tarや.zipなどの拡張子を持つ)に対してのみ適用されます。また、既に高度に圧縮されているファイルをさらに圧縮しても、必ずしも大きなサイズ削減効果が得られるわけではありません。PharData::compressFilesは、データアーカイブ内のファイルを効率的に管理し、最適化するための重要なツールです。

構文(syntax)

1<?php
2$pharData = new PharData('myarchive.tar');
3$pharData->compressFiles(Phar::GZ);
4?>

引数(parameters)

int $compression

  • int $compression: ファイル圧縮に使用する圧縮アルゴリズムを指定します。
    • Phar::GZ: gzip圧縮を指定します。
    • Phar::BZ2: bzip2圧縮を指定します。
    • Phar::NONE: 圧縮を行いません。

戻り値(return)

bool

pharアーカイブ内のファイルを指定された圧縮形式で圧縮できた場合にtrueを、それ以外の場合にfalseを返します。

サンプルコード

PHP PharData::compressFiles でファイルを圧縮する

1<?php
2
3// Phar拡張が有効かつphar.readonlyが'0'になっていることを確認してください。
4// php.iniで 'phar.readonly = 0' と設定するか、開発環境で一時的に 'ini_set('phar.readonly', 0);' を使用できます。
5// ただし、ini_set() は常に動作するとは限らず、セキュリティ上の理由から推奨されない場合もあります。
6
7// 一時ファイルとディレクトリのパスを設定
8$tempDir = __DIR__ . DIRECTORY_SEPARATOR . 'temp_phar_compress';
9$archivePath = $tempDir . DIRECTORY_SEPARATOR . 'my_archive.tar'; // 作成されるTARアーカイブのパス
10$file1Path = $tempDir . DIRECTORY_SEPARATOR . 'file1.txt';
11$file2Path = $tempDir . DIRECTORY_SEPARATOR . 'file2.txt';
12
13/**
14 * 指定されたパスのファイルまたはディレクトリを再帰的に削除するヘルパー関数。
15 * サンプルコードの実行後、一時ファイルをクリーンアップするために使用します。
16 *
17 * @param string $path 削除するパス。
18 */
19function cleanup_path(string $path): void
20{
21    if (!file_exists($path)) {
22        return;
23    }
24    if (is_dir($path)) {
25        $files = array_diff(scandir($path), ['.', '..']);
26        foreach ($files as $file) {
27            cleanup_path($path . DIRECTORY_SEPARATOR . $file);
28        }
29        rmdir($path);
30    } else {
31        unlink($path);
32    }
33}
34
35try {
36    echo "--- PharData::compressFiles メソッドのサンプル ---" . PHP_EOL;
37    echo "このサンプルでは、PharDataアーカイブ内の『個々のファイル』を圧縮します。" . PHP_EOL . PHP_EOL;
38
39    // 1. 一時ディレクトリを作成し、アーカイブに追加するファイルを用意します。
40    if (!mkdir($tempDir) && !is_dir($tempDir)) {
41        throw new RuntimeException(sprintf('一時ディレクトリ "%s" の作成に失敗しました。', $tempDir));
42    }
43
44    // アーカイブに追加する一時ファイルを作成
45    file_put_contents($file1Path, "これはファイル1の内容です。\nPharDataに圧縮されずに格納されます。");
46    file_put_contents($file2Path, "これはファイル2の内容です。\nPharDataに圧縮されずに格納されます。");
47
48    echo "1. 新しいPharDataアーカイブを作成し、ファイルをそこに追加します。" . PHP_EOL;
49
50    // PharDataオブジェクトを作成(TARアーカイブとして)。
51    // この時点でファイルは圧縮されずにアーカイブに格納されます。
52    $pharData = new PharData($archivePath);
53
54    // アーカイブにファイルを追加
55    $pharData->addFile($file1Path, 'file1.txt'); // アーカイブ内でのファイル名 'file1.txt'
56    $pharData->addFile($file2Path, 'file2.txt'); // アーカイブ内でのファイル名 'file2.txt'
57
58    echo "  - 作成されたアーカイブ: " . $archivePath . PHP_EOL;
59    echo "  - アーカイブに追加されたファイル: file1.txt, file2.txt" . PHP_EOL;
60    echo "  - 初期状態のアーカイブ内ファイルリスト (圧縮なし):" . PHP_EOL;
61    foreach ($pharData as $file) {
62        echo "    - " . $file->getFileName() . " (圧縮状態: " . ($file->isCompressed() ? 'Yes' : 'No') . ", サイズ: " . $file->getSize() . "バイト)" . PHP_EOL;
63    }
64    echo PHP_EOL;
65
66    // 2. PharDataアーカイブ内のすべてのファイルをGZIP形式で圧縮します。
67    echo "2. PharDataアーカイブ内のすべてのファイルをGZIP形式で圧縮します。" . PHP_EOL;
68    echo "   注意: PharData::compressFiles はアーカイブ自体を .tar.gz のように圧縮するのではなく、" . PHP_EOL;
69    echo "   アーカイブ『内』の個々のファイルを圧縮します。アーカイブのファイル名 (.tar) は変わりません。" . PHP_EOL;
70
71    // compressFilesメソッドを呼び出してアーカイブ内の全ファイルをGZIP圧縮
72    // 引数には Phar::GZ (GZIP圧縮) または Phar::BZ2 (BZIP2圧縮) を指定できます。
73    $success = $pharData->compressFiles(Phar::GZ);
74
75    if ($success) {
76        echo "  - アーカイブ内のファイル圧縮に成功しました。" . PHP_EOL;
77        echo "  - 圧縮後のアーカイブ内ファイルリスト:" . PHP_EOL;
78        // 圧縮されたか確認するため、再度アーカイブ内のファイルリストとサイズを表示
79        foreach ($pharData as $file) {
80            echo "    - " . $file->getFileName() . " (圧縮状態: " . ($file->isCompressed() ? 'Yes' : 'No') . ", サイズ: " . $file->getSize() . "バイト)" . PHP_EOL;
81        }
82    } else {
83        echo "  - アーカイブ内のファイル圧縮に失敗しました。" . PHP_EOL;
84    }
85
86} catch (PharException $e) {
87    echo "Phar操作中にエラーが発生しました: " . $e->getMessage() . PHP_EOL;
88} catch (RuntimeException $e) {
89    echo "ランタイムエラー: " . $e->getMessage() . PHP_EOL;
90} catch (Exception $e) {
91    echo "予期せぬエラー: " . $e->getMessage() . PHP_EOL;
92} finally {
93    echo PHP_EOL . "3. 後処理として、作成された一時ファイルとディレクトリを削除します。" . PHP_EOL;
94    cleanup_path($tempDir);
95    echo "  - クリーンアップが完了しました。" . PHP_EOL;
96}
97
98?>

PHP 8のPharDataクラスに属するcompressFilesメソッドは、PharDataアーカイブ内の『個々のファイル』を圧縮するために使用されます。このメソッドは、phar.readonly設定が0に設定されており、Phar拡張が有効な環境で利用可能です。

compressFilesメソッドは、int $compressionという一つの引数を受け取ります。この引数には、Phar::GZ(GZIP圧縮)やPhar::BZ2(BZIP2圧縮)のような定数を指定し、アーカイブ内のファイルをどの形式で圧縮するかを指示します。この圧縮は、アーカイブファイル自体の拡張子を変更するものではなく、アーカイブ内部に格納されている各ファイルのデータが圧縮される点が特徴です。例えば、.tarアーカイブを作成し、その内部のファイルをGZIP圧縮しても、アーカイブファイル自体は.tarのままです。

メソッドの戻り値はbool型で、アーカイブ内のファイル圧縮処理が成功した場合はtrueを、失敗した場合はfalseを返します。これにより、処理の成否を確認できます。サンプルコードでは、まず圧縮されていないファイルをPharDataアーカイブに追加し、その後にcompressFiles(Phar::GZ)を呼び出して、内部のファイルをGZIP形式で圧縮する様子を示しています。これにより、ディスクスペースの節約やデータ転送の効率化が期待できます。

このサンプルコードはPharData::compressFilesメソッドの利用を示していますが、いくつか重要な注意点があります。まず、PHPのPhar拡張が有効であること、そしてphp.iniでphar.readonly = 0が設定されていることが必須です。これはPharアーカイブへの書き込み操作に必要となります。特に、このメソッドは.tarファイルを.tar.gzのようにアーカイブ全体を圧縮するものではなく、アーカイブに格納されている個々のファイルをGZIPやBZIP2などの形式で圧縮します。圧縮形式はメソッドの引数で指定します。実際のシステム開発では、一時ファイルの管理、パスの指定、そしてエラー発生時の適切なハンドリングを確実に行うようにしてください。

PharData::compressFilesでアーカイブ圧縮する

1<?php
2
3/**
4 * 複数の画像ファイルをPharDataアーカイブにまとめて、アーカイブ内のファイルを圧縮します。
5 *
6 * この関数は、画像ファイルの品質を直接低下させてファイルサイズを削減するものではなく、
7 * ファイルをtarアーカイブに格納し、そのアーカイブ内の各ファイルをGzip形式などで透過的に圧縮するものです。
8 * これは、システムエンジニアが複数のファイルをまとめて配布したり、バックアップしたりする際に
9 * ファイルサイズを削減するための一般的な方法です。
10 *
11 * システムエンジニアを目指す初心者の方へ:
12 * - PharDataは、複数のファイルを1つのアーカイブファイル(例: .tar)にまとめるためのクラスです。
13 * - compressFiles()メソッドは、作成したアーカイブ内の各ファイルを指定された圧縮形式(例: Gzip)で圧縮します。
14 *   これにより、アーカイブ全体のサイズを削減できます。
15 * - これは、JPGやPNGなどの画像フォーマット特有の圧縮(品質劣化を伴うもの)とは異なります。
16 *   画像そのものの見た目の品質を落としてファイルサイズを減らすわけではありません。
17 *
18 * @param array $imageNames 圧縮する画像ファイルの名前の配列 (例: ['image1.jpg', 'photo_2.png'])。
19 *                          実際には、これらの名前で一時的なダミーファイルが作成されます。
20 * @param string $archiveBaseName 作成するアーカイブファイルのベース名(例: "my_images_archive")。
21 *                                .tar 拡張子は内部的に追加されます。
22 * @param int $compression 使用する圧縮方式。Phar::GZ または Phar::BZ2 を指定します。
23 *                         Phar::GZはGzip圧縮、Phar::BZ2はBzip2圧縮を意味します。
24 * @return string|false 成功した場合、作成されたアーカイブファイルのフルパスを返します。失敗した場合は false を返します。
25 */
26function createAndCompressImageArchive(array $imageNames, string $archiveBaseName, int $compression = Phar::GZ): string|false
27{
28    // 一時ディレクトリを作成し、サンプルファイルを生成する
29    $tempDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid('php_phar_example_');
30    if (!mkdir($tempDir, 0777, true)) {
31        error_log("一時ディレクトリの作成に失敗しました: {$tempDir}");
32        return false;
33    }
34
35    $archiveFullPath = $tempDir . DIRECTORY_SEPARATOR . $archiveBaseName . '.tar';
36    $createdImageFilePaths = [];
37
38    echo "ダミー画像ファイルを作成中 (場所: {$tempDir})...\n";
39    foreach ($imageNames as $filename) {
40        $tempImagePath = $tempDir . DIRECTORY_SEPARATOR . $filename;
41        // 実際の画像データではなく、ダミーの内容を書き込む
42        // 実際には、既存の画像ファイルをコピーしたり、パスを指定して追加したりします。
43        $dummyContent = "This is a dummy image file content for {$filename}.\n" . str_repeat('PHP', rand(100, 500));
44        if (file_put_contents($tempImagePath, $dummyContent) === false) {
45            error_log("ダミー画像ファイル '{$filename}' の作成に失敗しました。");
46            // 失敗した場合はクリーンアップして終了
47            array_map('unlink', $createdImageFilePaths);
48            @rmdir($tempDir); // 中身が空でなければ失敗する可能性あり (エラー抑制)
49            return false;
50        }
51        $createdImageFilePaths[] = $tempImagePath;
52        echo "  - {$tempImagePath} (" . filesize($tempImagePath) . " bytes)\n";
53    }
54
55    try {
56        // PharData オブジェクトを作成(Phar::TAR 形式で新規作成)
57        // 第2引数の Phar::TAR は、このアーカイブが tar 形式であることを明示します。
58        // 第3引数はアーカイブのエイリアス(別名)ですが、ここでは null を指定します。
59        $phar = new PharData($archiveFullPath, Phar::TAR, null);
60        echo "アーカイブ '{$archiveFullPath}' を作成中...\n";
61
62        // アーカイブにファイルを追加
63        foreach ($createdImageFilePaths as $fullPath) {
64            // addFileの第2引数は、アーカイブ内でのファイル名です。
65            // ここでは、元のファイル名をそのまま使用します。
66            $phar->addFile($fullPath, basename($fullPath));
67            echo "  - ファイル '" . basename($fullPath) . "' をアーカイブに追加しました。\n";
68        }
69
70        // アーカイブ内のファイルを圧縮
71        // $compression には Phar::GZ (Gzip圧縮) または Phar::BZ2 (Bzip2圧縮) を指定します。
72        $compressionTypeName = match ($compression) {
73            Phar::GZ => "Gzip",
74            Phar::BZ2 => "Bzip2",
75            default => "不明な形式",
76        };
77        echo "アーカイブ内のファイルを圧縮中 (形式: {$compressionTypeName})...\n";
78        
79        if ($phar->compressFiles($compression)) {
80            echo "アーカイブ内のファイルの圧縮に成功しました。\n";
81        } else {
82            error_log("アーカイブ内のファイルの圧縮に失敗しました。");
83            return false;
84        }
85
86        // PharData オブジェクトを明示的に解放 (Windowsなどでファイルロックを解除するため)
87        unset($phar); 
88        return $archiveFullPath;
89
90    } catch (PharException $e) {
91        error_log("Phar 操作中にエラーが発生しました: " . $e->getMessage());
92        return false;
93    } finally {
94        // 後処理: 生成したダミー画像ファイルを削除
95        echo "一時的なダミーファイルを削除中...\n";
96        foreach ($createdImageFilePaths as $file) {
97            if (file_exists($file)) {
98                unlink($file);
99            }
100        }
101        // 注意: アーカイブファイルは呼び出し元で削除します。
102        // 一時ディレクトリは、アーカイブファイルが削除された後に空になれば削除可能です。
103    }
104}
105
106// --- サンプルコードの実行 ---
107// 圧縮するダミー画像ファイルのリスト
108$imagesToCompress = [
109    'image1.jpg',
110    'photo_2.png',
111    'screenshot_3.gif',
112];
113
114// 作成するアーカイブのベース名
115$archiveBaseName = 'my_images_archive'; 
116
117// 関数を呼び出してアーカイブを作成・圧縮
118// ここではGzip圧縮を使用
119$compressedArchiveFilePath = createAndCompressImageArchive($imagesToCompress, $archiveBaseName, Phar::GZ);
120
121if ($compressedArchiveFilePath) {
122    echo "\n=== 成功 ===";
123    echo "\n圧縮されたアーカイブファイルが '{$compressedArchiveFilePath}' に作成されました。\n";
124    echo "このファイルは '.tar' 形式で、内部のファイルがGzip圧縮されています。\n";
125    echo "ファイルサイズ: " . filesize($compressedArchiveFilePath) . " bytes\n";
126
127    // 注意: compressFiles()はアーカイブ自体を .tar.gz に変更するのではなく、
128    // アーカイブ内部のファイルを透過的に圧縮します。
129    // そのため、ファイル名は .tar のままですが、中身は圧縮されています。
130    // このアーカイブの内容を確認するには、tar コマンドなどで展開する必要があります。
131    // 例 (Linux/macOS): tar -tvf my_images_archive.tar
132    // 例 (PHPから内容を確認):
133    try {
134        echo "\n=== アーカイブの内容を確認中 (PHPからアクセス) ===\n";
135        $phar = new PharData($compressedArchiveFilePath);
136        foreach (new RecursiveIteratorIterator($phar) as $file) {
137            // PharEntry はアーカイブ内のファイル名とパスを表す
138            echo "  - " . $file->getPathName() . " (アーカイブ内で圧縮済み)\n";
139        }
140        unset($phar); // オブジェクトを解放
141    } catch (PharException $e) {
142        error_log("アーカイブの内容確認中にエラー: " . $e->getMessage());
143    }
144
145    // サンプルの後処理: 生成されたアーカイブファイルと一時ディレクトリを削除
146    if (file_exists($compressedArchiveFilePath)) {
147        echo "\n生成されたアーカイブ '{$compressedArchiveFilePath}' を削除します。\n";
148        unlink($compressedArchiveFilePath);
149
150        // アーカイブファイルが削除された後、一時ディレクトリが空であれば削除
151        $tempDir = dirname($compressedArchiveFilePath);
152        // . と .. 以外のエントリがないことを確認
153        if (is_dir($tempDir) && count(scandir($tempDir)) === 2) { 
154            rmdir($tempDir);
155            echo "一時ディレクトリ '{$tempDir}' を削除しました。\n";
156        } else {
157            echo "注意: 一時ディレクトリ '{$tempDir}' は完全に空ではありませんでした。\n";
158        }
159    }
160
161} else {
162    echo "\n=== 失敗 ===\nアーカイブの作成と圧縮に失敗しました。\n";
163}
164
165?>

PHPのPharData::compressFilesメソッドは、複数のファイルをまとめたPharDataアーカイブ内の個々のファイルを指定された形式で圧縮します。この機能は、特にシステムエンジニアが複数のファイルをまとめて配布したり、バックアップしたりする際に、アーカイブ全体のファイルサイズを効率的に削減するためのものです。引数$compressionには、Phar::GZ(Gzip圧縮)またはPhar::BZ2(Bzip2圧縮)のような定数を指定し、アーカイブ内の各ファイルに透過的に圧縮を適用します。これは、JPEGやPNGといった画像フォーマット特有の、画質を低下させてファイルサイズを減らす「非可逆圧縮」とは異なります。compressFilesは、ファイルの品質そのものを変更せず、データサイズのみを小さくする「可逆圧縮」に近いです。メソッドが正常に実行されればtrueが、何らかの問題で失敗した場合はfalseが戻り値として返されるため、処理の成否をプログラムで判断できます。このメソッドを利用することで、大量のデータを扱うシステムの効率性を向上させることが可能です。

PharData::compressFilesは、画像ファイルの品質を直接低下させるのではなく、複数のファイルをまとめたアーカイブの内部にあるファイルをGzipやBzip2形式で圧縮する機能です。これにより、アーカイブ全体のサイズを効率的に削減できます。

重要な点として、このメソッドはアーカイブファイル自体の拡張子を.tar.gzのように変更するわけではなく、元の.tar拡張子のままで内部的に圧縮が行われます。そのため、内容を確認する際には、圧縮を意識して展開する必要があります。

利用する際には、PHPのPhar拡張が有効になっていることを確認してください。また、Phar::GZやPhar::BZ2などの適切な圧縮定数を引数に指定します。メソッドの戻り値がfalseの場合には圧縮が失敗しているため、必ずエラー処理を実装してください。特にWindows環境では、Pharオブジェクトをunset()で明示的に解放し、ファイルロックを避けることが安全な利用の鍵となります。

関連コンテンツ

関連IT用語

関連プログラミング言語