XDebug is a powerful PHP debugging extension that enables step-through debugging with breakpoints, variable inspection, and call stack analysis. This is particularly useful for Phel core/compiler development and understanding how your Phel code compiles to PHP.
Installation & Configuration ›
Installation
Recommended: Install via PIE (PHP Installer for Extensions)
PIE is the modern replacement for PECL. Download the latest pie.phar from the PIE releases, then:
# Install PIE
# Install XDebug with PIE
Note: PECL is now deprecated. PIE is the official successor and recommended installation method.
Alternative methods:
# Via system package manager (Ubuntu/Debian)
# On macOS with Homebrew
For Docker/container environments, add to your Dockerfile:
# Using PIE (recommended)
RUN curl -L https://github.com/php/pie/releases/latest/download/pie.phar -o /usr/local/bin/pie && \
chmod +x /usr/local/bin/pie && \
pie install xdebug/xdebug
# Or using PECL (legacy)
RUN pecl install xdebug && \
docker-php-ext-enable xdebug
Verify installation:
# Should show: "with Xdebug v3.x.x"
Configuration
Configure XDebug in your php.ini or create a dedicated config file (/etc/php/conf.d/xdebug.ini or similar):
[xdebug]
xdebug.so
.mode=debug
.start_with_request=yes
.client_host=
.client_port=9003
Key settings:
xdebug.mode=debug- Enable debugging modexdebug.start_with_request=yes- Start debugging on every requestxdebug.client_port=9003- Default port for XDebug 3.x (was 9000 in XDebug 2.x)
For containers/VMs:
- Set
xdebug.client_host=host.docker.internal(Docker Desktop) - Or set to your host machine's IP address
- Ensure the debug port (9003) is exposed/forwarded
Editor Setup
VSCode
Install the PHP Debug extension:
Create .vscode/launch.json in your Phel project:
Configuration Options:
| Option | Type | Default | Description |
|---|---|---|---|
phpDebugPort | number | 9003 | XDebug port to listen on |
pathMappings | object | {} | Path mappings for Docker/remote debugging |
cacheDir | string | auto | Phel cache directory (auto-detected from phel-config.php) |
skipPhelInternals | boolean | true | Skip stepping through Phel runtime code |
skipFiles | string[] | [] | Glob patterns for files to skip when stepping |
Path Mappings are crucial when using Docker/VMs. Map the container's path to your local workspace:
- Container path:
/var/www/html(or wherever your code lives in the container) - Local path:
${workspaceFolder}(your local project directory)
Usage:
- Set breakpoints directly in
.phelfiles by clicking left of line numbers - Press
F5or click "Run and Debug" → "Debug Phel" - Run your Phel code (CLI or web request)
- Execution will pause at breakpoints, showing Phel source context
Additional Commands:
Phel: Show Compiled PHP Location- Shows which PHP line a Phel line maps toPhel: Clear Source Map Cache- Clears cached source map data
Note: The extension auto-detects the cache directory from
phel-config.php. If your project uses a custom temp directory, it will be discovered automatically.
Alternative: Using PHP Debug Extension
If you prefer debugging at the PHP level (or don't have the Phel extension installed), you can use the PHP Debug extension:
With this approach, you'll need to set breakpoints in the compiled PHP files (found in the temp directory). Use setKeepGeneratedTempFiles(true) in phel-config.php to preserve the compiled files for inspection.
PHPStorm
PHPStorm has built-in XDebug support:
-
Configure PHP Interpreter:
- Go to:
Settings→PHP→CLI Interpreter - Add or select your PHP interpreter
- Verify XDebug shows as "Installed ✓"
- Go to:
-
Configure Debug Settings:
- Go to:
Settings→PHP→Debug - Set XDebug port to
9003 - Check "Can accept external connections"
- Go to:
-
Path Mappings (for Docker/VM):
- Go to:
Settings→PHP→Servers - Add a new server configuration
- Map your project root to the container path:
- Local:
/Users/you/phel-project - Remote:
/var/www/html
- Local:
- Go to:
-
Start Listening:
- Click the phone icon in the toolbar: "Start Listening for PHP Debug Connections"
- Or use menu:
Run→Start Listening for PHP Debug Connections
-
Set breakpoints and run your code
Detailed guide: VVV PHPStorm XDebug Setup
Emacs
XDebug uses the Debug Adapter Protocol (DAP). Set up dap-mode:
(use-package dap-mode
:config
(require 'dap-php)
(dap-php-setup))
(dap-register-debug-template
"Phel XDebug"
(list :type "php"
:request "launch"
:mode "remote"
:port 9003
:pathMappings (ht ("/var/www/html" "/local/path/to/project"))))
Neovim
Set up nvim-dap:
local dap = require
dap.. =
dap.. =
Debugging Phel Code
With VS Code Phel Extension
The Phel VS Code extension provides a seamless debugging experience:
-
Set breakpoints in
.phelfiles: Click in the gutter next to any line. The extension automatically maps these to the corresponding PHP lines. -
Source-level debugging: Stack traces show Phel file names and line numbers, not the compiled PHP.
-
Phel-native variable display: Variables are shown with Phel formatting:
- Vectors:
[3 items] - Maps:
{2 entries} - Keywords:
:status - Lists:
(5 items)
- Vectors:
-
Skip internals: By default, stepping skips Phel runtime code. Disable with
"skipPhelInternals": falseif debugging the Phel runtime itself. -
Hover for mapping info: Hover over a breakpoint to see which PHP file/line it maps to.
With Other Editors
When debugging Phel code with XDebug in editors without native Phel support:
-
Breakpoints in compiled PHP: Since Phel compiles to PHP, you'll be stepping through the generated PHP code. Use
setKeepGeneratedTempFiles(true)inphel-config.phpto inspect the compiled output. -
Path mapping is critical: Ensure your editor knows how to map container/VM paths to local paths.
-
Debugging the compiler: For Phel core development, set breakpoints in the compiler code (
vendor/phel-lang/phel-lang/src/). -
REPL debugging: You can debug REPL sessions by running the REPL with XDebug enabled.
Troubleshooting
Connection issues:
# Check if XDebug is loaded
# Check XDebug configuration
|
# Test if port 9003 is open
Enable XDebug logging to diagnose connection problems:
.log=/tmp/xdebug.log
.log_level=7
Common issues:
- Port conflicts: XDebug 3.x uses port 9003 (not 9000). Update your editor configuration.
- Firewall: Ensure port 9003 is not blocked by firewall rules.
- Path mappings: Double-check that container paths match your actual paths. Use
pwdinside the container to verify. - Docker: Use
host.docker.internalinstead oflocalhostforxdebug.client_host. - WSL2/VM: May need to use the host machine's network IP address.
Testing XDebug connection:
Create a simple test script:
Run it and verify your debugger connects.