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

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

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

作成日: 更新日:

基本的な使い方

mungServerメソッドは、Pharアーカイブ内のPHPスクリプトがWebサーバー環境で動作する際に、特定の$_SERVER変数の値を修正するメソッドです。

PharアーカイブをWebアプリケーションとして利用する場合、Webサーバーからアクセスされると、$_SERVER変数群、例えば$_SERVER['PHP_SELF']や$_SERVER['SCRIPT_NAME']などの値が、Pharアーカイブ自体のパスを指してしまうことがあります。しかし、Pharアーカイブ内部のPHPスクリプトは、自身の場所をアーカイブのルートディレクトリからの相対パスとして認識する必要があります。

このmungServerメソッドは、そのような状況において、$_SERVER変数の値をPharアーカイブ内部のパス構造に合わせて書き換える役割を担います。引数として配列を受け取り、その配列内に指定された$_SERVER変数のキー(例: ['PHP_SELF', 'REQUEST_URI'])に対応する値を修正します。これにより、Pharアーカイブ内部で動作するスクリプトが、あたかもアーカイブがWebサーバーのルートディレクトリであるかのように動作し、パス解決やリソースの参照が正しく行われるようになります。

特に、$_SERVER['PHP_SELF']、$_SERVER['SCRIPT_NAME']、$_SERVER['SCRIPT_FILENAME']、$_SERVER['DOCUMENT_ROOT']、$_SERVER['REQUEST_URI']といった変数が主な修正対象となります。この機能は、Pharアーカイブとして配布されるWebアプリケーションの互換性と信頼性を高める上で非常に重要です。

構文(syntax)

1<?php
2
3Phar::mungServer(['REQUEST_URI', 'PHP_SELF', 'SCRIPT_NAME']);
4
5?>

引数(parameters)

array $variables

  • array $variables: Phar::mungServer() が要求する環境変数名の連想配列

戻り値(return)

void

このメソッドは、Pharアーカイブの生成時にサルベージしたいサーバーメタデータのリストを設定するために使用されます。戻り値はありません。

サンプルコード

Phar::mungServerで$_SERVERを偽装する

