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

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

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

作成日: 更新日:

基本的な使い方

extractToメソッドは、PHPアプリケーションやライブラリを一つにまとめたPharアーカイブファイルの内容を、指定したディレクトリに展開(解凍)するメソッドです。このメソッドを利用することで、Pharファイル内部に格納されている複数のファイルやディレクトリを、通常のファイルシステム上に復元し、利用可能な状態にできます。

このメソッドの第一引数には、アーカイブを展開したい先のディレクトリパスを指定します。この展開先ディレクトリは、メソッドが呼び出される前に既に存在している必要があります。第二引数はオプションで、Pharアーカイブ内から展開したい特定のファイルやディレクトリを、単一の文字列または文字列の配列として指定できます。この引数を省略した場合、Pharアーカイブに含まれるすべての内容が展開されます。

さらに、第三引数もオプションで、展開先のディレクトリに同名のファイルが既に存在する場合に、そのファイルを上書きするかどうかを真偽値で指定します。trueを指定すると既存ファイルが上書きされ、false(デフォルト値)の場合は、既存ファイルがある場合に展開が失敗します。このメソッドは、Pharアーカイブの内容を確認したい場合や、一部のコンポーネントを独立して利用したい場合に非常に有効です。

構文(syntax)

1<?php
2$phar = new Phar('archive.phar');
3$phar->extractTo('extracted_directory');
4?>

引数(parameters)

string $directory, array|string|null $files = null, bool $overwrite = false

  • string $directory: Pharアーカイブを展開する先のディレクトリパス
  • array|string|null $files = null: 展開するファイルまたはディレクトリのパスを指定します。null の場合は Phar アーカイブ内の全てのファイルが展開されます。
  • bool $overwrite = false: 展開先に同名のファイルが存在する場合に上書きするかどうかを指定します。true の場合は上書きします。

戻り値(return)

bool

pharアーカイブを指定されたディレクトリに展開できた場合は true を、それ以外の場合は false を返します。

サンプルコード

PHP Phar::extractTo でPHARを展開する

