Skip to content

Instantly share code, notes, and snippets.

@pronskiy
Created May 26, 2026 04:40
Show Gist options
  • Select an option

  • Save pronskiy/cfddaa3bf0d12f985b1fe19b21ad841f to your computer and use it in GitHub Desktop.

Select an option

Save pronskiy/cfddaa3bf0d12f985b1fe19b21ad841f to your computer and use it in GitHub Desktop.
type idea
title PHPコアにdd()関数を追加する — var_dump() + exit()のショートカット
slug idea-add-dd-function
php_src_ref c4105b6243e8c0ae6882e847414df5930ac45ac7
status in-progress

PHPコアに dd() 関数を追加する

Context

status: done

1. 仮説の再定義

PHPには複数のデバッグ出力関数(var_dump()print_r()var_export())があるが、「変数を出力して即座に実行を停止する」というデバッグ時の最頻出パターンに対応する組み込み関数がない。dd()(dump and die)をPHPコアの組み込み関数として提供することで、フレームワーク非依存のデバッグ体験を改善し、すべてのPHP開発者が追加の依存なしに利用できるようにする。

2. 誰が恩恵を受けるか

  • フレームワーク非使用の開発者: Laravel・Symfonyのdd()にアクセスできないPHP開発者。素のPHPスクリプトやレガシーアプリケーションの保守者
  • PHP初学者: デバッグ手法の学習曲線を下げる。var_dump($x); exit;の2行パターンを1行で書ける
  • CLI/スクリプト開発者: ワンショットスクリプトやバッチ処理のデバッグ時に即座に値を確認して停止したい場面が多い
  • すべてのPHP開発者: IDEやエディタのスニペットに頼らず、言語レベルで統一されたデバッグプリミティブを持てる

3. 誰が反対するか

  • internals保守的派: 「ユーザーランドで簡単に実装できるものをコアに追加する意味がない」という立場。PHPコアの肥大化を懸念する層
  • フレームワーク開発者: LaravelやSymfonyは独自の高機能なdd()を提供しており、コアの簡素なdd()との名前衝突・動作差異が混乱を招く可能性を指摘する層(特にLaravelのdd()symfony/var-dumperベースで色付き出力やHTML出力を行う)
  • 言語設計純粋主義者: デバッグ専用関数はxdebugやphpdbgなど専用ツールの仕事であり、言語コアの責務ではないという立場
  • 名前空間を重視する層: グローバル名前空間に短い名前の関数を追加することへの反対。既存のユーザーランドdd()関数との衝突リスクを指摘

4. 現在のユーザーランドの状況

フレームワークやライブラリが独自にdd()を提供しており、事実上のデファクトスタンダードとなっている:

Laravel(Illuminate\Support\helpers.php):

function dd(...$vars): never
{
    if (!in_array(\PHP_SAPI, ['cli', 'phpdbg'], true)) {
        header('HTTP/1.1 500 Internal Server Error');
    }
    foreach ($vars as $v) {
        VarDumper::dump($v);
    }
    exit(1);
}

ソース: https://github.com/laravel/framework/blob/master/src/Illuminate/Support/helpers.php

Symfony(symfony/var-dumper):

function dd(mixed ...$vars): never
{
    // ...
    foreach ($vars as $v) {
        VarDumper::dump($v);
    }
    exit(1);
}

ソース: https://github.com/symfony/var-dumperdd()はcomposerのautoload.filesで自動ロードされる

WordPress(デバッグプラグイン各種): Kintプラグインなどがdd()相当の機能を提供

素のPHPでの一般的パターン(ユーザーランドワークアラウンド):

var_dump($variable); exit;
var_dump($variable); die;
echo "<pre>"; var_dump($variable); echo "</pre>"; exit;

5. 他言語の類似機能

言語 機能 説明
Ruby Kernel#p + abort pはオブジェクトの.inspectを出力。dd相当は標準ライブラリにないが、pの手軽さが同様のDX改善を実現。Railsではbinding.pryがデバッグの主流
Rust dbg!() マクロ Rust 1.32で標準ライブラリに追加。式の値をstderrに出力し、値をそのまま返す。プロセスは停止しない。ソース: https://doc.rust-lang.org/std/macro.dbg.html
Elixir IO.inspect/2 + dbg/2 Elixir 1.14でdbg/2マクロが追加。パイプライン中に挟んでデバッグ出力できる。プロセスは停止しない。ソース: https://hexdocs.pm/elixir/Kernel.html#dbg/2

