Debug PHP-FPM¶
Debug a PHP application served by PHP-FPM — a request coming from a browser or
curl stops on your breakpoint.
Prerequisites¶
php-dbgp-adapteronPATH- Xdebug installed in the PHP-FPM pool
- PHP-FPM already running
Xdebug settings¶
In the ini used by the FPM pool:
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=localhost
xdebug.client_port=9003
Restart PHP-FPM after editing:
Verify Xdebug is actually loaded in the pool — not just in the CLI PHP, which is a different ini:
Look for an Xdebug section with mode => debug.
Config¶
version = 1
default = "web"
[profiles.web]
adapter = "php"
program = "."
[profiles.web.launch_arguments]
sessionMode = "server"
port = 9003
server is the mode for something already running: the adapter waits, and PHP
requests connect to it as they arrive.
Run¶
-
Set a breakpoint in a file the request will reach — a controller, not a bootstrap file that ran long ago.
-
Start the session:
- Send a request:
What should happen¶
The request pauses, the debugger stops at line 45, and curl sits waiting for a
response until you continue.
Requests sent before you started the session run normally, without debugging.
That is the useful property of server mode: the site keeps working, and you
debug only when you choose to.
Requests time out while you are stopped¶
A stopped request is a request the web server is still waiting on. Nginx or Apache will eventually give up:
Raise it while debugging, or accept that long inspections end in a 504 on the client side — the debug session itself is unaffected.
Only debugging your own requests¶
On a shared or busy environment, start_with_request=yes makes every request
try to connect. Use the trigger instead:
Then only requests carrying the trigger are debugged:
Browser extensions for Xdebug set that cookie for you.
When it does not work¶
| Symptom | Fix |
|---|---|
| Nothing stops | the request went out before the session started — send another |
| Nothing ever connects | Xdebug is not loaded in the FPM ini; check phpinfo() |
| Breakpoints stay pending | normal before the first request; after one, check paths |
| The client gets a 504 | the web server's read timeout — raise it |
| Stops in a file you did not expect | an earlier breakpoint bound in a shared bootstrap file |