Debug PHP with Xdebug and PhpStorm on Windows: A Practical Setup Guide
Author TallmanCode
Categories PHP, Debugging, PHPStorm

Hey there, fellow PHP enthusiasts! Ever found yourself lost in a sea of var_dump() calls, trying to work out why your application is misbehaving? We've all been there. Today we're going to set up a proper step debugger using Xdebug on Windows, paired with PhpStorm. Once it's working, you'll be able to pause your code mid-request, look at every variable, and walk through it line by line.
A quick note before we start: this guide is for Xdebug 3. If you're following an older tutorial that mentions xdebug.remote_enable or port 9000, that's Xdebug 2. Xdebug 3 changed many of the settings, and the default port moved from 9000 to 9003.
Sound good? Let's get started!
What You'll Need
- PHP installed on Windows (through XAMPP, Laragon, a manual install, or similar)
- PhpStorm
- Access to your
php.inifile
Step 1: Grab the Right Xdebug Build
On Windows, Xdebug is a DLL file, and it has to match your PHP setup closely. You'll need the right combination of PHP version, architecture (32 or 64 bit), thread safety (TS or NTS), and Visual Studio compiler version. Getting one of those wrong is the most common reason Xdebug silently refuses to load.
Thankfully, you don't have to work that out by hand. Head to the Xdebug installation wizard at xdebug.org/wizard. Create a small PHP file that calls phpinfo();, open it in your browser, and copy the whole page. Alternatively, run php -i in a terminal and copy the output. Paste either one into the wizard, and it tells you exactly which file to download. Think of it as a personal shopping assistant for extensions.
While you're looking at the phpinfo() output, note the "Loaded Configuration File" entry. That's the php.ini we'll be editing shortly.
Step 2: Install the DLL
Place the downloaded DLL in the ext folder inside your PHP installation, and name it php_xdebug.dll. Then open your php.ini and add:
zend_extension=xdebugIf PHP complains that it can't find the extension, use the full path to the file instead:
zend_extension="C:\php\ext\php_xdebug.dll"Adjust the path to match your own PHP folder. Note that it's zend_extension, not the plain extension directive that most other PHP extensions use.
Step 3: Configure Xdebug
Next, add the settings that tell Xdebug how to behave. Put these in the same php.ini, ideally in an [xdebug] section:
[xdebug]
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=127.0.0.1
xdebug.client_port=9003Here's what each line does:
xdebug.mode=debugturns on step debugging. In Xdebug 3, this setting replaces the oldremote_enableoption.xdebug.start_with_request=yesstarts a debug session on every request. It replaces the oldremote_autostartsetting and is the simplest way to get going locally.xdebug.client_hostandxdebug.client_porttell Xdebug where to find your IDE. Port 9003 is the default in Xdebug 3, but spelling it out makes the setup easier to read and troubleshoot.
One thing to be aware of: with start_with_request=yes, every web request and every command-line script will try to connect to your IDE. That's fine on your own machine. If you'd rather have more control, set it to trigger instead. Xdebug will then only start a session when a trigger is present, such as a browser extension or bookmarklet from JetBrains. And keep the yes setting off shared or production servers.
Finally, save the file and restart your web server (Apache, or PHP-FPM, depending on your stack) so PHP picks up the changes. Skipping the restart is a common mistake, and it can leave you wondering why nothing changed.
Step 4: Test the Waters
Let's confirm Xdebug is actually loaded. You have two quick options:
- Run
php -vin a terminal. The output should mention Xdebug. - Open your
phpinfo()page in the browser. You should see an Xdebug section.
Keep in mind that the command line and your web server can load different php.ini files. If Xdebug shows up in one but not the other, compare the "Loaded Configuration File" entries in each. If you see the Xdebug section in your browser, you're golden.
Step 5: Set the Stage in PhpStorm
Now for the PhpStorm side. The simplest route is what JetBrains calls zero-configuration debugging, and it takes only a few steps.
Check the Debug Port
Open Settings (Ctrl+Alt+S) and go to the PHP section, then Debug. Under Xdebug, make sure the debug port matches the xdebug.client_port value in your php.ini. The default is 9003.
Start Listening
Click the Start Listening for PHP Debug Connections button on the toolbar, or choose it from the Run menu. This tells PhpStorm to wait for Xdebug to knock on the door.
Drop a Breakpoint
Click in the left gutter next to a line number where you'd like to pause, or press Ctrl+F8 on the line. If you want the debugger to stop at the very first line of a script instead, you can enable Break at first line in PHP scripts from the Run menu.
Load Your Page
Open your application in the browser and reload the page. The first time Xdebug connects, PhpStorm shows an Incoming Connection From Xdebug dialog and asks you to set up path mappings. Path mappings tell PhpStorm how the files on your web server line up with the files in your project. You can also manage them any time under Settings, PHP, Servers.
Once the connection is made, PhpStorm stops at your breakpoint, and you're debugging.
Prefer a Run Configuration?
If you like having a dedicated debug configuration, that works too. Go to Run, then Edit Configurations, and add a new PHP Web Page or PHP Script configuration. Choose your server and tell PhpStorm which page or file to start with. It's a bit more setup than listening, but some developers prefer having a one-click launch.
Step 6: Debugging in Practice
With PhpStorm paused at a breakpoint, the Debug tool window shows the current variables and the call stack. From there, the default keyboard shortcuts on Windows are:
- F8 to step over the current line
- F7 to step into a function call
- F9 to resume until the next breakpoint
It takes a little practice, but stepping through real code is one of the best ways to understand what your application is doing. You'll spot the wrong value or the unexpected branch far faster than you would by adding output and refreshing.
Troubleshooting Checklist
If your breakpoints aren't being hit, work through these in order:
- Is Xdebug loaded? Check
php -vandphpinfo(). If it's missing, revisit the DLL build (version, architecture, TS or NTS) and confirm you edited the rightphp.ini. - Did you restart the web server? Changes to
php.inidon't apply until you do. - Is PhpStorm listening? The Start Listening button needs to be active.
- Do the ports match? The port in PhpStorm should equal
xdebug.client_port. If another program is already using port 9003, choose a different port and update both places. - Are your path mappings correct? A mismatch can stop PhpStorm from connecting your breakpoints to the running files.
PhpStorm can also help. The Run menu includes a Web Server Debug Validation tool that checks your Xdebug installation and configuration and suggests fixes.
Wrapping Up
And there you have it! With Xdebug and PhpStorm working together, you can stop guessing and start watching your code run. It's a real shift in how you track down bugs, and it pays off on every project after this one. Happy debugging, and may your breakpoints always be hit!