1<?php
2
3// PHARファイルのファイル名
4const PHAR_FILE = 'my_application.phar';
5// PHARファイルに含める一時ファイルのソースディレクトリ
6const SOURCE_DIR = 'temp_source_for_phar';
7// 抽出先のディレクトリ
8const EXTRACT_DIR = 'extracted_application_files';
9
10/**
11 * ディレクトリとその内容を再帰的に削除します。
12 *
13 * @param string $dirPath 削除するディレクトリのパス
14 * @return bool 成功した場合はtrue、失敗した場合はfalse
15 */
16function deleteDirectory(string $dirPath): bool
17{
18    if (!file_exists($dirPath)) {
19        return true;
20    }
21    if (!is_dir($dirPath)) {
22        return unlink($dirPath); // ディレクトリではなくファイルの場合
23    }
24
25    $items = scandir($dirPath);
26    if ($items === false) {
27        return false; // ディレクトリを読み取れない場合
28    }
29
30    foreach ($items as $item) {
31        if ($item === '.' || $item === '..') {
32            continue;
33        }
34        $itemPath = $dirPath . DIRECTORY_SEPARATOR . $item;
35        if (!deleteDirectory($itemPath)) {
36            return false;
37        }
38    }
39    return rmdir($dirPath);
40}
41
42// 既存の一時ファイルやディレクトリをクリーンアップして、サンプルを確実に実行できるように準備
43deleteDirectory(SOURCE_DIR);
44deleteDirectory(EXTRACT_DIR);
45if (file_exists(PHAR_FILE)) {
46    unlink(PHAR_FILE);
47}
48
49try {
50    // --- 1. PHARアーカイブの作成 (サンプルコード実行に必要な準備) ---
51    // 抽出対象となるPHARファイルを作成します。
52    // PHARに含めるためのソースディレクトリとファイルを準備します。
53    mkdir(SOURCE_DIR);
54    file_put_contents(SOURCE_DIR . '/index.php', "<?php echo 'Hello from PHAR!';");
55    file_put_contents(SOURCE_DIR . '/config.json', '{"app_name": "MyPharApp", "version": "1.0.0"}');
56    mkdir(SOURCE_DIR . '/assets');
57    file_put_contents(SOURCE_DIR . '/assets/logo.txt', 'This is a logo placeholder.');
58
59    echo "--- PHARアーカイブ作成中 ---\n";
60    // 注意: Pharアーカイブを作成するには、php.iniで 'phar.readonly = Off' の設定が必要です。
61    // 一時的にini_set()で設定することも可能ですが、本番環境での推奨はphp.iniでの設定です。
62    // ini_set('phar.readonly', '0'); // 必要に応じてコメント解除
63
64    $phar = new Phar(PHAR_FILE);
65    // PHARにソースディレクトリの内容を全て追加します。
66    // 第2引数でファイルのパスを相対パスとしてPHAR内に保存します。
67    $phar->buildFromDirectory(SOURCE_DIR);
68    // PHARが実行可能になるためのスタブを設定します (オプションですが、実行可能なPHARには推奨)。
69    // ここでは、デフォルトのスタブを生成し、PHARが実行されたときに 'index.php' が起動するように設定しています。
70    $phar->setStub($phar->createDefaultStub('index.php'));
71    echo "PHARアーカイブ '" . PHAR_FILE . "' が作成されました。\n";
72
73    // Pharオブジェクトを閉じ、アーカイブを確定させます。
74    unset($phar);
75
76
77    // --- 2. Phar::extractTo メソッドの使用 ---
78    echo "\n--- PHARアーカイブからコンテンツを抽出中 ---\n";
79
80    // 抽出先のディレクトリを作成します。
81    mkdir(EXTRACT_DIR);
82
83    // 作成したPHARファイルを開きます。
84    $phar = new Phar(PHAR_FILE);
85
86    // 例1: 全てのファイルを抽出する
87    // extractTo(string $directory, array|string|null $files = null, bool $overwrite = false)
88    // 第2引数にnullを渡すと、アーカイブ内の全てのファイルが抽出されます。
89    // 第3引数にfalseを渡すと、既存のファイルは上書きされません。
90    echo "例1: 全てのファイルを '" . EXTRACT_DIR . "' に抽出します (既存ファイルは上書きしない)。\n";
91    $successAll = $phar->extractTo(EXTRACT_DIR, null, false);
92
93    if ($successAll) {
94        echo "全てのファイルの抽出に成功しました。\n";
95        // 抽出されたファイルの一部が存在することを確認
96        if (file_exists(EXTRACT_DIR . '/index.php') && file_exists(EXTRACT_DIR . '/config.json')) {
97            echo "-> 'index.php' と 'config.json' が存在します。\n";
98        }
99    } else {
100        echo "全てのファイルの抽出に失敗しました。\n";
101    }
102
103    // 例2: 特定のファイルのみを抽出し、上書きを許可する
104    // この例のデモンストレーションのため、抽出ディレクトリを一度クリーンアップします。
105    deleteDirectory(EXTRACT_DIR);
106    mkdir(EXTRACT_DIR);
107
108    echo "\n例2: 特定のファイル 'config.json' のみを '" . EXTRACT_DIR . "' に抽出し、上書きを許可します。\n";
109    $successSpecific = $phar->extractTo(EXTRACT_DIR, 'config.json', true); // 'config.json' のみを抽出し、上書きを許可
110
111    if ($successSpecific) {
112        echo "ファイル 'config.json' の抽出に成功しました。\n";
113        // 特定のファイルのみが抽出されたことを確認
114        if (file_exists(EXTRACT_DIR . '/config.json')) {
115            echo "-> 'config.json' が存在します。\n";
116        }
117        if (!file_exists(EXTRACT_DIR . '/index.php')) {
118            echo "-> 'index.php' は抽出されていません (期待通り)。\n";
119        }
120    } else {
121        echo "ファイル 'config.json' の抽出に失敗しました。\n";
122    }
123
124} catch (PharException $e) {
125    echo "エラーが発生しました: " . $e->getMessage() . "\n";
126    echo "PHARアーカイブの作成/読み込みには 'phar.readonly=Off' (作成時) または 'phar.readonly=On' (読み込み時) の設定が必要な場合があります。\n";
127} finally {
128    // --- 3. クリーンアップ ---
129    echo "\n--- クリーンアップ中 ---\n";
130    // 作成したPHARファイルと一時ディレクトリを削除します。
131    if (file_exists(PHAR_FILE)) {
132        unlink(PHAR_FILE);
133        echo "PHARアーカイブ '" . PHAR_FILE . "' を削除しました。\n";
134    }
135    deleteDirectory(SOURCE_DIR);
136    echo "ソースディレクトリ '" . SOURCE_DIR . "' を削除しました。\n";
137    deleteDirectory(EXTRACT_DIR);
138    echo "抽出ディレクトリ '" . EXTRACT_DIR . "' を削除しました。\n";
139    echo "クリーンアップ完了。\n";
140}

