PhpStorm Integration & Productivity Tips for Windows-Hosted PHP Dev [Visual Guide]

Along with my recent move from Vagrant to Docker I decided to revisit a number of tooling choices that I hadn’t second-guessed in a couple of years. The best new mousetrap I adopted after that review is PhpStorm, an IDE that manages to include a huge amount of features and integration capabilities without feeling bloated.

Here’s how I set it up so far with my Docker/LEMP/WP/JS/Jquery/Bootsteaprap/LESS stack in mind. Though this entry is focused on Windows, PhpStorm is cross-platform and most of what follows applies to Linux and Mac users.wita

1. Third-party Application deSupport/Integration

1.1. Docker

There’s Docker Support in PhpStorm, though there’s not much support for Docker Compose yet. At least the YAML code style is supported to help you use spaces instead of tabs for indentation in your docker-compose-yml file.

I put tcp://localhost:2375 in the API URL field to get PhpStorm to connect (thanks to this thread), and bingo, a mini-Kitematic interface right within the IDE, with container logs, properties, and bindings.

You can add your Docker Hub credentials: Ctrl+Alt+S to get PhpStorm settings then search “Docker registry”, you’ll then be able to pull images from there. This does not seem to work with the new Docker Store yet.


1.2. Terminal

You can use PowerShell  to run PhpStorm’s terminal. First change execution policies like explained here, then put powershell.exe as the shell path under Tools > Terminals in PhpStorm’s settings. Side note: Windows 10 comes with PSReadLine which improves command line editing.

PS within PS

PS within PS

But wait, there’s more better! You can set up Cmder in the same fashion. If you refer to it directly it will fire up a separate window instead of a dockable PhpStorm window, unless you refer to it that way (source):

“cmd.exe” /k “”%CMDER_ROOT%\vendor\init.bat””

Cmder / Clink = CLI QOL

Cmder / Clink = CLI QOL

Now your terminal is Git aware, has powerful command autocomplete/history capabilities, Ctrl-C/Ctrl-V support, and more, thanks to Clink. Though the Ctrl-R/Ctrl-S history manipulation commands don’t work with cmd.exe, but they do work with Powershell. Now I can’t get Cmder with Powershell to launch within PhpStorm, which sounds like the epitome of a First World Problem. Cmder, you get to live as your own separate window.

cmder-historyPro-tip: you can hashtag commands you want to re-use, then search these tags back and force with Ctrl-R/Ctrl-S. This persists through sessions too. Again, provided you use PowerShell.

Also, click on BufferHeight mode at the bottom right of Cmder or you won’t be able to scroll back. And notice the convenient search box in that same area.


An alternative to running Cmder within PhpStorm looks somewhat like the reverse, in that you can “attach” PhpStorm from Cmder/ConEmu, which makes the former a tab within the latter. I dabbled with that and found it wonky, your mileage may vary. Again, we’re starting to delve into acute configuritis at this point.

Up/down arrow keys don’t work in bash on Windows. A workaround was added to ConEmu, but Docker for Windows was getting in the way.  This was resolved as of Docker 1.12.3, which in combo with Cmder now has bash history, with persistence across sessions.

If your backspace key prints unexpected characters instead of doing what it’s supposed to, bash into your container and type (in my case backspace would issue a Ctrl+H sequence, you might need to edit the string after “erase”):

stty erase ^H

1.3. Node.js and NPM

I’m not one of the cool kids so I’m still using client-side JS/Jquery like it’s 2014 (along with 70+% of the web’s top sites), but I still need Node for Bower and Gulp (package managers to install package managers to install…). PhpStorm got you covered:

Enable NPM in SettingsEnable NPM in Settings

Node packages galore

Node packages galore

Here I’m installing the Uglify module with –save-dev, which will update  package.json:

Install from NPM repo

Install from NPM repo – wait I meant gulp-uglify, Well, this is easy to correct.

1.4. Orchestration Tools, from backend to frontend

We can tie our meta-tools together within PhpStorm, though if you’re using Docker and Windows, you’ll need to work a bit for it.

We just reviewed the Node prerequisite for the best-known package managers and task runners. Meanwhile, to work with PhpStorm, Composer and WP CLI need a PHP engine running either in the host or remotely – a feature which comes with native support for Vagrant but not Docker as of v2016.2 (though that is coming with 2016.3). Install PHP on Windows, or if you really want your remote interpreter, see:

1.4.1. Composer (PHP and WP dependencies)

