Quickly switching Xdebug on and off when using Homebrew

Published · Updated

You use Xdebug, built by Derick Rethans, to collect code coverage with phpunit/phpunit and to debug code in PhpStorm.

But you have also set xdebug.mode to coverage,debug, and everything else you run with PHP pays for that. On my Mac Mini, a synthetic benchmark takes 3.4 times as long as with xdebug.mode set to off.

How can you quickly switch Xdebug on and off when you have installed PHP with Homebrew?

Installing Xdebug

The Homebrew tap shivammathur/extensions provides one formula for Xdebug for each version of PHP.

Running

brew tap shivammathur/extensions \
  && brew trust shivammathur/extensions \
  && brew install shivammathur/extensions/xdebug@8.5

installs Xdebug for PHP 8.5 and creates the configuration file /opt/homebrew/etc/php/8.5/conf.d/20-xdebug.ini.

Switching Xdebug on and off

PHP only loads files with a .ini extension from that directory, so renaming the configuration file disables Xdebug.

Add the following functions to ~/.zshrc:

# Toggle extension
function toggle()
{
    name=$1
    displayName=${2:-$1}

    # Matches ext-<name>.ini (pecl) and 20-<name>.ini (shivammathur/extensions)
    enabledConfigs=(/opt/homebrew/etc/php/*/conf.d/*-${name}.ini(N))

    if (( $#enabledConfigs )); then
        for config in ${enabledConfigs[*]}; do
            mv "${config}" "${config}.bak"
        done
    else
        for config in /opt/homebrew/etc/php/*/conf.d/*-${name}.ini.bak(N); do
            mv "${config}" "${config%.bak}"
        done
    fi

    php -v

    if [[ $(php -m | grep ${name}) ]]; then
        echo "${displayName} extension has been enabled."
    else
        echo "${displayName} extension has been disabled."
    fi
}

# Toggle xdebug
function x () {
    toggle xdebug Xdebug
}

The function toggle expects the name of an extension and, optionally, its display name. When a matching configuration file is enabled for any installed version of PHP, the function adds a .bak extension to every matching configuration file. Otherwise, it removes the .bak extension from all of them. It then tells you whether the extension is enabled.

The glob qualifier (N) is a feature of zsh, so the functions do not work in bash.

Now running

x

switches Xdebug on and off for all installed versions of PHP.

Have you found a better option for switching Xdebug on and off?

Tagged with homebrew, macos, php, xdebug