注目すべき点: 主要言語の多くは「ダンプして停止」ではなく「ダンプして続行」のデバッグプリミティブを採用している。dd()(die付き)をコアに入れる言語は他にない。これはRFCのフレーミングに影響する。

6. 賛否

賛成(Pro) 反対(Con)
PHPで最も一般的なデバッグパターンを1関数にまとめる。フレームワーク非依存 ユーザーランドで2行(var_dump(); exit;)で実現可能。コアに追加する必要性が低い
LaravelやSymfonyでdd()は既にデファクトスタンダード。PHP開発者の期待に合致 Laravel/Symfonyのdd()はリッチな出力(色、折りたたみ、HTML)を提供。コアの素朴なdd()は「劣化版」と見なされる可能性
PHP初学者の学習曲線を下げる。「デバッグどうやるの?」→ dd($x) グローバル名前空間に短い名前を追加すると、既存のdd()定義と衝突する(function_existsガードなしの場合fatal error)
Rustのdbg!()、Elixirのdbg/2のように、モダン言語はコアにデバッグプリミティブを持つ流れがある exit()を含むデバッグ関数は本番コードに残りやすく、危険。xdebgやphpdbgの使用を阻害する
実装コストが非常に低い(var_dump() + exit()のラッパー) 実装コストが低いということは、コアに追加する理由も弱いということ

7. 関連サブシステム

  • ext/standard/var.c: var_dump()var_export()debug_zval_dump()の実装場所。dd()も同ファイルに追加するのが自然
  • ext/standard/basic_functions.stub.php: PHP関数のスタブ定義。dd()のシグネチャをここに追加
  • ext/standard/basic_functions_arginfo.h: build/gen_stub.phpから自動生成されるarginfo。スタブファイルから再生成
  • Zend/zend_builtin_functions.c: exit()/die()の実装場所。dd()からexitを呼ぶ際にこの機構(zend_throw_unwind_exit())を利用

8. このプロトタイプのスコープ外

  • INIディレクティブによる出力のカスタマイズ(深さ制限、文字列切り詰め、色付けなど)
  • HTTP SAPI用のレスポンスヘッダ設定(500ステータスコードなど)
  • HTMLの<pre>タグ自動付与
  • dump()(exit無し版)の同時追加
  • RFC本文のドラフト
  • フレームワークのdd()との互換性レイヤー
  • 出力先のカスタマイズ(stderr vs stdout)

Hypothesis & Metric

status: done

metric