See Composer Dependency Manager and Working with composer.json in PhpStorm.  By the way, don’t Confuse Composer with Docker Compose!

Here are Composer dependencies, retrievable from Packagist directly in the PhpStorm UI (you can see it recognizes and checks dependencies from my existing composer.json file):

Add Composer dependencies

There’s a third-party plugin that adds composer.json autocompletion and inspection, and it now supports custom repositories such as WPackagist. Here again, you’ll need to install a local PHP interpreter, remote ones are not supported despite popular demand. This gives you autocomplete from Packagist as illustrated below.

Incidentally in this screenshot you see WordPress set as a Composer dependency, which is how I currently pull WP and run it in its own directory. I used to have WP as a Git submodule for years, and even briefly tried WP as its own Docker container.

My life is auto-complete

My life is auto-complete

1.4.2. Bower (JS Dependencies)

See Bower Package Manager and PhpStorm gets Bower support. Bower dependencies are listed under Settings like NPM modules, with online checking of the latest version numbers:

Installing a package looks very similar to what we’ve seen earlier with NPM. Don’t you love consistency?

Querying the Bower registry

Querying the Bower registry – wait, it’s been 4 days, no support for Yarn yet?

Here’s the output of bower list from the integrated terminal:

Bower list, from the terminal

Bower list, from the terminal

1.4.3. Gulp/Grunt (Do You Like Infinifactory?)

In the screenshot below the JetBrains IDE 1) lets me edit a Gruntfile or Gulpfile, 2) parses it and automatically list the tasks registered in it, 3) lets me point and click to run any of these tasks, 4) show the output in a console. Pretty sweet huh? It is actually a much more functional outcome than the sparse – even cryptic – interaction with Grulp that I’d get through Docker Compose and command line instructions.

phpstorm + grunt

Powerful Grunt integration – Looks the same with Gulp

Thanks to the underlying NPM support, you get autocomplete for your installed packages when you edit gulpfile.js:

Gulp plugins from your installed NPM packages

Gulp plugins from your installed Node packages

You can also debug these tasks since, after all, this is javascript:

Boo: sloppy!

Boo: sloppy!

1.4.4. PhpStorm + Gulp + Bower + Composer + Docker, Because You Can

Screenshot or it didn't happen

Screenshot or it didn’t happen

Now, while you can interact independently with Composer, Bower, and Gulp, I try to get the most out of the latter. This means I install/update Composer and Bower dependencies using Gulp with gulp-bower and gulp-composer (who would have thought?).

Windows doesn’t know what to do with .phar files so make sure to create a composer.bat file as per the Composer documentation. Otherwise Gulp-Composer won’t be able to launch Composer, nor will you be able to manually interact with Composer from the command line. You’ll also need to use the bin: setting in your gulp-composer task to point to the path where composer.phar is located.





There is a Gulp-Docker package but it doesn’t parse Compose files, and defining containers in a Gulp task seems redundant. If what you want to accomplish is to make sure your containers are running before you launch Browser-Sync via Gulp (for example):

  1. external-tool-runCreate a bat file with “docker-compose up -d” in it.
  2. Point to it as an External Tool in PhpStorm
  3. Edit the Before Launch section of the Run/Debug configuration of your Browser-Sync Gulp task

You could even start Docker for Windows that way. I don’t because I already start Docker when Windows launches.

I’ve made a simple batch file to check that everything is properly installed and display tool versions. In this screenshot I execute it via Launchy passing along command line instructions to Cmder:


It’s really on top of Bower that Gulp pipelines will be most useful, as you’ll typically need to:

  1. Retrieve packages from Bower.
  2. Sort out exactly which files you’re interested in within these packages. Things such as folder layout and whether there are minified files vary from package to package. There’s also stuff such as readme files that you don’t want in your own project.
  3. Lint, concatenate, beautify, and add sourcemaps to have centralized CSS and JS files made of your imported libraries + your custom code. These are the files you’ll use for debugging, since they’re legible and code/design can be traced back to its source components.
  4. Then uglify production-ready versions of these same files (no need for sourcemaps there, unless you want to do some debugging in production).

Behind the scenes, each tool retrieves images from a central public repository, sometimes complemented by private ones:

  • Docker -> Docker Hub
  • Composer -> Packagist, WPackagist
  • Bower ->
  • Gulp -> NPM

See for module meta-search.

If my screenshots are not enough, watch the following video about Gulp integration. PhpStorm is a super-set of WebStorm so this applies to both:

1.5. Databases