1<?php
2
3/**
4 * Phar::mungServer() メソッドの使用例。
5 *
6 * このメソッドは、PHPの組み込みWebサーバーでPharアーカイブが実行される際に、
7 * $_SERVER 変数のエントリを変更するために使用されます。
8 * アプリケーションが特定のサーバー変数を期待している場合、
9 * それを偽装することで環境の互換性を高めることができます。
10 *
11 * 注意: 'php mysql server has gone away' エラーは通常、データベース接続のタイムアウトや
12 * MySQLサーバー側の問題が原因であり、$_SERVER 変数の調整で直接解決されるものではありません。
13 * このサンプルはPhar::mungServerの機能を示すものであり、特定のデータベースエラーの直接的な解決策ではありません。
14 */
15
16try {
17    // 作成するPharアーカイブのファイルパスを指定します。
18    $pharFileName = __DIR__ . '/application.phar';
19
20    // 既存のPharファイルを削除し、新しいアーカイブを作成できるように準備します。
21    // 本番環境でのPhar作成では、この削除処理は慎重に行うべきです。
22    if (file_exists($pharFileName)) {
23        unlink($pharFileName);
24    }
25
26    // 新しいPharアーカイブを作成するためのPharオブジェクトをインスタンス化します。
27    // 第二引数 '0' はデフォルトのフラグ、第三引数 'application.phar' はエイリアスです。
28    $phar = new Phar($pharFileName, 0, 'application.phar');
29
30    // Pharアーカイブへの書き込みを開始します。
31    $phar->startBuffering();
32
33    // Phar::mungServer() に渡す、偽装したい$_SERVER変数を定義します。
34    // これらの変数は、PharがPHPの組み込みWebサーバーで実行されたときに、
35    // 実際の$_SERVER変数を上書きまたは追加します。
36    $variablesToMung = [
37        'REQUEST_URI' => '/my-app/index.php',
38        'SCRIPT_NAME' => '/my-app/index.php',
39        'SERVER_NAME' => 'phar-test.local',
40        'SERVER_PORT' => '80',
41    ];
42
43    // mungServer メソッドを呼び出し、Pharアーカイブに$_SERVER変数の変更を予約します。
44    // この設定は、Pharアーカイブが組み込みWebサーバーでリクエストされた際に適用されます。
45    $phar->mungServer($variablesToMung);
46
47    // Pharアーカイブに含めるエントリポイントとなるファイルを定義します。
48    // ここでは、Pharが実行されたときに$_SERVER変数の値を表示する簡単なPHPスクリプトを追加します。
49    $phar->addFromString('index.php', <<<'PHP_CODE'
50<?php
51// このコードは、作成された application.phar の内部で実行されます。
52// Phar::mungServer() で設定された値が反映されていることを確認できます。
53echo "Hello from Phar application!\n";
54echo "Current SCRIPT_NAME: " . ($_SERVER['SCRIPT_NAME'] ?? 'N/A') . "\n";
55echo "Current SERVER_NAME: " . ($_SERVER['SERVER_NAME'] ?? 'N/A') . "\n";
56echo "Current REQUEST_URI: " . ($_SERVER['REQUEST_URI'] ?? 'N/A') . "\n";
57?>
58PHP_CODE);
59
60    // Pharのスタブを設定します。
61    // スタブは、Pharファイルを直接実行したときに最初に実行されるコード(エントリポイント)を定義します。
62    // createDefaultStub() は、指定されたファイルをデフォルトのエントリポイントとして設定します。
63    $phar->setStub($phar->createDefaultStub('index.php'));
64
65    // Pharアーカイブへの書き込みを終了し、ファイルを保存します。
66    $phar->stopBuffering();
67
68    // このスクリプトは 'application.phar' ファイルを作成します。
69    // mungServer() の効果を確認するには、このPharファイルをPHPの組み込みWebサーバーで実行する必要があります。
70    // 例:
71    // 1. コマンドラインでこのスクリプトを実行し、'application.phar' を生成します。
72    // 2. 同じディレクトリで 'php -S localhost:8000 application.phar' を実行します。
73    // 3. ブラウザで 'http://localhost:8000/my-app/index.php' にアクセスし、出力される$_SERVER変数の値を確認します。
74
75} catch (PharException $e) {
76    // Phar固有のエラーが発生した場合の処理。
77    // サンプルコード以外の出力は行わないため、ここではエラーメッセージを標準出力しません。
78    // 実際のアプリケーションでは、エラーログなどに記録することが推奨されます。
79} catch (Exception $e) {
80    // その他の一般的なエラーが発生した場合の処理。
81    // 同様に、エラーメッセージは標準出力しません。
82}
83

Phar::mungServer()メソッドは、PharアーカイブがPHPの組み込みWebサーバーで実行される際に、特別な機能を提供します。このメソッドは、グローバル変数$_SERVERの特定のエントリを、指定した値で上書きまたは追加するために使用されます。これにより、Pharアーカイブ内で動作するアプリケーションが、特定のサーバー環境変数を期待している場合に、その環境を偽装し、互換性を高めることができます。

引数$variablesには、連想配列形式で変更したい$_SERVER変数のキーと値を渡します。例えば、'REQUEST_URI'や'SERVER_NAME'などを指定することで、Pharが組み込みWebサーバー上で実行されたときに、これらの値が実際に上書きされます。戻り値はvoidであり、このメソッド自体は何も値を返しません。単にPharアーカイブの設定を変更する役割を果たします。

サンプルコードでは、application.pharというアーカイブを作成し、その内部でREQUEST_URIやSERVER_NAMEなどの$_SERVER変数を事前に定義した値で偽装する例を示しています。これにより、アーカイブ内のスクリプトがこれらの偽装された変数を参照できるようになります。

なお、「php mysql server has gone away」というエラーは通常、データベース接続のタイムアウトやMySQLサーバー側の問題で発生します。Phar::mungServer()は$_SERVER変数を調整する機能であり、データベース接続の問題を直接解決するものではないことにご留意ください。このメソッドは、アプリケーションが実行されるサーバー環境のシミュレーションや調整に役立ちます。

Phar::mungServer()は、PharアーカイブがPHPの組み込みWebサーバーで動作する際に、$_SERVER変数の値を変更する機能です。アプリケーションが特定のサーバー変数を期待する場合に、互換性を高める目的で使われます。

