Skip to content

Commit 8604526

Browse files
Merge pull request #30 from php-debugger/stop-using-dd
add the stop using dd guide page
2 parents d7d8fb3 + d14694a commit 8604526

2 files changed

Lines changed: 132 additions & 0 deletions

File tree

‎docs/user-guide/stop-using-dd.md‎

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
---
2+
title: Stop using dd()
3+
---
4+
5+
Most PHP developers debug by printing. A `dd()` here, a `var_dump()` and `die` there,
6+
run it again, read the output, move the call somewhere else, run it again. Whole
7+
careers have been built on it, and it works often enough to feel like a method
8+
rather than a habit.
9+
10+
It is worth asking why it became the default, because the reasons were real — and
11+
because most of them no longer hold.
12+
13+
## Why it made sense
14+
15+
For a long time, a step debugger for PHP was something you set up once, fought with,
16+
and gave up on.
17+
18+
It was **hard to install**: a separate extension to get in place, and an editor to
19+
configure to match it.
20+
21+
It was **slow**: loading it made every request noticeably worse, so it was something
22+
you enabled to hunt one bug and disabled immediately afterwards.
23+
24+
It was **not there when you needed it**. Because it was slow, it stayed off. Because
25+
it stayed off, hitting a bug meant stopping, turning it on, restarting things, and
26+
trying to reproduce what you had just seen. By then, printing a variable and
27+
re-running had already answered the question.
28+
29+
Against that, `dd()` was the rational choice. It needed nothing, cost nothing when
30+
absent, and was always available.
31+
32+
## What changed
33+
34+
All three of those reasons are gone.
35+
36+
**The setup is one command.** The [installer](../getting-started/installation.mdx)
37+
works out what you are running and puts the right build in place. There are
38+
[prebuilt Docker images](../getting-started/docker.mdx) if you would rather not
39+
install anything at all.
40+
41+
**It is fast.** With no editor connected the cost is close to nothing — the debugger
42+
tries once, finds no one listening, and gets out of the way. This is the whole point
43+
of the project.
44+
45+
**It is always available.** Because it costs almost nothing, there is no reason to
46+
turn it off. Every request can be debugged, so the moment you want to look at
47+
something you already can — no restart, no configuration change, no reproducing the
48+
bug a second time.
49+
50+
The debugger being off when you needed it was what made printing worth it. That is
51+
no longer true.
52+
53+
## What printing cannot do
54+
55+
Some of this is impossible with `dd()`. The rest is possible but so tedious that
56+
nobody does it.
57+
58+
**See everything in scope, not just what you guessed.** `dd($order)` shows you
59+
`$order`. If the problem turns out to be `$discount`, that is another edit and
60+
another run. [The variables panel](./inspect-variables.md) shows all of it at once,
61+
including private and protected properties, without a single guess.
62+
63+
**Look at the caller.** When a function chokes on what it was handed, the useful
64+
question is what the caller passed and where it came from. A debugger lets you
65+
[step up the call stack](./inspect-variables.md#stack-levels) and read the caller's
66+
variables at the moment it made the call. With printing you have to go and edit the
67+
caller too.
68+
69+
**Carry on afterwards.** `dd()` kills the request — that is the second `d`. You see
70+
one moment and lose everything after it: the rest of the function, the response,
71+
the shutdown, the commit. A breakpoint pauses; you look, and then you
72+
[keep going](./step-debugging.md).
73+
74+
**Watch a value change.** Printing gives you one snapshot per edit-and-run cycle. To
75+
see how a value evolves you add a dump per line, or a dump in a loop and then scroll
76+
through a thousand of them. Stepping shows you the change as it happens, and a
77+
[watch expression](./watches-and-edits.md) keeps the value in front of you at every
78+
stop.
79+
80+
**Stop on the iteration that matters.** A dump inside a loop gives you every
81+
iteration. A [conditional breakpoint](./breakpoints.md#conditions) gives you the one
82+
where `$i > 1000 && $found === null` — the case you actually care about, with
83+
everything else running at full speed.
84+
85+
**Catch a throw where it happens.** An
86+
[exception breakpoint](./breakpoints.md#exception-breakpoints) stops at the line
87+
that threw, before any `catch` runs, with the stack as it was. Printing gets you
88+
whatever the handler chose to log, from wherever it eventually ended up.
89+
90+
**Change something and see what happens.** Force a retry path, hand an error handler
91+
a malformed response, push a value over a threshold —
92+
[edit the value in place](./watches-and-edits.md#editing-values) and carry on,
93+
rather than contriving the input or editing the code to fake it.
94+
95+
**Debug what you cannot see.** A dump only helps if you can read the output. An API
96+
request, a queue worker, a webhook, a redirect, an AJAX call that a browser swallows
97+
— all of them are ordinary debugging sessions, and none of them show you a
98+
`var_dump()`.
99+
100+
**Leave no trace.** Every `dd()` is an edit to your code, which means one can be
101+
committed, and eventually one is. Breakpoints live in your editor and cannot ship.
102+
103+
## When it is still fine
104+
105+
None of this makes printing wrong.
106+
107+
If you want to know whether a line is reached, or what one variable holds at one
108+
point, and the answer ends the matter — print it. Starting a session to answer a
109+
question that a single `var_dump()` settles in five seconds is not a better
110+
workflow, it is a worse one.
111+
112+
The line is roughly this: printing suits a question you already know the shape of.
113+
The moment you find yourself moving the call around, adding a second one, or running
114+
it a third time to see what changed, you have stopped answering a question and
115+
started searching. That is what the debugger is for, and it will be faster from the
116+
second run onwards.
117+
118+
## Worth reconsidering
119+
120+
If printing is your whole workflow, it is likely because of how debuggers used to
121+
be, not because of a comparison you have made recently. That is a reasonable way to
122+
have ended up here — the tools really were not good enough, and the habit really did
123+
work.
124+
125+
The next time you reach for `dd()`, consider setting a breakpoint instead and seeing
126+
how far it gets you. Start your editor listening, put a breakpoint on the line you
127+
would have dumped from, and look around when it stops. There is nothing to install
128+
and nothing to turn on.
129+
130+
If you have not tried it since the tooling got better, it is worth one afternoon to
131+
find out.

‎sidebars.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const sidebars = {
3838
'user-guide/step-debugging',
3939
'user-guide/inspect-variables',
4040
'user-guide/watches-and-edits',
41+
'user-guide/stop-using-dd',
4142
'user-guide/logging',
4243
'user-guide/troubleshooting',
4344
],

0 commit comments

Comments
 (0)