Since I explained in my Docker for Windows tutorial how to connect to your database container, here’s what it looks like:

1. SQL connections. 2. connection settings to Docker container. 3. SQL console. 4. Query result.

1. SQL connections. 2. connection settings to Docker container. 3. SQL console. 4. Query result.

Make sure to use the Synchronize command to retrieve the database’s structure and thus enable auto-completion:


Now the IDE knows what’s in there

For the record, at the end of 2015 JetBrains launched DataGrip – a competitor to the likes of SQLYog or HeidiSQL – but it’s nice to be able to do database work right from the IDE. Database tools in PhpStorm are functionally equivalent to what’s in DataGrip.

1.6. Web Servers

There are plugins to support Nginx and Apache config (.htaccess).

1.7. CSS Preprocessors & Frameworks

PhpStorm comes with native support for SASS, SCSS, and LESS. Myself I use Gulp for that type of task.

Bootstrap  3 live templates are available through a plugin, there’s one for Zurb Foundation 6 too.

1.8. Version Control

Git as well as Github support come natively, with a plugin available for .ignore files. BitBucket, which I use because it has free private repos unlike Github, requires a plugin.

There’s also support for SVN though I personally haven’t used it in years.

Use Annotations to get the equivalent of git blame in the left gutter. From there you can see what granular changes amount to, roll them back, or open a separate window dedicated to showing differences between two files (or in this case, two versions of the same file).



Show Diff

Show Diff

In 2014 JetBrains introduced Upsource, a code review and a repository browser. It runs with a local web server  and integrates with the IDE via a plugin.

1.9. Frameworks & CMS

1.9.1. WordPress

See WordPress Development using PhpStorm, which covers most needs. The people at JetBrains are pretty thorough and they included support for WP-CLI, but I found plenty of caveats with my Windows/Docker environment.

You can install WP-CLI on Windows using the .phar file and a .bat file just like we did earlier for Composer, or you can install it globally using Composer. In the latter case, you might as well install the psysh console/debugger/REPL. WP-CLI will then use psysh when you type wp shell after bashing into your container (See the Terminal section earlier in this entry). See:

Note that psysh’s tab completion (for variable names, functions, classes, methods, properties, and files) needs Readline or Libedit in your PHP. The Readline extension is not available on Windows. You could presumably compile your own PHP with libedit support, though that’s a lot of work just for this. Anyway your PHP/WP CLI experience is not going to be optimal, but it sort of works.


Unfortunately, going back to PhpStorm, it relies on a local install and is not aware of my Docker container setup where the database is located. Other people pointed out that remote CLI support would be nice.


WP CLI within PhpStorm with auto complete – Works with a local serverunr

Alternatively you can use a Docker image that includes WP-CLI, in which case you’ll have to bash into the container and won’t benefit from auto-complete unless you set that up explicitly (see Tab Completions here).

WP CLI within Docker

WP CLI within Docker

Finally, here’s a tease screenshot that should get you to keep reading in case you’re not yet using Xdebug:

You don't need to guess what's in the WordPress Loop

You don’t need to guess what’s in the WordPress Loop

1.9.2. Others

There’s similar support for Drupal, Laravel, and possibly others. However I’m not going to develop this part of the entry because I’m usually working with WP.

2. Debugging, Previewing, Testing

2.1. PHP Debugging

2.1.1. Options & Moving Parts

Here’s an outline to wrap our head around the many debugging options:

My first instinct was to use debugging with a remote PHP interpreter. It turns out doing so with PHP running in a Docker container is cutting edge and won’t be officially supported until 2016.3, which is in early access program as I’m writing this. There’s a workaround method for 2016.2 which wouldn’t work for me, so I installed 2016.3 EAP and struggled for days before finally prevailing.

In the end, here’s what worked for me:

  • No interpreter, Remote Interpreter, and Local Interpreter all worked once I had sorted out the proper host and mapping. In hindsight it looks trivial, but you wouldn’t imagine the nooks and crannies I went through to sort it out. I haven’t tested this thoroughly, but it feels like Local Interpreter may have a performance edge.
  • xdebug.remote_host = (my host’s LAN IP – find yours with ipconfig from the Windows prompt), not, not localhost, not
  • A single mapping between the local web directory and /var/www/project/web on the server. This is for the Bedrock WP project structure.

If you’re fighting with this, these may help:



The drawback of PhpStorm’s power and feature wealth is its sprawling option screens. They’re easy to navigate and search, but when you’re talking PHP + Debug + Docker + WordPress, there’s a dozen screens involved, often with overlapping concepts and settings such as mappings and ports.