PHPのPharクラスのextractToメソッドは、PHPアプリケーションを一つのアーカイブにまとめたPHARファイルから、その中身のファイルやディレクトリを指定した場所へ展開するために使用されます。これにより、配布されたアプリケーションのコンテンツを簡単に取り出すことができます。

このメソッドは3つの引数を取ります。まず、$directory引数には、PHARファイルの内容を展開したい先のディレクトリパスを文字列で指定します。次に、$files引数では、抽出したいファイルやディレクトリを特定できます。この引数をnullに設定するか省略すると、PHARアーカイブ内の全てのコンテンツが抽出されます。特定のファイルのみを抽出する場合はファイルパスを文字列で、複数のファイルを抽出する場合はそれらのファイルパスを配列で渡します。最後に、$overwrite引数は、抽出先に同名のファイルが既に存在する場合に、上書きを許可するかどうかを真偽値(trueで上書き許可、falseで上書き禁止)で設定します。

メソッドの戻り値はbool型で、抽出処理が成功した場合はtrue、失敗した場合はfalseを返します。

サンプルコードは、まずPHARアーカイブを作成し、その後extractToメソッドを使ってアーカイブ内の全てのファイルを抽出する例と、特定のファイルのみを抽出する例を示しています。PHARアーカイブの作成には、PHPの実行環境でphar.readonly = Offの設定が必要になる場合がありますのでご注意ください。

Phar::extractToメソッドは、PHPのPHARアーカイブからファイルやディレクトリを特定の場所へ抽出する際に利用します。第一引数で指定する抽出先ディレクトリは、事前に作成しておく必要があります。第二引数でnullを指定するとアーカイブ内の全てのファイルが抽出されますが、特定のファイルやディレクトリのみを抽出したい場合は、アーカイブ内の相対パスでファイル名を文字列または配列で指定してください。第三引数は、同名のファイルが既に存在する場合に上書きを許可するかどうかを決定します。安全のため、既存ファイルを上書きしない場合はfalseを、上書きを許可する場合はtrueを設定し、意図しないデータ消失を防ぎましょう。このメソッドは成功時にtrue、失敗時にfalseを返すため、戻り値を確認して適切なエラーハンドリングを行うことが重要です。

PHP Phar::extractTo でアーカイブを抽出する

