PHPStorm and Xdebug

In the last lesson, we looked at debugging, the old school way. There's a better way to debug, but it has some messy setup. Let's check it out.

How many doggos?

Let's take a program from before, with the variable $dogs changed to $doggos. Here's the code.

  1. <?php
  2. $doggos = $_GET['dogs'];
  3. // Compute message, and CSS class.
  4. $message = '';
  5. $class = '';
  6. if ($doggos < 1) {
  7.     $message = "You don't have doggos! Boo! Get doggos!";
  8.     $class = 'argh';
  9. }
  10. else if ($doggos = 1) {
  11.     $message = "You have a doggo! That's good, but you need one more.";
  12.     $class = 'fair';
  13. }
  14. else if ($doggos == 2) {
  15.     $message = "You have two doggos! That's the perfect number!";
  16.     $class = 'good';
  17. }
  18. else {
  19.     $message = "Wow, that's a lot of doggos!";
  20.     $class = 'fair';
  21. }
  22. ?><!DOCTYPE html>
  23. <html lang="en">
  24.     <head>
  25.         <meta charset="UTF-8">
  26.         <title>Dogs</title>
  27.         <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  28.         <link rel="stylesheet" href="styles.css">
  29.     </head>
  30.     <body>
  31.         <h1>Dogs</h1>
  32.         <p>Do you have enough dogs?</p>
  33.         <p>Number of dogs: <?= $doggos ?></p>
  34.         <p class="<?= $class ?>"><?= $message ?></p>
  35.     </body>
  36. </html>

I made one other change, too, as we'll see.

So, I run the program. Here's the GET param:

  • something.php?dogs=2

Two dogs. Here's the output:

Wrong output!

What the f...?? It thinks we have one dog.

Let me try this:

  • something.php?dogs=3

I get:

Wrong output!

Argh! It's broken!

I read through the code carefully, but I don't see the problem. This is where the debugger can help.

I'll add a breakpoint to the code, just as you would be in VBA, by clicking in the grey area:

Breakpoint set

Now, when I run the program, it will stop when it gets to the line. Actually, it will stop just before it runs the line.

I refresh the browser, which runs the program again. PHPStorm stops at the breakpoint, and shows me memory so far. You can see the values of variables.

Stopped

You can see $_GET, and $doggos. What can you tell me about the bug so far?

Adela
Adela

Well, $doggos is what we expect. So the problem isn't with line 2.

Right! The variables' values are what we expect, so the problem is after the breakpoint.

Now I'll add a breakpoint right after the ifs, but before the HTML. Here's what I see:

Stopped later

Ethan
Ethan

Hey! $doggos is now 1. That's wrong! It should still be 3.

Indeed! Something went wrong between the breakpoints. We've narrowed down the lines that could be wrong.

Single step

OK, I'll run the program again, but when it stops on the first breakpoint, I'm going to single step the code. That is, run just one line at a time. The shortcut key for that is F8, on Windows and Linux.

I get to line 10:

Stopped again

Alright, $doggos is 3, everything is fine. I hit F8, to run line 10. What should happen?

Ray
Ray

Well, $doggos is not equal to 1, so it should skip to line 14.

Makes sense. I'll hit F8:

Argh!

Wait, what?! It's running line 11. And look at $doggos! It has the wrong value!

The program was OK up to line 10, then not. Line 10 is messing things up.

Georgina
Georgina

