対応機能とその制限一覧
← コンバーターへ戻るこのページは、The Spaghetti Dream が 入力コードとして受け付ける PHP 機能の現在の対応状況を説明しています。
対応している機能は SPAGHETTI_SPEC.md で定義された goto ベースのコードに変換されます。
例えば ?? や ?: 演算子は入力として対応していますが、出力では goto 文に変換されます。
生成コードに対しては専用の PHPStan ルールセットが用意されており、禁止された構文(構造的制御フロー・OOP 等)が使われていないかを静的解析で検証できます。 → phpstan-spaghetti: Rules 一覧
new ClassName() によるオブジェクト生成が動作します。各インスタンスは独立したIDを保持します。
動的インスタンス化(new $variable())も対応しており、spaghetti 変換済みクラスの場合は配列として生成され、組み込みクラスの場合は __builtin_new() が呼び出されます。
new class { ... } 構文が対応しています。プロパティのデフォルト値やメソッド呼び出しが動作します。
1ファイル内に複数の匿名クラスも対応しています。
__construct)__destruct)readonly、final 修飾子は未対応です。get =>)get => 短縮フック構文(計算プロパティ)に対応しています。phpdbg はフックを別メソッドとして出力しないため、PhpParser で AST を解析し、FETCH_OBJ_R の呼び出し箇所にインライン展開します。
get => 短縮フック(式で定義された読み取り専用計算プロパティ)set => フック、ブロック形式のフック(get { return ...; })
$obj->prop += 5、$obj->prop .= 'x'、++$obj->prop などが動作します。
$this$this も正しく参照できます。
===)==)== 演算子は内部的に配列比較になるため、__id フィールドの差異により本来 true になるべきケースで false が返ることがあります。
static プロパティとメソッドが動作します。静的プロパティはグローバルな $_static 配列に格納されます。
get_called_class()false を返します(PHP の動作に一致)。
class_exists() / method_exists()$_spaghetti_classes テーブルを使ってルックアップします。
DateTime、Exception など)は認識されず、false が返ります。ClassName::CONSTANT が動作します。parent::CONST、static::CONST、動的クラス参照も対応しています。
parent:: 呼び出し、プロパティデフォルト値の継承が動作します。
abstract、final 修飾子は実行時に強制されません。use 文によるトレイトの利用、メソッドの継承と解決が動作します。複数トレイトの合成も対応しています。
insteadof、as)は未テスト・未対応です。instanceof チェックのみ)implements による実装追跡と instanceof チェックが動作します。
__construct 以外)__invoke: SUPPORTED — $obj($args) 構文による呼び出しが動作します。__toString: SUPPORTED — echo、文字列連結などの文字列コンテキストで自動的に呼び出されます。__get、__set、__call など): NOT SUPPORTED
cloneclone $obj が完全に対応しています。ユーザー定義オブジェクトは配列がコピーされ新しい __id が付与されます。組み込みオブジェクトは __builtin_clone() で処理されます。
DateTime、DateTimeImmutable、stdClass、ArrayObject などのネイティブ PHP クラスのインスタンス化とメソッド呼び出しが動作します。内部的には FFI ID によって管理されます。
stdClass)では動作します。
DateTime::createFromFormat() などの静的メソッド呼び出しが動作します。
date_create() などの返り値が自動的に FFI ID でラップされます。
date_format()、date_diff() などの引数として渡す際に FFI ID が自動的にアンラップされます。
Exception、DateTime、ArrayObject など任意の組み込みクラスを継承することができます。継承したクラスは __builtin_define_class() を通じて実行時に eval() で定義されます。
_ffi_is_ffi_id() を使ったランタイムディスパッチが自動的に生成されます。
&$param)も対応しています。
$_objects にオブジェクトとして事前割り当てされ、$_class_const['EnumName']['CaseName'] でそのIDを参照します。
enum Status { case Active; }enum Suit: string { case Hearts = 'H'; }->name(ケース名)、->value(Backed Enum のバッキング値)=== / !== による同一性比較EnumName::CaseName によるケースアクセスEnumName::cases()(宣言順に全ケースの配列を返す)::from($value)(バッキング値でケース取得。未一致は trigger_error)::tryFrom($value)(バッキング値でケース取得。未一致は null)match($this) パターンを含む)implements、instanceof チェック対応)match 式との組み合わせ::from() の未一致エラーは \ValueError としてキャッチ不可(trigger_error による致命的エラー)
yield)yield をサポートします。各 yield 地点でローカル変数をスナップショット保存し、goto で再開するアプローチです。ジェネレータメソッド(インスタンスメソッド内の yield)も対応し、$this の保存・復元も行います。
yield $value / yield $key => $value(明示的なキーも対応)$gen->current() / $gen->next() / $gen->valid()$gen->send($value)(ジェネレータへの値送信)foreach ($gen as $key => $value)(foreach によるイテレーション)$obj->gen()、foreach ($obj->gen() as $v))yield from(変換時に ConversionException)
function($x) use ($y) {...})とアロー関数(fn($x) => ...)が完全に対応しています。値キャプチャ・参照キャプチャ・$this バインディングも動作します。
call_user_func / call_user_func_array[$obj, 'method'] 形式のオブジェクトメソッド配列が対応しています。
'Class::method' 形式の静的メソッド文字列は対応していません。...$args)...$args 形式の可変長引数が完全に対応しています。スプレッド演算子(呼び出し側での ...$array)も動作します。
include / require / include_once / require_once(静的パスのみ)_once 系の重複排除も対応しています。
include $file)は対応していません。式としての戻り値($x = include 'file.php')も対応していません。
if 文(goto に変換)else / elseif・for / while / foreach ループgoto とラベルmatch 式match 式が完全に対応しています。各アームは厳密等価チェックと条件付き goto に変換されます。
// 入力
$result = match($n) {
1 => 'one',
2, 3 => 'two or three',
default => 'other',
};
// 生成コード
$_cond = ($n === 1);
if ($_cond) goto main_0003;
$_cond = ($n === 2);
if ($_cond) goto main_0005;
$_cond = ($n === 3);
if ($_cond) goto main_0005;
goto main_0007; // default
match(true) に複雑な条件(例: $x < 5)を使う場合は MATCH オペコードを生成しません。PHP が IS_IDENTICAL + JMPNZ チェーンにコンパイルするため、すでに対応しています。
+、-、*、/、%、==、===、&&、||、!、. などが動作します(オブジェクト等値比較の制限については前述を参照)。
? :(ネスト含む)と ?:(Elvis)が goto ベースの条件分岐に変換されます。
@)@ 演算子が対応しています。BEGIN_SILENCE でエラー報告を無効化し、END_SILENCE で復元します。
instanceof 演算子...)func(...$args))が完全に対応しています。
??)・Null 合体代入(??=)?? と ??= が完全に対応しており、goto ベースのコードに変換されます。
?->)?-> が対応しています。オブジェクトが null の場合に呼び出しチェーンをショートサーキットします。
isset() / empty()array_push、array_pop、count、array_key_exists、in_array などの組み込み関数も対応しています。
[$a, $b] = $array)list() 関数と短縮記法 [] の両方が対応しています。連想配列のデストラクチャリングも動作します。
. 演算子と組み込み文字列関数が動作します。
"Hello $name"){$arr['key']})やオブジェクトプロパティ({$obj->name})の補間も動作します。
+=、-=、*=、/=、.=、%= などの複合代入演算子がすべて対応しています。
++$i、--$i)と後置($i++、$i--)の両方が式中でも対応しています。
&$var)$b = &$a)と参照渡し(function foo(&$param))が対応しています。
unset()global・$GLOBALS)global 文と $GLOBALS 配列の両方が完全に対応しています。グローバル変数は $_globals 配列に格納されます。
(int)、(string)、(array) などのキャストが動作します。
is_string()、is_int()、is_null()、is_array()、is_float()、is_bool()、is_object()、is_resource() が対応しています。
declare(strict_types=1)namespace・use)\ が __NS__ に置換されます。
const・define())const)と実行時定数(define())の両方が対応しています。定数はグローバルな $_const 配列に格納されます。
#[Attribute])throw 文Exception などを継承したユーザー定義例外クラスが完全に対応しています。実行時に __builtin_define_class() で定義されます。
FAST_CALL/FAST_RET オペコードを goto ベースのサブルーチン呼び出しとして実装。finally ブロック実行後の戻り先をリターンラベル配列で管理し、ディスパッチャが元の処理に戻します。try-catch-finally・try-finally(catch なし)・例外伝播・ネストした finally に対応しています。
set_error_handler にクロージャを渡す