DI container and IDE integration

Say we use a DI container directly, i.e. via functions like get() or make(), how do we achieve proper IDE support? For example I create a class instance the usual way

$server = $this->container->get(Server::class);

and I want to know what methods my Server class provides

$server-> ???

I could use docblocks

/** @var Server $server */ 
$server = $this->container->get(Server::class);

This works fine in many IDE like PhpStorm:

php-di-ide-integration-1

however the docblock is somehow annoying to me. The IDE *should* really know what class instance the variable $server is, since everything it needs to know is in the class name constant I provided as parameter for the get() function.

There might be a way using the hardly known .phpstorm.meta.php file for PhpStorm, but that one is currently some sort of under construction – at least I couldn’t get it working properly. Hopefully the PhpStorm guys will extend the documentation soon!

Once again, the PHP community provides the solution: the small but pretty cool PhpStorm PHP-DI plugin does exactly what we need! Now PhpStorm knows that $server is an instance of the Server class without me needing to do any further work:

php-di-ide-integration-2

Class name constants should be used wherever possible nowadays, however it also works with the Fully-qualified class name as string:

$server = $this
             ->container
             ->get('CarstenWindler\ApiGuy\Server');

But really, you shouldn’t do that. Please. Better just forget what I said. Forget it. Begone!

Awesome! Although actually written for the PHP-DI container, it also supports container-interop and even that crapp… I mean lovely but omnipresent Laravel App Facade sort of jun… container… thing.

I’d recommend to use DI containers directly only in very few places like Application bootstrapping or factories. But imagine you have to deal with a legacy Laravel 4.2 application which uses that awful App::make() basically EVERYWHERE, you are happy about any help.

Debug Unit Tests using the PhpStorm built-in test runner

PhpStorm comes with a handy phpunit test runner, which lets you execute your tests with just one click. Even better: if a test fails, you can just run that test also with just one click. That’s how I like it.

However I often use the debugger to debug failed tests. This is easy with phpunit and via the command line (see e.g. Remote CLI debugging). But since PhpStorm is obviously not using the command line, we have to pass the information necessary for Xdebug and PhpStorm to initiate the debug session using the Test Runners configuration.

XDEBUG_CONFIG=idekey=PHPSTORM ; PHP_IDE_CONFIG=serverName=local.dev

Needless to mention that the above values need to fit your setup. Most likely your server name will be different, and make sure to check the ide key.

But where to put it? Assuming you already setup your Run/Debug configuration, just open the configuration dialog and put the above environment variables into the “Environment variables” input field. You don’t need to add “export” or anything. Well, just have a look:

phpstorm_unit_test_runner

Now just place your breakpoints as you need them and start the Run/Debug configuration.

Remote CLI debugging with XDebug

There are quite some tutorials out there on how to use XDebug to debug PHP CLI code, which where more confusing than helpful (to me). I found out that, once you have a running XDebug configuration, it is very easy to debug on the console, particularly with phpStorm.

Simply run the following line once

export PHP_IDE_CONFIG=serverName=www.domain.com ; export XDEBUG_CONFIG=idekey=PHPSTORM

(after customizing it to your needs, of course), set your breakpoints and run the script. That’s already it. You can also put this into your .bashrc file.