PHPコアにdd()関数を追加した場合、以下のすべてを満たすことで成功とする(反証可能な判定基準):

  1. 動作の正確性: dd($x)var_dump($x); exit(0);とバイト単位で同一の標準出力を生成し、同じ終了コード(0)でプロセスを終了する。これを3つの.phptテストケースで検証する:

    • スカラー値(int、string、bool、null)
    • 複合型(配列、ネストされた配列)
    • 複数引数(dd($a, $b, $c)
  2. 既存のdd()定義との共存: ユーザーランドでfunction dd() {}が定義済みの場合、PHPが明確なfatal errorを出すこと(暗黙の上書きやサイレントな無視ではない)。これは既存のPHP動作(組み込み関数と同名のユーザー関数定義はfatal error)に準拠するが、明示的に確認する。

  3. ビルドの健全性: make -j$(nproc)がゼロ新規コンパイラ警告で完了する。

反証条件: 上記3項目のうちいずれか1つでも失敗した場合、メトリクスは未達成とする。

workload

以下の3つのPHPスクリプトをプロトタイプビルドのsapi/cli/phpで実行する:

テスト1: 基本的なスカラー値のダンプ

<?php
dd(42, "hello", true, null);

期待出力: var_dump(42, "hello", true, null)と同一の出力後、終了コード0で停止。

テスト2: 複合型のダンプ

<?php
dd(["a" => 1, "b" => [2, 3]]);

期待出力: var_dump(["a" => 1, "b" => [2, 3]])と同一の出力後、終了コード0で停止。

テスト3: dd()後のコードが実行されないことの確認

<?php
dd("stop here");
echo "THIS SHOULD NOT APPEAR";

期待出力: var_dump("stop here")の出力のみ。"THIS SHOULD NOT APPEAR"は出力されない。終了コード0。

PHPバージョン: 現在のmasterブランチ(c4105b6243e)をベースにビルド。

Research

status: done

Guardrails

  • pre: Hypothesis & Metricフェーズ完了済み
  • post: 4つのソースのうち3つが実行完了(gh-prsは0件)

Steps

  • keywordsdd, dump die, var_dump exit, dd function, dump and die, Pre-RFC dd dump

  • algolia-internals — 3件の関連ヒット(複数クエリの合計)

    1. 「Pre-RFC: dd() and dump() functions for PHP core」 — Larry Garfield, 2025-06-17 — https://externals.io/message/127699直接関連: 2025年6月にBraunson Yagerが提案した、まさに今回と同じdd()+dump()をPHPコアに追加する提案。強い反対を受けてRFCに至らず
    2. 「Pre-RFC: dd() and dump() functions for PHP core」(Grekas返信) — Nicolas Grekas, 2025-06-19 — https://externals.io/message/127719直接関連: Symfony VarDumperの作者による詳細な反対意見。名前衝突、イノベーション凍結、パフォーマンス主張の棄却、ユーザーランドの十分性を指摘
    3. 「Pre-RFC: dd() and dump() functions for PHP core」(Vollebregt返信) — Jonathan Vollebregt, 2025-06-17 — https://externals.io/message/127701直接関連: 名前衝突の意図的発生を批判。PHPコアには既にprint_rvar_dumpdebug_zval_dumpvar_exportの4つのダンプ関数があると指摘
    4. 「New function proposal」 — Korvin Szanto, 2015-10-10 — https://externals.io/message/88733直接関連: 2015年にMattias Gonzalezがvar_die($var)を提案。Johannes Schlüterが「ユーザーランドで簡単に実装でき、パフォーマンスの利点もない。コアに追加する理由がない」と却下
  • gh-issues — 0件の直接関連ヒット

    GitHub issueの検索ではdd()関数の追加に直接関連するissueは見つからなかった。議論はすべてinternals MLで行われている。

  • gh-prs — 0件

    dd()dump()の追加に関するPRは提出されていない。Pre-RFCの段階で議論が終了しているため、実装に至っていない。

  • git-log — 0件の直接関連コミット

    dd()関数の追加に関するコミットは存在しない。var_dumpdebug_zval_dumpに関する多数のコミットが存在するが、dd()の実装を試みたものはない。

Notes

この提案は過去に2回(2015年、2025年)internals@で議論され、いずれも強い反対を受けてRFCに至っていない。 主な反対論点は一貫している: (1) ユーザーランドで2行で実装可能でコアに追加する理由がない(Schlüter 2015, Tekiela 2025)、(2) dd/dumpという名前はLaravel/Symfonyで広く使われており意図的な名前衝突になる(Vollebregt, Grekas 2025)、(3) ユーザーランド実装の方がイノベーションの自由度が高い(Grekas 2025)、(4) var_dumpに加えて5つ目のダンプ関数は冗長(Vollebregt 2025)。特にNicolas Grekas(Symfony VarDumperの作者)の反対は技術的に詳細で、拡張性(casters API)の喪失やパフォーマンス主張の無意味さを指摘している。プロトタイプのVerdictでは、これらの反対論点に対して技術的証拠で応答できるものとできないものを明確に区別する必要がある。

Survey & Plan

status: done

subsystem-map

最小限のプロトタイプに必要な変更ファイル一覧:

  1. ext/standard/basic_functions.stub.phpdd()のPHPスタブ定義を追加(シグネチャ: function dd(mixed $value, mixed ...$values): never {})。var_dump()定義の直後(3794行付近)に配置
  2. ext/standard/basic_functions_arginfo.hbuild/gen_stub.phpで再生成。dd用のarginfo定義とZEND_FE(dd, ...)エントリが自動追加される
  3. ext/standard/var.cPHP_FUNCTION(dd)の実装を追加。PHP_FUNCTION(var_dump)(242行)の直後に配置。内容はvar_dumpのコードをコピーし、末尾にzend_throw_unwind_exit()を追加するだけ

Per Researchの発見: 2025年のPre-RFCで議論されたのはリッチな出力を持つdd()だったが、本プロトタイプはvar_dumpとバイト同一の出力に限定する。Grekas(externals.io/message/127719)が指摘した「パフォーマンスの利点はない」という点については、プロトタイプはパフォーマンスを主張しないため直接の反論は不要。

design-space

次元 プロトタイプの選択 RFCで議論すべき選択肢
関数名 dd debug_dump, dump_die, var_dump_exit, 名前空間付き\Debug\dd
終了コード 0(exit()デフォルトに合致) 1(Laravel/Symfony互換)、設定可能
出力フォーマット var_dump()とバイト同一 色付き出力、構造化出力、深さ制限、文字列切り詰め
INI設定 なし dd.depth_limit, dd.string_truncation, dd.colorize
SAPI動作 全SAPI統一(CLIと同じ出力) HTTP 500レスポンスヘッダ、<pre>タグ自動付与
戻り値型 never(プロセス停止するため) never一択(設計上変更の余地なし)
dump()(exit無し版)同時追加 しない RFCでdump()を同時提案するか議論

counter-position-binding

反対論点 発言者 プロトタイプ証拠で対応可能か 対応する証拠
ユーザーランドで2行で実装可能、コア追加不要 Schlüter (2015), Tekiela (2025) no これは「必要性」の哲学的議論であり、技術的証拠では覆せない。RFC本文で「利便性の正当化」を別途論じる必要がある
dd名はLaravel/Symfonyと衝突する Vollebregt, Grekas (2025) partially プロトタイプで既存のfunction dd()定義時のfatal errorを確認できる(PHPの標準動作)。ただし衝突が「望ましくない」かは政治的判断
ユーザーランドの方がイノベーション自由度が高い Grekas (2025) no コアのdd()が素朴であることは設計判断。リッチなDumperを阻害しないことは論じられるが、プロトタイプでは証明不可
5つ目のダンプ関数は冗長 Vollebregt (2025) partially dd()は既存ダンプ関数と異なりnever戻り値型でプロセスを停止する。機能的に新しい組み合わせであることをシグネチャで示せる
コアの素朴なdd()は「劣化版」と見なされる (Context Con #2) yes プロトタイプがvar_dumpと同一出力であることを明示し、「最小限のコアプリミティブ」という位置づけを証拠で示す。フレームワークのリッチ版と競合する意図がないことを実装で裏付ける
exit()含むデバッグ関数は本番に残りやすい (Context Con #4) no 静的解析ツールやCI linterの領域。プロトタイプで対応不可

plan-1: スタブファイルにdd()シグネチャを追加

ファイル: ext/standard/basic_functions.stub.php(3794行のvar_dump定義の後)

追加内容:

/** @return never */
function dd(mixed $value, mixed ...$values): never {}

plan-2: arginfo再生成

コマンド: php build/gen_stub.php ext/standard/basic_functions.stub.php

これによりext/standard/basic_functions_arginfo.hに以下が自動追加される:

  • arginfo_dd定義(IS_NEVER戻り値型付き)
  • ZEND_FUNCTION(dd);宣言
  • ZEND_FE(dd, arginfo_dd)エントリ

plan-3: PHP_FUNCTION(dd)の実装

ファイル: ext/standard/var.c(255行、PHP_FUNCTION(var_dump)}の直後)

実装内容:

PHP_FUNCTION(dd)
{
	zval *args;
	int argc;
	int	i;

	ZEND_PARSE_PARAMETERS_START(1, -1)
		Z_PARAM_VARIADIC('+', args, argc)
	ZEND_PARSE_PARAMETERS_END();

	for (i = 0; i < argc; i++) {
		php_var_dump(&args[i], 1);
	}

	zend_throw_unwind_exit();
	RETURN_THROWS();
}

plan-4: ビルド確認

コマンド: make -j$(nproc) — 成功で完了

Prototype

status: todo

(Survey & Plan完了後に記入)

Measurement & Verdict

status: todo

(Prototype完了後に記入)


Progress Log

  • 2026-05-26 — idea-prototype — Contextフェーズ完了。仮説を再定義し、8つの必須セクションすべてを記入。
  • 2026-05-26 — idea-prototype — Hypothesis & Metricフェーズ完了。DX型メトリクスを定義:動作の正確性(3つの.phptケース)、既存定義との共存、ビルド健全性。
  • 2026-05-26 — research — Researchフェーズ完了。4ソース中3ソース実行。重要発見: 2015年と2025年に同じ提案がinternals@で議論され、いずれも強い反対で却下。Grekas(VarDumper作者)の詳細な技術的反対が最大の障壁。
  • 2026-05-26 — idea-prototype — Survey & Planフェーズ完了。最小プロトタイプ: 3ファイル変更(stub, arginfo, var.c)。design-space 7次元、counter-position-binding 6反対論点をマッピング。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment