Jan 27 2018
Jan 27

The problem: XDebug doesn't work for Composer scripts

PhpStorm is quite convenient to debug scripts with XDebug (do you support Derick for giving us XDebug ?): just add a "Run/Debug configuration", choosing the "PHP Script" type, give a few parameters, and you can start debugging your PHP CLI scripts, using breakpoints, evaluations, etc.

Wonderful. So now, let's define such a configuration to debug a Composer script, say a Behat configuration generator from site settings for some current Drupal 8 project. Apply the configuration, run it in debug mode, and ....

...PhpStorm doesn't stop, the script runs and ends, and all breakpoints were ignored. How to actually use breakpoints in the IDE ?

Broken configuration to debug a Composer script

The diagnostic

Let's see how Composer actually starts: <?php
#!/usr/bin/env php
<?phpif (PHP_SAPI !== 'cli') {
    echo
'Warning: Composer should be invoked via the CLI version of PHP, not the '.PHP_SAPI.' SAPI'.PHP_EOL;
}

require

__DIR__.'/../src/bootstrap.php';

use

Composer\Factory;
use
Composer\XdebugHandler;
use
Composer\Console\Application;error_reporting(-1);// Create output for XdebugHandler and Application
$output = Factory::createOutput();$xdebug = new XdebugHandler($output);
$xdebug->check();
unset(
$xdebug);// [...more...]
?>

Now, we can step through this, and notice the Composer script actually runs during the $xdebug->check(); line. What's going on ?

<?php
// In vendor/composer/composer/src/Composer/XdebugHandler.php
   
