Advanced debugging with PHP

Michalio

Moderator
Most of the time on working with the code is debugging. For simple projects the echo and print_r is enough, but for little bit more complicated projects we need something more. Let's imagine the possibility where you can go to any place in the code and check the values of each variable while code is executing.

I will show you how to do that. We will need:
- good editor that support debugging in the example I will use VSCode with plugins
- some time for reading and trying

Let's start
  1. First of all we need a local installation of PHP, debugging on remote server is possible, but is not recommend.
    You can install XAMP server of create your own configuration, if you want to deploy your app on any server then you should install the same version of PHP locally to be sure that the app will works on server.
    If we are using some functionality that's works only on specific OS (like executing bash scripts) then you can install your local environment inside docker or similar solution to have the same configuration on local machine as it is on your server.
  2. Then we need to enable and configure one PHP extension: xdebug. The configuration of xdebug v2 and v3 looks differently, because sometimes we need to maintain very old apps I will also show the configuration for v2 for php 7.1 and older.
    On windows we need to uncomment one line in your php.ini file:
    Code:
    extension=php_xdebug.dll
    On linux you need to install xdebug package from your repository (can be named php-xdebug, php8.0-xdebug or similar)
    Then we need to enable remote (in editor) debugging by editing xdebug.conf (may be placed in /etc/php/8.0/fpm/conf.d/20-xdebug.ini or conf.d directory in your php installation directory). If you can not find it you can place the configuration at the end of php.ini (it is testing environment so we can).

    Configuration for XDebug v3:
    Code:
    zend_extension=xdebug.so
    xdebug.mode=debug
    xdebug.start_with_request=yes
    xdebug.client_host=127.0.0.1
    xdebug.client_port=9080
    xdebug.discover_client_host=1
    xdebug.idekey=VSCODE
    xdebug.show_exception_trace = 1
    xdebug.show_error_trace = 1
    xdebug.max_nesting_level=250
    xdebug.log_level = 0

    XDebug v2:
    Code:
    zend_extension=xdebug.so
    xdebug.remote_enable = 1
    xdebug.remote_autostart = 1
    xdebug.remote_host = 127.0.0.1
    xdebug.remote_port = 9056
    xdebug.remote_connect_back = 0
    On my local device I am using more than one php version, so the port tell me which php version it is, port 9080 means php 8.0 and 9056 means php 5.6
    Now we need to restart our php server (or apache if we using it).
  3. Now it is time for create configuration for debugging in the editor. I am using VSCode with php extensions (link is at the end of the article).
    • Create launch.json for debugging:
      image.png

      image.png

      Then you can copied some configuration from my launch.json:
      Code:
      {
          // Use IntelliSense to learn about possible attributes.
          // Hover to view descriptions of existing attributes.
          // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
          "version": "0.2.0",
          "configurations": [
              {
                  "name": "Listen for XDebug (php 8.0)",
                  "type": "php",
                  "request": "launch",
                  "pathMappings": {
                      "/mnt/c/Users": "C:\\Users"
                  },
                  "port": 9080,
                  "hostname": "127.0.0.1",
                  "ignore": [
                      "**/vendor/**/*"
                  ]
              },
              {
                  "name": "Listen for XDebug (php 8.0) with vendor",
                  "type": "php",
                  "request": "launch",
                  "pathMappings": {
                      "/mnt/c/Users": "C:\\Users"
                  },
                  "port": 9080,
                  "hostname": "127.0.0.1"
              }
          ]
      }
      I added two configurations, because sometimes I want to debug packages in vendor directory.
  4. The debugging should works so let's test it.
    Create a sample php file:
    Code:
    <?php
    
    namespace App;
    
    class MyApp {
        private const APP = true;
        private array $data = [ 1, 2, 3 ];
        public int $id;
        public function __construct() {
            $var = 1;
    
            $this->ranomize();
            $this->echoSomething();
        }
    
        private function ranomize() {
            $this->id = rand();
        }
    
        private function echoSomething(): void {
            echo 'something';
        }
    }
    
    $app = new MyApp();
    The code should echo 'something' word, the code also set id to some random number with randomize() method, so lets check the number with debugging.

    We need to start debugging session:
    image.png

    You can do it with steps 1, 2 and 3 or just select the debugging configuration on the bottom (A)

    Then go to the code id is set, this is in the line 17 and set the breakpoint (red dot) by clicking or by pressing ter F9 key:
    image.png

    Then just run the php file, by http server or from command line (if you also set the xdebug configuration for cli), the php should stop on the line 17 before id is set:
    image.png

    We stopped the php before the id was set so we need to go one line forward with button 1, and then on the place marked as 2 we can see the value of the id.

That's all, happy debugging :)

Useful links:
  • VSCode: https://code.visualstudio.com/Download
  • VSCodium (opensource version of VSCode): https://vscodium.com/
  • PHP plugin for VSCode/VSCodium: https://marketplace.visualstudio.com/items?itemName=xdebug.php-pack
  • XAMP: https://www.apachefriends.org/
  • PHP Docker: https://hub.docker.com/_/php
 
Back
Top