|
2 | 2 | title: Step Debugging |
3 | 3 | --- |
4 | 4 |
|
5 | | -Step over, into, and out of your code with ease, following execution across files, closures, and includes. |
| 5 | +When a [breakpoint](./breakpoints.md) fires, your script freezes exactly where it |
| 6 | +is and the debugger hands control to your editor. Nothing else happens until you |
| 7 | +say so — PHP is sitting inside the request, holding its stack, its variables and |
| 8 | +its open connections, waiting. |
6 | 9 |
|
7 | | -:::note |
8 | | -This page is a work in progress — full documentation is coming soon. |
9 | | -::: |
| 10 | +From there you have four ways to move, and two ways to finish. |
| 11 | + |
| 12 | +## Moving through the code |
| 13 | + |
| 14 | +| Action | What happens | |
| 15 | +| --- | --- | |
| 16 | +| Step into | Runs the next statement. If it calls a function, enter the function and stop on its first line. | |
| 17 | +| Step over | Runs the next statement, including any calls it makes, and stops on the line after without entering them. | |
| 18 | +| Step out | Runs the rest of the current function and stops just after it returns. | |
| 19 | +| Run | Carries on until the next breakpoint, or to the end of the request. | |
| 20 | + |
| 21 | +**Step into** is the one that follows your code down. It descends into your |
| 22 | +functions, methods and closures, and into files pulled in by `include` or |
| 23 | +`require`. Bear in mind that it descends into *everything* your code calls — step |
| 24 | +into a line that starts with a framework call and you can find yourself several |
| 25 | +layers deep in code you did not write. |
| 26 | + |
| 27 | +**Step over** is what you want on the lines you already trust. The call still |
| 28 | +happens, and its breakpoints still fire — stepping over a function does not disable |
| 29 | +what is inside it. It only means you do not want to watch. |
| 30 | + |
| 31 | +**Step out** is the way back up when you have descended too far, or when you have |
| 32 | +seen what you needed to and want to get back to the caller. If you are already at |
| 33 | +the top level, there is nothing to return to, and it behaves like Run. |
| 34 | + |
| 35 | +**Run** — your editor may call it Continue or Resume — continues running the |
| 36 | +script. If nothing else stops it, the request completes normally and the session |
| 37 | +ends with it. |
| 38 | + |
| 39 | +## Run to cursor |
| 40 | + |
| 41 | +Most editors offer a "run to cursor" or "run to here": put the caret somewhere |
| 42 | +ahead and the script continues until it reaches that spot. |
| 43 | + |
| 44 | +There is no such command in the debugger. What your editor does is set a |
| 45 | +[temporary breakpoint](./breakpoints.md#temporary-breakpoints) on that line and |
| 46 | +then Run. The breakpoint fires once and switches itself off, which produces exactly |
| 47 | +the behaviour you asked for. |
| 48 | + |
| 49 | +Worth knowing for two reasons. The line still has to be one that executes, exactly |
| 50 | +as with any other breakpoint — aim at a comment or a closing brace and the script |
| 51 | +will run straight past it to the end. And it is subject to everything else in the |
| 52 | +way: any other breakpoint that fires first will stop you before you arrive. |
| 53 | + |
| 54 | +## Seeing return values |
| 55 | + |
| 56 | +By default, stepping out of a function drops you on the line after the call, and |
| 57 | +the value that came back is not shown anywhere — you have to step on and inspect |
| 58 | +whatever it was assigned to. If it was not assigned to anything, or the call is |
| 59 | +part of a longer chain, that value is awkward to get at. |
| 60 | + |
| 61 | +The debugger can add an extra stop on the way out of each function, showing what it |
| 62 | +is about to return. This is off unless your editor asks for it — it is negotiated |
| 63 | +when the session starts, so where you turn it on is an editor setting, usually |
| 64 | +along the lines of "break on return" or "show return values". |
| 65 | + |
| 66 | +The cost is one more stop per function you step out of, which is the reason it is |
| 67 | +not on by default. Turn it on while you are chasing a wrong value through a chain |
| 68 | +of calls, and off again afterwards. |
| 69 | + |
| 70 | +## Stopping and detaching |
| 71 | + |
| 72 | +Two ways to end a session, and the difference matters: |
| 73 | + |
| 74 | +| Action | Effect | |
| 75 | +| --- | --- | |
| 76 | +| Stop | The script is killed. It does not finish. | |
| 77 | +| Detach | The debugger lets go and the script runs to completion on its own. | |
| 78 | + |
| 79 | +**Stop** terminates the request where it stands. Nothing after the current point |
| 80 | +runs — no remaining output, no shutdown functions, no destructors you were counting |
| 81 | +on. Anything half-finished stays half-finished: a transaction that was never |
| 82 | +committed, a file that was written but not closed, a queue message taken but not |
| 83 | +acknowledged. |
| 84 | + |
| 85 | +**Detach** disconnects the debugger and leaves the script running. Breakpoints stop |
| 86 | +firing, the request finishes as it normally would, and your editor goes quiet. This |
| 87 | +is the one to use when you have seen what you came for on a request that ought to |
| 88 | +complete — a checkout that should reach the end, a job that should be marked done. |
| 89 | + |
| 90 | +Neither turns the debugger off. The next request starts a fresh session and |
| 91 | +connects again, so if you are stepping through something and want the noise to stop |
| 92 | +for a while, disconnect your editor rather than detaching from each request in turn. |
0 commit comments