《PHP8上級試験対策》__halt_compiler() と COMPILER_HALT_OFFSET の挙動を理解する

  • URLをコピーしました!

はじめに

PHP8上級試験の問題集を進めていると、Phar アーカイブや __halt_compiler() に関する問題が出てきます。普段の開発ではなかなか触れる機会が少ないため「何をしているの?」と混乱しやすいポイントです。

この記事では、試験に登場する次のコード例をベースに、__halt_compiler()__COMPILER_HALT_OFFSET__ の動きを整理します。

キーワード: __halt_compiler() / COMPILER_HALT_OFFSET / Phar / データ埋め込み / PHP8上級試験

目次

サンプルコード

<?php
declare(strict_types=1); 
error_reporting(-1);

var_dump(__COMPILER_HALT_OFFSET__);
$data = file_get_contents(filename:__FILE__, offset:__COMPILER_HALT_OFFSET__);
var_dump($data);

__halt_compiler();
set data;
write data i ACED.

実行結果

int(205)
string(29) 
" set data; 
write data i ACED."

解説

__halt_compiler()

  • PHP の コンパイル処理をそこで終了 させる特殊関数です。
  • この行以降に書いたテキストは「PHPコード」ではなく「生データ」としてファイルに保存されます。
  • exitdie のように「実行を止める」わけではなく、「これ以上コードをコンパイルしない」 という動作をするのがポイントです。

COMPILER_HALT_OFFSET

  • __halt_compiler() が登場した位置(=ファイル内のバイトオフセット値)を保持する定数です。
  • これを利用すると「ファイルのどこからがデータ領域なのか」を知ることができます。

今回の例では 205 という値が返ってきています。つまり、ファイルの 205 バイト目以降は 任意データ領域 です。

file_get_contents(FILE, offset: COMPILER_HALT_OFFSET)

  • 実行中のファイル (__FILE__) を読み込みます。
  • offset を指定することで「205バイト目以降(__halt_compiler の直後)」だけを取得しています。
  • そのため、出力は set data; write data i ACED. という埋め込んだ文字列になるわけです。

まとめ

  • __halt_compiler() … コンパイルを中止して、以降を「データ領域」とする。
  • __COMPILER_HALT_OFFSET__ … そのデータ領域の開始位置(バイトオフセット)。
  • file_get_contents(__FILE__, offset: …) で自分自身のファイルを読み込むと、埋め込みデータを取り出せる

この仕組みは Phar アーカイブの「起動スタブ」に必須で、試験でもよく問われるポイントです。
普段の開発では触れなくても、理解しておくと「PHP がどうやって Phar を扱っているのか」が見えてきます。

この記事が気に入ったら
いいねしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次