Interpret this. Or not.


narrow-scope2.1.2. Scoping What Gets Debugged

If you do stick to your PhpStorm debugging guns, it will come handy to block debugging feedback about code that’s not yours. There are several possibilities:

2.1.3. Too Complicated?

If this all looks too daunting, a quick-and-dirty alternative that still beats var_dump may be found with: Debugging PHP Code with FirePHP (Chrome extension).

2.2. Javascript Debugging

PhpStorm relies on a Chrome extension to receive JS debug information back from the browser. Note that you need to close Chrome DevTools before launching a PhpStorm JS debug session. For details, see my entry on PhpStorm + Browser dev tools.

Add a console.log statement in your javascript, put a break point after it, launch your debug session, and if everything is working you should see the console message in PhpStorm:


Yes we can

Here’s a video tutorial:

Here too there’s a quick-and-dirty alternative, with Chrome Logger.

2.3. Browser Auto Refresh with Edit Roundtrips Between IDE and Browser

2.3.1. PhpStorm Live Edit

PhpStorm comes with a Live Edit plugin to instantly preview HTML, CSS, and JavaScript files, using its own web server. It has its place for lightweight prototyping and testing, in the way you’d use a code playground such as JSfiddle or Codepen. If you have enough screen real estate, you can separate the debugging tools in their own windows and arrange them so that you can live edit your code, see it running in the browser, and get debugging output (rendered page structure and content, variables, watches, console). Each tab within the editor can also be dragged and dropped outside of the main PhpStorm window so you can stretch and separate things into a 3rd monitor if you want to.

Tool Sprawl

Tool Sprawl – here on two monitors

2.3.2. BrowserSync via Gulp

Alternatively you can use BrowserSync with a task runner (Grunt, Gulp), which is how I personally roll for full-fledged projects. BrowserSync comes with a ghost mode and support for remote debugging with Winre (see this video), the sum of which looks pretty close to the sort of synchronized cross-device mobile testing that Ghostlab offers.

When I make an edit to the LESS file I use to customize/override Bootstrap and save it (Ctrl+S), Gulp catches the update and compiles LESS to CSS, a second or two later my browser shows the update without having to hit refresh. It’s not a full refresh either, only the CSS file is streamed and injected, so the browser doesn’t blink through a blank page. Smooooth.

Add watches on your JS and PHP source files, and never manually refresh your test/dev browser again. Of course in the case of PHP changes there will be a full page refresh.

A note for Docker users: gulp watch processes don’t seem to work with mounted volumes, i.e. file changes don’t get picked up. I tried, gulp-watch, neither would pick up changes, so instead use the files: section of your browserSync task.

2.3.3. Roundtrips with the Browser

If you squint just right, you can not only automatically push changes made in PhpStorm to the browser, but also save changes made in the browser back to your source files. This involves lots of moving parts though, so this section became too long and became its own entry on browser dev tools and addons.

Since we’re focused on optimizing our full-stack workflow, note that you can debug PHP while using BrowserSync, and you can debug PHP and JavaScript code at the same time.

2.4. Testing

Section to be developed. See:

2.5. Code Hygiene & Refactoring

2.5.1. Looking for Duplicate Content

Install PHP Copy/Paste Detector (PHPCPD)‘s phar/bat file the same way we’ve installed Composer and WP-CLI before, then set it up as an external tool with macros (in this context, this means variables) rather than hard-coded paths, so it will work across your projects:

App launcher

App launcher

Then Ctrl+Shift A, type “external tools” (or mouse to the Tools menu), select PHPCDP, you’ll get the result in PhpStorm’s Run window:

De-dupe this

De-dupe this

2.5.2. Refactoring

Section to be developed. See Refactoring Source Code.

3. Other Goodies

 3.1. RegexpTester

This plugin adds a mini RegexBuddy to the IDE.


3.2. Structured and Visual Navigation

PhpStorm’s UI always helps you know where you are and navigate around your project easily and quickly. See here the Structure pane listing a linked outline of functions within a longish php page, a visual cue in the margin of the main window showing the function’s span, and a minimap a la Sublime on the right (plugin).

Structural outline > zoom into code > zoom out to minimap

Structural outline > zoom into code > zoom out to minimap

And if you’re looking at the physical layout of your project, both the Project sidebar and top navigation bar (Alt+Home) have a solid feel to them. You’ll like this If you’re the type of person to replace Windows Explorer with Directory Opus or Xplorer2.