1<?php
2
3// このスクリプトは、Phar::extractTo メソッドの使用方法を示すサンプルです。
4// Pharアーカイブを作成し、その内容を指定したディレクトリに抽出します。
5// システムエンジニアを目指す初心者の方にも分かりやすいように、必要な手順と説明を含みます。
6
7// --------------------------------------------------------------------------------------------------------------------
8// 前提条件:
9// Pharアーカイブを作成するには、PHPの設定ファイル (php.ini) で 'phar.readonly = Off' に設定されている必要があります。
10// 多くの共有ホスティング環境ではこの設定を変更できません。開発環境やVPS/専用サーバーで実行してください。
11// 既にPharファイルが存在し、それを展開するだけであれば 'phar.readonly = On' のままでも動作します。
12// --------------------------------------------------------------------------------------------------------------------
13
14// 定数定義
15const PHAR_FILE_NAME = __DIR__ . '/example.phar';      // 作成するPharアーカイブのファイル名
16const EXTRACT_DIRECTORY = __DIR__ . '/extracted';    // 抽出先のディレクトリ名
17
18/**
19 * 指定されたディレクトリとその中身を再帰的に削除するヘルパー関数。
20 * 主に一時ファイルのクリーンアップに使用します。
21 */
22function rrmdir(string $dir): void
23{
24    if (!is_dir($dir)) {
25        return;
26    }
27    $files = array_diff(scandir($dir), ['.', '..']);
28    foreach ($files as $file) {
29        $path = $dir . DIRECTORY_SEPARATOR . $file;
30        (is_dir($path)) ? rrmdir($path) : unlink($path);
31    }
32    rmdir($dir);
33}
34
35// --------------------------------------------------------------------------------------------------------------------
36// メイン処理の開始
37// --------------------------------------------------------------------------------------------------------------------
38
39echo "--- Phar::extractTo メソッドのサンプル --- \n\n";
40
41// 1. クリーンアップ: 前回の実行で残った一時ファイルを削除します。
42if (file_exists(PHAR_FILE_NAME)) {
43    unlink(PHAR_FILE_NAME);
44    echo "既存のPharアーカイブを削除しました: " . PHAR_FILE_NAME . "\n";
45}
46if (is_dir(EXTRACT_DIRECTORY)) {
47    rrmdir(EXTRACT_DIRECTORY);
48    echo "既存の抽出先ディレクトリを削除しました: " . EXTRACT_DIRECTORY . "\n";
49}
50echo "\n";
51
52try {
53    // ----------------------------------------------------------------------------------------------------------------
54    // 2. サンプルPharアーカイブの作成 (テスト用)
55    // 実際にPhar::extractToを使用する際は、この部分は既に存在するPharファイルを開く処理になります。
56    // ----------------------------------------------------------------------------------------------------------------
57
58    // Pharアーカイブを作成するために 'phar.readonly' を一時的にオフにする必要がある場合があります。
59    // ini_set('phar.readonly', '0'); // 環境によってはコメントアウトを解除して有効にしてください
60
61    // 一時的なPharオブジェクトを作成(書き込みモード)
62    $phar = new Phar(PHAR_FILE_NAME);
63    $phar->startBuffering(); // バッファリングを開始し、効率的な書き込みを可能にする
64
65    // アーカイブに追加するテストファイルの内容を定義
66    $testFile1Content = "これはアーカイブ内の1つ目のファイルです。\n";
67    $testFile2Content = "これはアーカイブ内のサブディレクトリにある2つ目のファイルです。\n";
68
69    // ファイルをPharアーカイブに追加 (addFromStringは文字列を直接ファイルとして追加)
70    $phar->addFromString('file1.txt', $testFile1Content);
71    $phar->addFromString('sub_dir/file2.txt', $testFile2Content); // サブディレクトリ内のファイルとして追加
72
73    $phar->stopBuffering(); // バッファリングを終了し、変更をPharファイルに書き込む
74    echo "サンプルPharアーカイブ '" . PHAR_FILE_NAME . "' が作成されました。\n";
75    echo "  - 含まれるファイル: file1.txt\n";
76    echo "  - 含まれるファイル: sub_dir/file2.txt\n\n";
77
78    // ini_set('phar.readonly', '1'); // 必要であれば元の設定に戻す
79
80    // ----------------------------------------------------------------------------------------------------------------
81    // 3. Phar::extractTo メソッドを使用してファイルを抽出
82    // ----------------------------------------------------------------------------------------------------------------
83
84    // 抽出先ディレクトリが存在しない場合は作成
85    if (!is_dir(EXTRACT_DIRECTORY)) {
86        mkdir(EXTRACT_DIRECTORY, 0777, true);
87        echo "抽出先ディレクトリ '" . EXTRACT_DIRECTORY . "' を作成しました。\n";
88    }
89
90    // 作成したPharアーカイブを読み込みモードで開く
91    // (既に開いているPharオブジェクトを使用する場合、通常は新しいPharオブジェクトを作成する必要はありませんが、
92    // ここでは作成と抽出の役割を明確にするため、あえて新しいオブジェクトを作成しています)
93    $pharToExtract = new Phar(PHAR_FILE_NAME);
94
95    // Phar::extractTo(string $directory, array|string|null $files = null, bool $overwrite = false): bool
96    // $directory: ファイルを抽出する先のディレクトリパス。
97    // $files: 抽出するファイルやディレクトリのリスト。nullの場合はアーカイブ内の全てを抽出。
98    // $overwrite: 抽出先に同名のファイルが存在する場合に上書きするかどうか。デフォルトはfalse (上書きしない)。
99    $extractionSuccessful = $pharToExtract->extractTo(EXTRACT_DIRECTORY, null, true); // 全て抽出し、既存ファイルは上書き
100
101    if ($extractionSuccessful) {
102        echo "Pharアーカイブの内容が '" . EXTRACT_DIRECTORY . "' に正常に抽出されました。\n";
103        echo "抽出されたファイルの内容を確認:\n";
104        echo "  - " . EXTRACT_DIRECTORY . DIRECTORY_SEPARATOR . 'file1.txt' . ": " . file_get_contents(EXTRACT_DIRECTORY . DIRECTORY_SEPARATOR . 'file1.txt');
105        echo "  - " . EXTRACT_DIRECTORY . DIRECTORY_SEPARATOR . 'sub_dir' . DIRECTORY_SEPARATOR . 'file2.txt' . ": " . file_get_contents(EXTRACT_DIRECTORY . DIRECTORY_SEPARATOR . 'sub_dir' . DIRECTORY_SEPARATOR . 'file2.txt');
106    } else {
107        echo "エラー: Pharアーカイブの抽出に失敗しました。\n";
108    }
109
110} catch (PharException $e) {
111    // Phar関連のエラーを捕捉
112    echo "Phar関連のエラーが発生しました: " . $e->getMessage() . "\n";
113} catch (Exception $e) {
114    // その他の予期せぬエラーを捕捉
115    echo "予期せぬエラーが発生しました: " . $e->getMessage() . "\n";
116} finally {
117    // ----------------------------------------------------------------------------------------------------------------
118    // 4. 後処理: 作成した一時ファイルとディレクトリの削除
119    // ----------------------------------------------------------------------------------------------------------------
120    echo "\n--- クリーンアップ --- \n";
121    if (file_exists(PHAR_FILE_NAME)) {
122        unlink(PHAR_FILE_NAME);
123        echo "一時的なPharアーカイブ '" . PHAR_FILE_NAME . "' を削除しました。\n";
124    }
125    if (is_dir(EXTRACT_DIRECTORY)) {
126        rrmdir(EXTRACT_DIRECTORY);
127        echo "抽出先ディレクトリ '" . EXTRACT_DIRECTORY . "' とその中身を削除しました。\n";
128    }
129    echo "クリーンアップが完了しました。\n";
130}