重要な注意点として、「php mysql server has gone away」エラーはデータベース接続のタイムアウトなど別原因であり、このメソッドで直接解決されるものではありません。既存のPharファイルを削除する処理は、本番環境での運用では特に慎重な検討が必要です。このメソッドの効果は、PharファイルをPHP組み込みWebサーバーで実行した際にのみ現れますので、実行環境にご注意ください。エラーが発生した場合は、実際にはエラーログへ記録することが推奨されます。

PHP Phar mungServerで$_SERVERを操作する

1<?php
2
3// Pharアーカイブの作成には 'phar.readonly' を '0' に設定する必要があります。
4// これは開発時やビルドスクリプトでのみ行い、本番環境では注意が必要です。
5ini_set('phar.readonly', 0);
6
7/**
8 * Phar::mungServer メソッドの動作を示すPharアーカイブを作成し、実行する関数。
9 *
10 * この関数は、`$_SERVER` 変数を変更する設定を持つPharアーカイブを生成します。
11 * その後、生成されたアーカイブを実行し、`Phar::mungServer` によって設定された
12 * 値がアーカイブ内のスクリプトにどのように反映されるかを示します。
13 *
14 * @param string $pharFileName 生成するPharアーカイブのファイル名。
15 * @param string $filePathInPhar アーカイブ内に含めるスクリプトのパス名。
16 * @return void
17 */
18function demonstratePharMungServer(string $pharFileName = 'munged_server_app.phar', string $filePathInPhar = 'index.php'): void
19{
20    // 以前に作成されたPharファイルが残っている場合、削除して再生成を準備します。
21    if (file_exists($pharFileName)) {
22        unlink($pharFileName);
23    }
24
25    try {
26        // 1. 新しいPharアーカイブを作成します。
27        // Pharコンストラクタは例外をスローする可能性があるため、try-catchブロック内で処理します。
28        $phar = new Phar($pharFileName);
29
30        // 2. アーカイブ内に含めるPHPスクリプトの内容を定義します。
31        // このスクリプトはPharアーカイブが実行されたときに呼び出されます。
32        $scriptContent = <<<'PHP_SCRIPT'
33<?php
34// このスクリプトはPharアーカイブ内で実行されます。
35// Phar::mungServerによって$_SERVER変数がどのように変更されたかを確認します。
36
37echo "--- $_SERVER variables inside Phar archive ---\n";
38
39// mungServerで設定されたカスタム変数の値を確認
40echo "MY_CUSTOM_VAR: " . ($_SERVER['MY_CUSTOM_VAR'] ?? 'Not set (default)') . "\n";
41
42// mungServerで上書きされた可能性がある既存の$_SERVER変数の値を確認
43echo "REQUEST_METHOD: " . ($_SERVER['REQUEST_METHOD'] ?? 'Not set (default)') . "\n";
44
45// mungServerで設定されたが、PHPの実行環境では元々存在しないキーの値を確認
46echo "CUSTOM_INJECTED_KEY: " . ($_SERVER['CUSTOM_INJECTED_KEY'] ?? 'Not set (default)') . "\n";
47
48// 通常の$_SERVER変数(mungServerで変更されていない)の例
49echo "SCRIPT_NAME: " . ($_SERVER['SCRIPT_NAME'] ?? 'Not set (default)') . "\n";
50PHP_SCRIPT;
51
52        // 3. 定義したスクリプトの内容をアーカイブに追加します。
53        $phar->addFromString($filePathInPhar, $scriptContent);
54
55        // 4. Phar::mungServer を使用して、Pharアーカイブ実行時に`$_SERVER`変数に適用する値を定義します。
56        // ここで指定されたキーと値は、アーカイブ内のスクリプトが実行される直前に`$_SERVER`に設定されます。
57        // 既存のキーは上書きされ、新しいキーは追加されます。
58        $serverVariablesToMung = [
59            'MY_CUSTOM_VAR'       => 'Value injected by mungServer!', // 新しいカスタム変数を追加
60            'REQUEST_METHOD'      => 'CLI-MUNGED',                   // 既存の変数を上書き
61            'CUSTOM_INJECTED_KEY' => 'Another custom value',         // 事前に存在しない新しいキーを追加
62        ];
63        $phar->mungServer($serverVariablesToMung);
64
65        // 5. Pharアーカイブのエントリポイント(スタブ)を設定します。
66        // これはPharファイルを直接実行したときに最初に実行されるスクリプトを指定します。
67        $phar->setStub($phar->createDefaultStub($filePathInPhar));
68
69        // 6. Pharアーカイブへの変更を保存し、クローズします。
70        $phar->stopBuffering();
71
72        echo "Phar archive '{$pharFileName}' has been created successfully.\n";
73        echo "You can execute it directly from the command line: php {$pharFileName}\n";
74
75        // 作成されたPharアーカイブを直接実行し、`mungServer`の効果を示します。
76        echo "\n--- Executing the created Phar archive ---\n";
77        // system()関数を使ってコマンドラインからPharファイルをPHPで実行します。
78        // escapeshellarg()はシェルインジェクションを防ぐためにファイル名を適切にエスケープします。
79        system("php " . escapeshellarg($pharFileName));
80
81    } catch (PharException $e) {
82        echo "Error creating Phar archive: " . $e->getMessage() . "\n";
83        // エラーが発生した場合、不完全なPharファイルを削除することを試みます。
84        if (file_exists($pharFileName)) {
85            Phar::unlinkArchive($pharFileName);
86        }
87    } catch (Exception $e) {
88        // Phar関連以外の予期せぬエラーを捕捉します。
89        echo "An unexpected error occurred: " . $e->getMessage() . "\n";
90    } finally {
91        // スクリプトの終了時に作成されたPharファイルをクリーンアップするよう登録します。
92        // これにより、サンプルコード実行後に不要なファイルが残りません。
93        register_shutdown_function(function() use ($pharFileName) {
94            if (file_exists($pharFileName)) {
95                unlink($pharFileName);
96                echo "\nCleaned up '{$pharFileName}'.\n";
97            }
98        });
99    }
100}
101
102// 上記の関数を実行してデモンストレーションを開始します。
103demonstratePharMungServer();