Sehr strukturiert, Herr JetBrains

Sehr strukturiert, Herr JetBrains

3.3. External Tools

We’ve used this as explained above to set up PHPCPD or launch Docker containers. Here’s a more detailed tutorial.

3.4. Interface Automation

3.4.1. Macros

PhpStorm has macros, though don’t expect the full power from, say, Microsoft Office VBA. Mouse presses are ignored, the documentation is pretty limited, and if there’s a way to use variables in macros, it’s well hidden. I tried to put the launch of a specific Gulp task into a macro, and all the recorder shows is a generic RunJsbtTask action.

Moreover, you can’t add a macro to a Run Configuration, so the potential for automation from within PhpStorm is limited. I filed a feature request, and I should mention that I found the Jetbrains folks very responsive in my interactions with them.

Don’t be confused by the fact that PhpStorm also use the “macro” word to refer to variables that you can use to customize how you launch External Tools.

3.4.2. Live Templates

The other feature meant to cut time spent typing is Live Templates, i.e. “frequently-used or custom code constructs.” I haven’t used this yet.

3.5. Other Stuff to come

I will keep updating this entry as I dive deeper into PhpStorm’s capabilities, and I feel I’ve only scratched the surface. Eventually I hope to get around to using and properly documenting:

  • Linting/code checking LESS/CSS, JS and PHP, using PhpStorm and/or Gulp
  • (Unit) testing
  • Profiling
  • Refactoring
  • Documentation
  • Issue management
  • Deployment

You can always check out the plugin directory to find something that works with your own environment.

With my triple screen setup, I can have PhpStorm with all the integrations listed above in (docked or floating) windows, ConEmu, a couple browser windows with dev tools, and a reference book or web page all neatly visible at the same time.

When all of that stuff is up and running:

4. Limitations

PhpStorm does a lot, but not everything just yet. Here’s a small list of the things I’ve been looking into that don’t exist:

5. Summary: Re-Creating a Project From Scratch

5.1. From Boot to Dev

If I need to reinstall a whole project from scratch, it looks roughly like this:

  1. Pull my project/theme from Bitbucket.
  2. Launch my Docker containers.
  3. Import a MySQL dump.
  4. Copy media assets.
  5. Launch a few Gulp commands.
  6. Fully working website running locally and ready to be debugged.

Step 3 can be done via your Docker-compose file (example) or a SQL command.

Step 4 is still a manual process for me, I’ll have to automate/manage that at some point, maybe with a WP plugin and some cloud hosting.

Step 5 should be reduced to a single Gulp master task once Gulp 4 is out of beta (watch Github releases) which will improve task dependencies and executing ordering. Gulp takes care of retrieving PHP libraries (including WordPress and plugins), JS libraries, fonts, CSS, and meshing that with my own code to build an entire production-ready site, while I don’t have to commit any externals in my own source repository.

So I’m not quite pushing a single button just yet to get the whole thing going, but I’d say it’s pretty streamlined and clean.

5.2. Essential Dev Software

And if I were to start on a brand new machine, I’d install and configure the following development suite:

  • Docker for Windows
  • PhpStorm
  • Git for Windows
  • Node, Bower, Gulp, Gulp project dependencies
  • PHP, Composer, WP-CLI
  • Chrome Canary + extensions
  • Firefox Developer Edition + extensions
  • Kitematic
  • Cmder
  • Notepad++
  • SourceTree or GitKraken
  • Fiddler

From my experience, the worst in the lot is installing NPM dependencies, sometimes it borks for obscure reasons (“unmet dependencies” and similar-sounding bullshit) which may require you to delete node_modules and restart. This can be sloooow.

Sometime in 2017 I plan to build a new PC with Unraid, which would combine native Docker support with Windows as a VM, but at bare metal performance levels thanks to PCI pass-through. Exciting stuff!

6. More resources

7. Notepad++

I’m not going to write a whole post just about this editor, but I do recommend using it when you need more lightweight work done because it’s so fast. I made it my default editor for a variety of file extensions and removed the default Notepad in my shortcuts so they don’t compete in Launchy.

I run PhpStorm and Notepad++ at the same time. using the latter for things such as conf, ini, or log files, or for a quick edit.

A couple pointers:

Pretty Huge PhpStorm

Pretty Huge PhpStorm – This monstruosity is Actually A Thing

Leave a Reply

Your email address will not be published. Required fields are marked *