PHPのPhar::extractToメソッドは、複数のファイルやディレクトリを一つにまとめたPharアーカイブから、その内容を指定したディレクトリに展開するために使用されます。これは、アプリケーションの配布形式として利用されるPharファイルを、必要に応じて元のファイル群に戻したい場合に大変便利な機能です。

このメソッドは主に3つの引数を取ります。最初の$directoryは、アーカイブの内容を抽出する先のディレクトリパスを指定します。$files引数は、アーカイブから抽出したい特定のファイルやディレクトリを配列または文字列で指定します。この引数をnullに設定すると、アーカイブ内の全てのファイルが抽出されます。最後の$overwriteは、抽出先のディレクトリに同名のファイルが存在した場合に、それらを上書きするかどうかを真偽値(trueまたはfalse)で指定します。デフォルトではfalseが設定されており、既存のファイルを上書きしません。メソッドは、抽出処理が成功した場合にはtrueを、失敗した場合にはfalseを戻り値として返します。

サンプルコードでは、まずテスト用に一時的なPharアーカイブを作成し、その中にファイルを追加しています。その後、Phar::extractToメソッドを使用して、作成したPharアーカイブの内容を新しいディレクトリに全て抽出しています。このPharアーカイブの作成には、php.iniphar.readonly = Offの設定が必要な場合がありますが、既存のPharファイルを展開するだけであればこの設定を変更する必要はありません。これにより、アーカイブされたファイルが指定されたディレクトリに復元され、内容を確認できます。

Phar::extractToメソッドは、Pharアーカイブからファイルを指定ディレクトリに抽出する際に用います。特に注意すべき点は、第三引数$overwriteです。これをtrueに設定すると、抽出先に同名のファイルがあっても警告なく上書きされてしまうため、重要なファイルが失われないよう十分な確認が必要です。Pharファイルを展開する操作自体はPHP設定phar.readonlyOnでも通常は可能ですが、Pharファイルを新たに作成するにはOffにする必要があることを理解しておきましょう。展開先のディレクトリが存在しない場合は、事前にmkdirなどで作成する必要があります。メソッドの戻り値は成功時にtrue、失敗時にfalseとなるため、適切なエラーハンドリングを実装することが大切です。セキュリティのため、抽出先のディレクトリは信頼できるパスを指定してください。

関連コンテンツ