public function check()
    {
       
$args = explode('|', strval(getenv(self::ENV_ALLOW)), 2);

        if (

$this->needsRestart($args[0])) {
            if (
$this->prepareRestart()) {
               
$command = $this->getCommand();
               
$this->restart($command);
            }

            return;
        }
    

// [...more...]
?>

Here's the crux of the problem: in order to alleviate the extreme slowdown caused by XDebug when running Composer commands, any time Composer is run, it checks for the presence of Xdebug in the running PHP configuration, and if it finds it (the needsRestart() check), it rebuilds a command line with a different PHP configuration ($command = $this->getCommand();), which does not include the xdebug extension, and runs it in the $this->restart($command); call, which actually runs the new command using the passthru mechanism.

<?php
   
protected function restart($command)
    {
       
passthru($command, $exitCode);
   
// [...more...]
?>

Now, since this command no longer runs with Xdebug, there is no way a debugging tool can use it. So how does one fix the problem ?

The solution

Let's go back to the beginning of this check() method:

<?php
class XdebugHandler
{
    const
ENV_ALLOW = 'COMPOSER_ALLOW_XDEBUG'; // [...snip...] public function check()
    {
       
$args = explode('|', strval(getenv(self::ENV_ALLOW)), 2);

        if (

$this->needsRestart($args[0])) {
   
// [...more...]
?>

So the call to needsRestart($args[0] does actually depend on the value of the XdebugHandler::ENV_ALLOW constant, i.e. COMPOSER_ALLOW_XDEBUG. Let's see.

<?php
   
private function needsRestart($allow)
    {
        if (
PHP_SAPI !== 'cli' || !defined('PHP_BINARY')) {
            return
false;
        }

        return empty(

$allow) && $this->loaded;
    }
?>

So, if COMPOSER_ALLOW_XDEBUG is not empty, needsRestart($allow) will return FALSE. In which case, as shown above, it won't cause the new command to be built, and Composer will just proceed with our script and allow our debugging to work.

In practice, this means all we need it to pass a COMPOSER_ALLOW_XDEBUG environment variable with a non-empty value in the PhpStorm run configuration, like this.

Debug configuration for Composer command in PhpStorm

Debugging a Composer script in PhpStorm

Problem solved_! BTW, did you notice this was explained in the Composer vendor/composer/composer/doc/articles/troubleshooting.md documentation ?

[...snip...]
## Xdebug impact on Composer

To improve performance when the xdebug extension is enabled, Composer automatically restarts PHP without it.
You can override this behavior by using an environment variable: `COMPOSER_ALLOW_XDEBUG=1`.
[...more...]

Yeah, me neither, until I solved the problem as described. So let's all just keep in mind to RTFM.

Jul 09 2012
Jul 09

Since having moved to Mac from Linux around 1 year ago I have been using MAMP to develop with Drupal. I actually bought the PRO version and my favorite MAMP features are:

  • Easy creation of Virtual Hosts
  • Easy switching between PHP 5.2 and 5.3

That said, there are some major annoyances with MAMP:

  • PHP versions hardly ever get updated (even with paid PRO version), latest available is 5.3.6
  • PHPMyAdmin version included is very outdated and missing out on some nice features
  • MySQL version is stuck at 5.1
  • PHP requires a workaround to work in the terminal
  • Built-in PEAR doesn't play nice

So, after reading about VirtualDocumentRoot in this article I decided to take the plunge and try replacing my MAMP setup with the built-in Apache and PHP and using Homebrew to complement whatever was missing. Since I hardly use Drupal 6 anymore, I figured I can live without PHP 5.2.

What started out as a "I wonder if I can get this to work" 10-minute hobby thing turned out into a full-day task and after finally getting everything to work I'm really satisfied with the results. Since I ran into a bunch of pitfalls along the way I thought I'd document my findings for future reference and also to share with others thinking about doing the same thing.

Despite being fully aware that we can actually and effortlessly build a full LAMP stack using Homebrew, I figured since OSX ships with Apache and PHP let's use them!

Step 1 - Backup

This one is a no-brainer. Backup all your stuff, especially MySQL databases as you will have to import them manually later on.

Step 2 - Enable built-in Apache

Open MAMP and stop all running servers but don't uninstall MAMP just yet! Ok, now go to the "Tools" menu and click on "Enable built-in Apache server". Next, go to "System Preferences -> Sharing" and enable the "Web Sharing" checkbox.

Update for Mountain Lion: The "Web Sharing" option doesn't exist anymore! In order to get things working check out the excellent instructions in this article.

If you're having issues with the checkbox not staying on, don't worry it's a simple fix: replace your /etc/apache2/http.conf with the default version:

1
2
3
4
5
# Backup your current http.conf (or remove it altogether)
sudo mv /etc/apache2/http.conf /etc/apache2/http.conf.bak
 
# Copy over the default settings
sudo cp /etc/apache2/http.conf.default /etc/apache2/http.conf

Step 3 - Enable built-in PHP

This one is easy, edit your new http.conf file and uncomment the following line:

1
#LoadModule php5_module        libexec/apache2/libphp5.so

Step 4 - Install MySQL

Just download MySQL and install it! You can then go to "System Preferences -> MySQL" to start the server and set it up to start up automatically.

Now, all we need to do is add the mysql directory to our PATH and we're good. You can set this up either in your ~/.bashrc or .~/profile: (know that if you have a .bashrc then your .profile won't get used, so pick one or the other)

1
export PATH="/usr/local/mysql/bin:$PATH"

Step 5 - Install PHPMyAdmin

This is an optional but highly-recommended step. I'm not going to bother rewriting this as there's a great article here that gives precise and up-to-date instructions. After following the instructions you should be able to access PHPMyAdmin at http://localhost/~username/phpmyadmin.

In order to persist your settings in PHPMyAdmin, you will need to do the following:

  • Create a "pma" user and give it a password "pmapass" (or whatever)
  • Import the "create_tables.sql" file found in your PHPMyAdmin's example folder
  • Grant full access to the "pma" user for the "phpmyadmin" database
  • Now edit your config.inc.php and add the following:
1
2
3
4
56
7
8
9
1011
12
13
14
1516
17
18
19
2021
22
23
24
// Setup user and pass.
$cfg['Servers'][$i]['controluser'] = 'pma';
$cfg['Servers'][$i]['controlpass'] = 'pmapass'; // Replace this with your password.
 
// Setup database.$cfg['Servers'][$i]['pmadb'] = 'phpmyadmin';
 
// Setup tables.
$cfg['Servers'][$i]['bookmarktable'] = 'pma_bookmark';
$cfg['Servers'][$i]['relation'] = 'pma_relation';$cfg['Servers'][$i]['table_info'] = 'pma_table_info';
$cfg['Servers'][$i]['table_coords'] = 'pma_table_coords';
$cfg['Servers'][$i]['pdf_pages'] = 'pma_pdf_pages';
$cfg['Servers'][$i]['column_info'] = 'pma_column_info';
$cfg['Servers'][$i]['history'] = 'pma_history';$cfg['Servers'][$i]['designer_coords'] = 'pma_designer_coords';
$cfg['Servers'][$i]['tracking'] = 'pma_tracking';
$cfg['Servers'][$i]['userconfig'] = 'pma_userconfig';
$cfg['Servers'][$i]['hide_db'] = 'information_schema';
$cfg['Servers'][$i]['recent'] = 'pma_recent';$cfg['Servers'][$i]['table_uiprefs'] = 'pma_table_uiprefs';
 
// For good measure, make it shut up about Mcrypt.
$cfg['McryptDisableWarning'] = true;

At this point everything should be ok, but I couldn't get it to work. I found that logging into PHPMyAdmin as "pma" and then logging out made everything work. I won't bother to try and understand this, just happy it worked.

Step 6 - Install Homebrew

Ok, now things start to get fun! All you need to do to install Homebrew can be found in the very nice installation instructions.

Once Homebrew is installed, run brew doctor from your terminal and fix any errors that appear, it's pretty straightforward. If you are getting a weird error about "Cowardly refusing to continue at this point /", don't worry. I had to update my XCode version and install the Command Line Tools from within the XCode preferences to make brew work without complaining.

Step 7 - Configure VirtualDocumentRoot

Once again, there's great a great article on this already so I won't bother rewriting this step.

Are you still with me? Don't forget to add Google DNS or Open DNS or something else in your network preferences after 127.0.0.1 or you won't be able to access anything outside your local environment.

At this point you should probably test out accessing http://localhost/~username in your browser and make sure everything works. Also create a "test.dev" folder in your Sites directory and make sure you can access it via http://test.dev.

If, like myself, you received some access denied errors, you might have to complement the Directory setting added in your http.conf:

1
2
3
4
56
7
<Directory "/Users/alex/Sites"> # obviously replace this with your username
  Options FollowSymLinks Indexes
  AllowOverride All
  Order deny,allow
  RewriteEngine on  RewriteBase /
</Directory>

Also, be warned, if you start getting errors navigating to any path except the frontpage in a Drupal site, you might need to edit your .htacccess file and uncomment the DocumentRoot / line.

Step 8 - Install PEAR

This is an optional, but highly recommended step. First, download the installer:

1
2
3
4
5
# If you have wget installed (hint: use Homebrew)
wget http://pear.php.net/go-pear.phar
 
# If not
curl -0 http://pear.php.net/go-pear.phar > go-pear.phar

Now, just run the phar archive:

1
sudo php -d detect_unicode=0 go-pear.phar

For whatever reason PEAR wants to install itself in your home folder by default, I suggest moving it to "/usr/local/pear".

After installing, make sure that the PEAR include path has been added to the end of your /etc/php.ini:

1
2
3
;***** Added by go-pear
include_path=".:/usr/local/pear/share/pear"
;*****

(If you don't have an /etc/php.ini file, copy it over from /etc/php.ini.default)

You will also have to add the PEAR path to your PATH in your .bashrc or .profile (see step 4).

1
export PATH="/usr/local/pear/bin:$PATH"

Step 9 - Install Drush

With PEAR available, installing Drush is a breeze. I personally prefer to install Drush using PEAR because its easier to manage and update:

1
2
sudo pear channel-discover pear.drush.org
sudo pear install drush/drush

If you skipped Step 8 and don't have PEAR installed, don't worry, there's plenty of information in the README to get Drush up and running.

Step 10 - Install XDebug

Ok, we are almost there! The last thing we really need to get a fully-functional development environment is XDebug. Unfortunately, despite many articles mentioning installation via Homebrew, I couldn't find the formula, so let's compile and install it ourselves.

Updated: There's an XDebug brew formula in @josegonzalez's homebrew-php. Just follow the steps in 11 but replace "xhprof" with "xdebug".

Once again, there's a great article for this. If you get an "autoconf" error you might need to install it using Homebrew:

1
brew install autoconf

Now phpize should work. Don't worry if it gives you a warning, just follow the steps in the article and it'll work anyway!

Now we should make a couple tweaks to our php.ini to take advantage of XDebug:

1
2
3
4
56
7
8
9
1011
12
13
14
1516
# General PHP error settings.
error_reporting = E_ALL | E_STRICT # This is nice for development.
display_errors = On # Make sure we can see errors.
log_errors = On # Enable the error log.
html_errors = On # This is crucial for XDebug 
# XDebug specific settings.
[xdebug]
zend_extension="/usr/lib/php/extensions/no-debug-non-zts-20090626/xdebug.so" # Enable the XDebug extension.
# The following are sensible defaults, alter as needed.
xdebug.remote_enable=1
xdebug.remote_handler=dbgp
xdebug.remote_mode=req
xdebug.remote_host=127.0.0.1xdebug.remote_port=9000

Afterwards just restart Apache and run php -v or open a phpinfo() script and you will see that XDebug appears after the "Zend Engine" version.

Step 11 - Install XHProf

This step is optional and I had forgotten about it until Nick reminded me, so props to him! :)

XHProf is a PHP profiler which integrates nicely with the Devel Drupal module and here's how to install it using Homebrew:

1
2
3
4
# Tap into the php formulae by @josegonzalez.
brew tap josegonzalez/php
brew install php53-xhprof
# This will automatically install the PCRE dependency.

Now all we need to do is add it to our php.ini and we're golden:

1
2
3
4
[xhprof]
extension="/usr/local/Cellar/php53-xhprof/0.9.2/xhprof.so" # Make sure this is the path that homebrew prints when its done installing XHProf.
;This is the directory that XHProf stores it's profile runs in.
xhprof.output_dir=/tmp

Now restart apache and look for "xhprof" in your phpinfo() to confirm all went well.

Bonus Steps - APC, Intl and UploadProgress

If you added josegonzalez's excellent homebrew-php (step 11), you can easily install some extra useful extensions:

1
2
3
4
56
7
8
# Recommended for Drupal
brew install php53-uploadprogress
 
# Recommended for Symfony2
brew install php53-intlbrew install php53-apc
 
# Don't forget to add them all to your php.ini, as per brew's post-install notes!

Step 12 - Cleanup

Ok, we're done! Now go to PHPMyAdmin and re-create your databases and users and also import the backups you made from MAMP's version of PHPMyAdmin. Assuming you followed all the steps successfully, it is now safe to completely uninstall MAMP.

Good for you! :) Now you can go look over the shoulder of a coworker that uses MAMP, smirk and shake your head in disapproval.

Dec 16 2011
Dec 16

I usually use linux, but for various reasons I've needed to use windows lately and so I figured I would setup Xdebug, Acquia Dev Desktop, and Netbeans in Windows.  I didn't see much for guides out there but its really pretty easy.

Step 1 - Install Acquia Dev Desktop:

You can install either the D6 or D7 one, because really they are the same and you can just add D6/7/yourflavor to it using its "import" button.

I installed this to "C:\acquia-drupal" and "C:\sites\acquia-drupal".  That way I don't have to worry about the spaces when configing my php.ini files.  Spaces in file directories always seem to cause me issues.  Like so:

Step 2 - Install Netbeans

I just went for the php version.  Once its installed you can download any plugins you want.

Step 3 - Setup Netbeans

This is pretty easy, I just basically followed: http://drupal.org/node/1019816.  Some of the options shown on that url are missing in my netbeans, so I just ignored them.

Also, install whatever plugins you want (git is a good one) from W.  To do this I had to run netbeans as administrator (in windows 7), everytime after that I didnt, but to get it going the first time I had too.

Step 4 - Add your project and config it for debug

The Drupal.org link above shows you how to add a project.  One tweak I would do after you add the project, right click your project > properties > Run configuration > Advanced > Do not open webbrowser.

Step 5 - Setup PHP for xdebug.

I noticed Acquia Dev Desktop had the xdebug extension already in the "C:\acquia-drupal\php5_2\ext" folder so I didn't even have to download it.

All I did was edit my php.ini file.  I added this to the bottom:

[debug]
zend_extension_ts=C:\acquia-drupal\php5_2\ext\php_xdebug-2.1.2-5.2-vc6.dll;
xdebug.remote_autostart=off
xdebug.remote_enable=1
xdebug.remote_handler=dbgp
xdebug.remote_host=localhost
xdebug.remote_port=9000

You can find a link to your php.ini file opening your Acquia Dev Desktop Control Panel and clicking on Settings, then config tab, then the "edit" button next to the php.ini file.

After you add the above to the php.ini file, stop and start the Acquia Drupal Stack.  Now, go back into setting, config tab, and click the phpinfo link.  This will open a page where you can see if xdebug is setup and working.  If you see anything about xdebug on that page, its probably working.

Step 6 - Install the easy Xdebug plugin for FireFox

This will put 2 little icons in your lower right of firefox, a bug-looking-thing and a green square.

Step 7 - Setup Breakpoints and debug

Boot up Netbeans, Acquia Drupal Stack, and Firefox. 

In firefox, go to the php page you want to debug. 

In netbeans, add breakpoints to where you want to stop.  Then click to the debug button in netbeans:

In firefox, click the green bug (lower right from easy Xdebug) and reload the page.

TADAAA, Netbeans will stop at the breakpoints and show you variables and such.  Very cool.

Conclusion

So there you go.  Pretty quick and easy to get up and running.  If you have any questions just let me know.  I'm not a pro at this stuff but I'll sure try and answer whatever you throw at me.

Jan 12 2011
mg
Jan 12

I had written about setting up php debugging environment with Eclipse on windows.

Well, turns out, setting up the debug environment on Mac OS X is also a little tricky since the library files do not always work.

I used the Helios Eclipse PDT distribution. I tried using the Zend debugging environment. But after struggling with the settings in the php.ini file, I decided to try XDebug. XDebug is straightforward, once you have crossed the windy roads. 

Here is the main gottcha - the default xdebug.so which ships with MAMP server might not always work. xdebug.org does not have the mac os x distribution for the .so file either. The one that ships with komodo editor however works and you can get it from here. Once you download the right file, save it and note the location.

Next edit the php.ini located at /Applications/MAMP/conf/php5.3 - Add the following to it

zend_extension="/Applications/MAMP/bin/php5.3/lib/php/extensions/no-debug-non-zts-20090626/xdebug.so"
xdebug.profiler_output_dir = "/tmp/xdebug/"
xdebug.profiler_enable = On
xdebug.remote_enable=On
xdebug.remote_host="localhost"
xdebug.remote_port=9000
xdebug.remote_handler="dbgp"
xdebug.idekey=ECLIPSE_DBGP

Now if you run phpinfo(), you should get some output about xdebug. The basic debugging is setup.

Make sure your eclipse is configured to work with php5.3 and that it uses the xdebug.

Don't modify ini files or other setting for php5.2 or in the incorrect directory. This usually makes up for most errors.

You should be on your way to happily debug Drupal now.

Jun 25 2009
Jun 25
firebug-xdebughelper.png

If you're a developer who uses the XDebug PHP debugger, you probably already use a Firefox extension called XDebug Helper, which provides a convenient toggle switch for enabling debugging. You probably have Firebug installed too. Here is a method for setting up keyboard shortcuts to toggle them on and off (I use F1 & F2).

First, install the keyconfig Firefox extension (unfortunately it doesn't have an official page). Click Tools->Keyconfig... and you should get the following window:

keyconfig-screenshot2.png

Changing the "Open Firebug" shortcut is easy: you should see it listed with a standard key binding of F12. Click it, type your new key into the edit box at the bottom of the window, and hit "apply".

To toggle XDebug Helper, you need to click "Add a new key". Fill out the popup window as follows:

xdebug-helper-toggle.png

Click ok and it will be added to the list. Then you can set the key binding in the same way as you did for Firebug, I set mine to F2. Don't forget to close and reopen Firefox. That's it!

If you're interested in setting up your own keyboard shortcuts for extensions that may not natively support them, here is the hack I used:

  1. Download the .xpi extension file, and extract it (it's just a zip file).
  2. Look through the source code for the main.js file.
  3. Find the function you'd like to call and set up a new shortcut for it in keyconfig.
May 08 2008
IO1
May 08

This Drupal Amazon EC2 AMI builds on our first released drupal Ec2 Ami. By adding xdebug and configuring it to work with VIM and output profiles for KCacheGrind or WinCacheGrind to our first Ami release, you can now instantly have a fully ready to go test server for everything from functional testing to performance testing.

All you have to do is run the normal ec2 installation, select the version of drupal you require and hey presto in a couple of minutes you have a fully working test environment with drupal, xdebug and vim all playing nicely together and outputting profiles for KCacheGrind/WinCacheGrind .

For both KCacheGrind / WinCacheGrind you need to download and install locally as they are GUI based.

Its not one of our hardened production server setups, its should not to be used in a production environment.

Technical installation details

The image is based on the standard Amazon FC8 image. On start up it automatically downloads and installs the latest version of Drupal core unless you specify otherwise.

  • The AMI ID of the image is: ami-534da83a
  • It will install the latest version of Drupal 6.x unless you specify a different core version with the -d parameter.
  • So, for example, if you want to create a Drupal 5.x instance:
  • ec2-run-instances ami-534da83a -k gsg-keypair -d 5
  • The -k parameter is mandatory, as there is no root password so you will have to log in with an ssh key
  • Default user name/passwords are both: drupal

Drupal Debugging/testing setup

The PHP xdebug extension is installed and configured to output profiling information in the /mnt/xdebug/profiler/ directory for every request.  

Download these files to your local machine and use a program like KCacheGrind (or WinCacheGrind on Windows) to view them.
You should see a list of functions that were called, along with the the time taken by each function and the functions it called, number of calls and lots of other useful statistics and analysis.

This is useful, but slows things down overall quite considerably.  If you want to disable it, edit the file /etc/php.d/xdebug.ini and change or remove the line "xdebug.profiler_enable = 1".  You can also set it to be enabled only for a specific request; see the comments in xdebug.ini for details.

Vim is installed, along with the DBGp client script from http://www.vim.org/scripts/script.php?script_id=1929 allowing it to act as a debugger for PHP code running on the server.  To use this, type "vim" at the shell prompt, press F5, and (within the next 5 seconds) point your web browser at the page you wish to debug, then go back to vim and press Enter.  

Now you can step through the code, set breakpoints, monitor variables etc.  Instructions are displayed in a help pane in the vim window.

Thanks to john for this one.

Bookmark/Search this post with

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web