PHPのPhar::mungServerメソッドは、Phar(PHPアーカイブ)ファイルが実行された際に、アーカイブ内部のスクリプトから参照できる$_SERVERスーパーグローバル変数の値を制御するために使用されます。このメソッドは、array $variablesという連想配列を引数として受け取ります。この配列のキーは$_SERVER変数のキーに対応し、その値が$_SERVER変数に設定される値となります。

具体的には、引数で指定された配列のキーが$_SERVER変数にすでに存在する場合、その既存の値は引数の値で上書きされます。存在しないキーを指定した場合は、新しいキーとその値が$_SERVER変数に追加されます。これにより、Pharアーカイブを特定の環境や設定で実行されているかのように振る舞わせることが可能になります。メソッドの戻り値はvoidであり、操作後に何も返しません。

サンプルコードでは、mungServerメソッドを使ってMY_CUSTOM_VARのようなカスタム変数を追加したり、REQUEST_METHODのような既存の変数をCLI-MUNGEDという値で上書きしたりするPharアーカイブを作成しています。その後、作成したPharを実行することで、アーカイブ内部のスクリプトが、mungServerで設定された$_SERVER変数の値を受け取っていることを具体的に示しています。

Phar::mungServerは、Pharアーカイブ内で実行されるスクリプトの$_SERVER変数を、指定した値で上書きしたり、新しいキーを追加したりする機能です。この機能を利用する上で最も注意すべき点は、サンプルコード冒頭のini_set('phar.readonly', 0)です。この設定はPharファイルを書き込み可能にするため、開発やビルド時のみに限定し、本番環境ではPharファイルの改ざんを防ぐために必ずデフォルトの1を維持してください。mungServerによる$_SERVER変数の変更は、Pharアーカイブ内部のスクリプトにのみ適用され、外部のPHP実行環境には影響しません。これは主にPharアプリケーションの実行環境を制御するための機能であり、一般的なウェブ開発で直接利用する機会は少ないことをご理解ください。

関連コンテンツ

関連IT用語

関連プログラミング言語