Oh, my dude! I see it! Line 10 is supposed to be...

  • else if ($doggos == 1) {

... but it's...

  • else if ($doggos = 1) {

It's missing an =.

Adela
Adela

OMG, Georgina! You rock!

Ethan
Ethan

Yeah, nice work!

Ray
Ray

I don't get it.

== and = are different. == is a test for equality. So $doggos == 1 gives true, or false, depending on whether $doggos is one or not.

= is an assignment statement, like VBA. Put the value on the right, into the variable on the left. $doggos = 1 puts one into $doggos, erasing what was there.

Ray
Ray

Oh, I see! Wow, that sucks.

You know, with all the cool stuff PHPStorm does, it should be able to check that.

Hmm. Good point, Ray. Let me dig around a bit... Aha!

PHPStorm has many rules it uses to warn you about possible errors. They're called inspections. There are hundreds of them, and they've saved me time and again.

You can see them under File | Settings | Editor | Inspections. Go to PHP, and scroll down to Probable bugs. Guess what the first one in the list is?

Inspection

"Assignment in condition" is the bug we saw. Look at what PHPStorm does when it detects that: fix it automatically, without telling you. The problem is, because of the way I edited the code, PHPStorm didn't detect the problem! And I'm not so keen on it editing my code without telling me.

I changed the setting to Warning. This is what I see now:

Inspection output changed

Remember that the yellow background indicates a warning. Just what I want.

PHPStorm rarely gets a setting wrong, but this is a case where it did. In my opinion, anyway.

Adela
Adela

That's a freakin' long list of inspections.

Aye, it is. It's one reason PHPStorm is a fave among developers.

Setting up debug

Debugging is a Must Have. PHPStorm uses an external tool: Xdebug. It's perhaps the most widely used PHP debugging tool.

XAMPP already includes Xdebug. Yay!

Xdebug is free. Free is good.

But Xdebug might not be connected up. Let's check. Make sure Apache is running, then go to one of these, or whatever port you use for XAMPP:

You'll see config info about PHP.

Adela
Adela

So, this a URL on localhost, so the file dashboard/phpinfo.php should be on my PC, right?

Aye! Good thinking, Adela! Let me look for the file... there it is!

phpinfo.php

It has this in it:

  • <?php phpinfo();

phpinfo() that makes HTML to show the deets of your PHP installation. You can use it yourself, whenever you want.

Here's some of what I see:

phpinfo output

My XAMPP has PHP version 7.4.11. Yours will probably be later.

You can also see the path to the php.ini file. That stores the config info for PHP, including debugging config.

IMPORTANT

On my PC, Xdebug is working well, but I don't remember everything I did to get it that way. The below is based on my memory of things, and some interwebs searching.

If you do something different, please let me know.

Search for "xdebug" on you PHPInfo page. Because my debugger is linked in my php.ini file, xdebug shows up. For example:

IDE key

I remember setting the IDE key, though I don't remember if I had to, or not.

OK, let me open D:\xampp\php\php.ini. Down around line 909, I find:

  • zend_extension=php_xdebug.dll
  • xdebug.remote_enable=1

Xdebug is packaged as a DLL. That's Windows-speak for code that other programs can call.

(I don't know how Macs do this.)

Where is the DLL file? There's a directive in the ini file for that:

  • extension_dir="D:\xampp\php\ext"

I check that folder, and there's the Xdebug code:

The Xdebug DLL

Check your PC

Make sure you have php_xdebug.dll in xampp/php/ext. It should be there.

Open your php.ini file (e.g., with Notepad). Check around line 909 for...

  • zend_extension=php_xdebug.dll
  • xdebug.remote_enable=1

If it's not there, add it. Restart Apache, when you make any changes to ini files.

You can add the path to the zend_extension setting, as in:

  • zend_extension = "C:/xampp/php/ext/php_xdebug.dll"

You shouldn't need to, though.

You can check here for more. The same document is on your PC, in D:\xampp\htdocs\dashboard\docs.

Go to...

... again, and search for "Xdebug".

Into the storm, again

Xdebug is installed, and hooked up to Apache. Now, how do you get to it in PHPStorm?

I used the zero-configuration debugging method, from PHPStorm's debugging quickstart. For that, you need to install debugging extensions in your browser. There are instructions on how.

On Chrome, I added the Xedug helper (this link may not work - search the webstore for Xdebug). It adds an icon to your browser. Click it to enable/disable debugging.

Chrome extension

Firefox has an extension, too.

Firefox extension

The debug listener

In PHPStorm, debugging will work only if the debug connection listener is on:

Turn on the listener

Now you should be able to add breakpoints in PHPStorm.

If you have trouble, check Debug with PhpStorm: Ultimate Guide.

Unwanted breaking

Sometimes I have trouble with PHPStorm breaking when I don't want it to. If that happens to you, check under File | Settings | Languages & Frameworks | PHP | Debug. Here are my settings:

Settings

Debugging validation

PHPStorm can check whether debugging is set up correctly. There's an item in the Run menu:

Validate debug setup

You'll see something like this:

Start

What this tool does is:

  1. Write a special PHP program to your hard drive, using a file path.
  2. Run the program, using a URL.
  3. Check the output, to see whether the debugger is running.

Remember that a URL like localhost/test.php is really a path to a file, like D:\xampp\htdocs\test.php. So the tool might:

  1. Write test.php to D:\xampp\htdocs.
  2. Go to localhost/test.php to run the program.
  3. Check the output.

You need to pick a folder on your local site that PHPStorm can write its test program to. For example, I decided to keep it simple, and have PHPStorm use the root of localhost.

So, I needed to tell PHPStorm file path and URL of localhost's web root:

Paths for debug checker

OK, if you remember, I used port 8080 for my server, so I needed to add that to the URL.So the root of my website is http://127.0.0.1:8080. You won't need to add that, if you used port 80.

BTW, localhost and 127.0.0.1 are the same.

I installed XAMPP in D:\xampp, so the file root of my local site is at D:\xampp\htdocs.

I filled those two things in, and clicked the Validate button:

Validation succeeds

W00f!

Here are some debug settings I find useful:

Settings

Exercise

Exercise

Set up debugging

Prove that you've set up debugging in your IDE. Include the following screen shots.

Show your PHP info, with the location of your php.ini file. For example:

php.ini location

Your PHP info again, with your Xdebug IDE key.

IDE key

Code in your IDE, stopped at a breakpoint, showing variable values. For example:

Stopped at breakpoint

This screen shot must show the value of at least one variable, like the 11 on line 4. Use this code, if you like:

  • <?php
  • // Debugging test.
  • $message = 'Doggos are the best!';
  • $rating = 11;
  • ?><!DOCTYPE html>
  • <html lang="en">
  •     <head>
  •         <meta charset="UTF-8">
  •         <title>Dogs</title>
  •         <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  •         <link rel="stylesheet" href="styles.css">
  •     </head>
  •     <body>
  •         <h1>Dogs</h1>
  •         <p><?= $message ?></p>
  •         <p>Rating: <?= $rating ?> out of 10</p>
  •     </body>
  • </html>

Up next

Let's continue learning PHP.