Woah! I switched to Windows and it’s awesome for PHP development.

After twenty-two years as a Mac user, I switched to Windows 10. I was motivated by excellent hardware that became available (the Dell XPS 15 specifically). Macbook Pros had remained stagnant for years and I wanted a larger, better screen. I do a lot of photography, so 4k and the Adobe RGB colorspace were quite compelling!

While I was excited for the hardware, I was nervous about the OS. I had played with Windows in the past and was always underwhelmed. I was scared my web development productivity would plummet, and I dreaded losing important software. It turns out I was wrong. My web development workflow on Windows 10 is as productive as it was on OS X, and I continue enjoying the same software to develop PHP on Windows.

I tell this story to my fellow PHP developers, and they look at me like I’m crazy. Just a few years ago I would have agreed with them—maybe even a few months ago! However, I must commend Microsoft for its progress on Windows 10. I find Windows 10’s aesthetics simple and well-designed. Windows 10 is stable with the “Threshold 2” update. And my new Dell XPS 15 Core i7 Skylake laptop is powerful and packed with pixels. I am happy with Windows 10. Perhaps most interestingly, based on my own experience, the difference between OS X and Windows continues to shrink. Both borrow good ideas from one another, and more and more software is cross-platform or web-based.

This post covers what I learned during the transition from OS X to Windows 10 that is relevant to PHP developers. It turns out there isn’t much to relearn, and you don’t even lose the command line!

My Software Runs on Windows

It is paramount that my PHP development software runs on Windows. I also want the transition from OS X to Windows 10 to be seamless. I am happy to report that all of my PHP development software does, in fact, run on Windows 10, including:

This list should be familiar because it is the same software I used to develop PHP on OS X.

First a Note: It’s a Best Practice to Virtualize

It’s important to emphasize that I heavily rely on Vagrant virtual machines to preview my local applications through an environment that matches their production servers. I would do this even if I developed in Linux. A development machine is never going to exactly match a production machine the same way a scripted Virtual Machine can. It is silly to not virtualize production environments regardless of your local OS. Windows, OS X, and even Linux users should all use a virtual machine to preview local applications and avoid software discrepancies with production servers.

So when evaluating a development OS, the only consideration is the development experience. This post demonstrates that Windows 10 is finally a capable platform for PHP development. Whether you are building custom applications or contributing to your favorite open source projects, Windows 10 is finally a sane choice as a modern PHP development platform. What follows is a collection of what I’ve installed to get going on my Windows development machine.

PHP 7.0 Runs on Windows

The PHP internals team provides pre-compiled PHP binaries for Windows. These binaries are available to download at http://windows.php.net/download/ for both 32-bit and 64-bit operating systems. I use the 64-bit (non-thread-safe) PHP 7.0 build for Windows 10.

The thread-safe builds are intended for PHP developers running a local Apache web server. The non-thread-safe builds are intended for PHP developers running a local IIS web server. I do not run Apache or IIS. Instead, I use PHP’s built-in web server or a Vagrant virtual machine when developing applications on my own computer.

It is important to download and install the Visual C++ Redistributable that complements the selected PHP binary. I use the x64 VC14 C++ Redistributable required by the PHP 7.0 binary.

The PHP pre-compiled binary is a ZIP archive. I extract it to C:\Users\josh\Apps\php7.0\ on my computer, and I add that directory to the system PATH environment variable.

I recommend the following changes to the php.ini file located immediately beneath the PHP install directory.

First, I uncomment the extension_dir directive. The resulting line reads:

extension_dir = “ext”

Next, I locate the section named “Dynamic Extensions” and uncomment most of the included PHP extensions. My php.ini file uses these dynamic extensions:

extension=php_bz2.dll
extension=php_curl.dll
extension=php_fileinfo.dll
extension=php_gd2.dll
extension=php_intl.dll
extension=php_mbstring.dll
extension=php_exif.dll
extension=php_openssl.dll
extension=php_pdo_mysql.dll
extension=php_pdo_sqlite.dll

Xdebug Runs on Windows

Derick Rethans provides a pre-compiled Xdebug binary for Windows at http://xdebug.org/download.php. I move the downloaded .dll PHP extension into the C:\Users\josh\Apps\php7.0\ext\ directory, and I append this text to my php.ini file:

[xdebug]
zend_extension = php_xdebug-2.4.0rc2-7.0-vc14-nts-x86_64.dll
xdebug.default_enable = 1
xdebug.scream = 1
xdebug.coverage_enable = 1
xdebug.profiler_enable = 0
xdebug.profiler_enable_trigger = 1
xdebug.profiler_output_dir = "C:\Users\josh\Apps\php7.0\profiles"
xdebug.remote_enable = 1
xdebug.remote_host=127.0.0.1
xdebug.remote_port = 9000

The zend_extension value must be the exact filename of the .dll file. This name may vary depending on the specific Xdebug build.

The second line, xdebug.default_enable, activates Xdebug  by default.

The xdebug.scream directive instructs Xdebug to ignore the @ suppression operator.

The xdebug.coverage_enable directive activates Xdebug’s code coverage feature that often complements PHPUnit tests.

The xdebug.profiler_enable directive disables Xdebug’s profiler feature by default since it consumes a lot of system resources and disk space on every PHP run.

The xdebug.profiler_enable_trigger directive, however, lets me selectively activate Xdebug’s profiler by passing the ?XDEBUG_PROFILE=1 query parameter to a PHP script.

The xdebug.profiler_output_dir is the path to a directory in which Xdebug stores profiler output data. Profiler data can consume a lot of disk space.

The xdebug.remote_enable directive activates Xdebug’s remote debugging features.

The xdebug.remote_host and xdebug.remote_port directives tell Xdebug the host and port to which Xdebug sends debugger information. The PHPStorm IDE listens on 127.0.0.1:9000 for inbound Xdebug debugger information.

PHPStorm Runs on Windows

I use PHPStorm with PHP 7.0 and Xdebug. PHPStorm is a popular integrated development environment (IDE). It is commercial software availble via subscription at https://www.jetbrains.com/phpstorm/.

PHPStorm website with @codeguy testimonial

I never appreciated PHPStorm until I did most menial development tasks by hand. Only then did I learn to love PHPStorm. There is comfort and simplicity in its perceptually complex user interface. I won’t go into the details; PHPStorm’s features are listed on its website. I do, however, appreciate PHPStorm’s support for PHPUnit, Xdebug profiling, Xdebug code coverage, Composer, and PHP Code-Sniffer.

To configure a new PHP 7.0 interpreter in PHPStorm, I open PHPStorm's settings window (Ctrl+Alt+s) and navigate to Languages & Frameworks > PHP and click the button located to the right of the Interpreter dropdown.

PHPStorm PHP interpreter

In the subsequent window, I click the button to the right of the PHP executable text field and select the C:\Users\josh\Apps\php7.0\php.exe executable file beneath the PHP install directory. PHPStorm automatically finds and reads the php.ini file. PHPStorm also recognizes the Xdebug extension.

PHPStorm PHP interpreter

Finally, I navigate to Languages & Frameworks > PHP > Debug to ensure the Xdebug Can accept external connections checkbox is checked and the Debug port value is 9000. These settings tell PHPStorm to listen for inbound Xdebug debugger data on 127.0.0.1:9000.

PHPStorm remote debugging setup

Composer Runs on Windows

Composer is a PHP dependency manager that is often attributed as the catalyst for the modern PHP renaissance. Composer changed how I develop PHP applications. It’s an invaluable tool that I use everyday.

Composer provides a native Windows installer on its website at https://getcomposer.org/download/. The installer puts the Composer binary in the C:\ProgramData\ComposerSetup\bin\ directory, and it puts global vendor packages into the C:\Users\josh\AppData\Roaming\Composer\vendor\bin\ directory.

After I add the C:\Users\josh\AppData\Roaming\Composer\vendor\bin\ directory to my system PATH environment variable, I can invoke any Composer-managed global binary in the command prompt.

Composer in the command prompt

PHPUnit Runs on Windows

PHPUnit runs on Windows, and it can be installed with Composer. I install PHPUnit with this command in the Windows command prompt:

   composer require global phpunit/phpunit

When Composer completes its installation, I can invoke PHPUnit on the command prompt:

phpunit

PHPUnit in the command prompt

In PHPStorm, I specify the path to the PHPUnit executable in the settings panel (Ctrl+Alt+s). I navigate to Languages & Frameworks > PHP > PHPUnit. I click the Path to phpunit.phar radio button and enter the C:\Users\josh\AppData\Roaming\Composer\vendor\bin\phpunit PHAR archive path in the Path to phpunit.phar text field.

PHPUnit in PHPStorm

PHP Code Sniffer Runs on Windows

PHP Code Sniffer provides code linting against the PSR-1 and PSR-2 code styles (among other features). PHPStorm uses PHP Code Sniffer to lint code in real-time with inline notifications of syntax and style mistakes.

I install PHP Code Sniffer with Composer.

composer require global squizlabs/php_codesniffer

When Composer completes its installation, I can invoke the phpcs binary on the command prompt:

phpcs --help

PHP Code Sniffer in the command prompt

In PHPStorm, I specify the path to the PHP Code Sniffer executable in the settings panel (Ctrl+Alt+s). In navigate to Languages & Frameworks > PHP > Code Sniffer. I click the ... button and, in the subsequent dialog, select the C:\Users\josh\AppData\Roaming\Composer\vendor\bin\phpcs.bat file for the PHP Code Sniffer (phpcs) path text field.

PHP Code Sniffer in PHPStorm

PHP Mess Detector Runs on Windows

PHP Mess Detector detects messy PHP code, including “unused variables, bugs, suboptimal code, or overcomplicated expressions” according to its website. PHPStorm uses PHP Mess Detector to lint code in real-time with inline notifications.

I install PHP Mess Detector with Composer.

composer require global phpmd/phpmd

When Composer completes its installation, I can invoke the phpmd binary on the command prompt:

phpmd --help

PHP Mess Detect in the command prompt

In PHPStorm, I specify the path to the PHP Mess Detector executable in the settings panel (Ctrl+Alt+s). I navigate to Languages & Frameworks > PHP > Mess Detector. I click the button to the right of the Configuration dropdown and, in the subsequent dialog, select the C:\Users\josh\AppData\Roaming\Composer\vendor\bin\phpmd.bat file in the PHP Mess Detector (phpmd) path text field.

PHP Mess Detector in PHPStorm

Git, Bash, and SSH Run on Windows

I admit that I miss a familiar bash shell and an underlying BSD subsystem. However, Git Bash is a competent bash substitute on Windows. Git Bash is a psuedo-bash shell on Windows that provides oft-used bash commands and transparently maps them to their DOS counterparts.

Git Bash, as its name suggests, also provides the Git version control system complemented by a built-in SSH client that operates exactly like it’s Unix-y brethren. The SSH client uses ~/.ssh/id_rsa and ~/.ssh/id_rsa.pub private and public SSH keys, and it uses a ~/.ssh/config file for SSH connection aliases.

Git Bash is available for download at https://git-scm.com/downloads.

Out of the box, Git Bash runs slower than I prefer because it customizes the command prompt color based on the current Git repository branch. This overhead slows Git Bash’s response time. Git Bash is fast again when I remove this line from the etc\profile.d\git-prompt.sh file beneath the Git Bash install directory:

PS1="$PS1"'`__git_ps1`'

As you can see in the screenshots above, I run Git Bash via Cmder, a Windows user interface that wraps nicely around Git Bash, the native Command Prompt, or PowerShell.

Windows, PHP, and Me

Many of my friends who use OS X and Linux carry negative preconceptions of Windows, especially with regards to PHP development. These were true. I recently switched to Windows 10 after twenty-two years with a Mac, and I believe these negative preconceptions of Windows are now false.

All of my software runs on Windows. I write PHP with a stellar IDE using the latest and greatest features available in PHP 7.0.

I also run Xdebug, the de facto PHP debugger and code profiler, to analyze and optimize my PHP code. I step-debug my code in PHPStorm when I run into otherwise tricky-to-diagnose issues with my PHP code.

I write PHPUnit tests and generate real-time code coverage statistics so I know which code is tested and which is not.

I use PHP Code Sniffer and PHP Mess Detector to ensure my code is efficient and adheres to PSR-1 and PSR-2 code styles.

I run all of these tools in a familiar bash-like terminal with Git and SSH not unlike my previous OS X development environment.

Yes, I was hesitant moving to Windows. My time developing PHP on Windows 10, however, is efficient, familiar, and productive. Windows 10 supports the tools I need to create and deploy modern PHP applications.

Comments

Will's avatar
Will
I used cygwin for years for a bash shell under unix but have now gone over to MobaXterm which has both a built in cygwin environment and excellent terminal emulation for ssh duties. It has it's own x display manager so you can run remote x windows app if you want too.
Nemanja's avatar
Nemanja
Very helpful article. Thank you so much!
Terry's avatar
Terry
10 bucks says that he'll be back to a mac by Easter ;)
Ben's avatar
Ben NMC team member
Great article! I'll definitely be trying out most of these tips, and I've already improved things on my work mac :) Thanks for taking the time to write it up
Mathew's avatar
Mathew
How have you gone with doing Docker dev on Windows? (I note your previous Docker posts).
The volumes in the docker-compose is a real problem and I'm wondering if you got it working.
Dũng Nguyễn (nhymxu)'s avatar
Dũng Nguyễn (nhymxu)
I prefer Open-server with multi PHP version, Apache version, Nginx and may module. Good enviroment.
Tomás's avatar
Tomás
There is a typo in the composer command, I believe it should be:

composer global require phpunit/phpunit
PK's avatar
PK
One thing that keeps me off Windows is quality of backup, on Mac I have backup that survived few computers and it's almost 8 years old, started from OSX 10.5, no plan to switch to Win until they upgrade quality of backup tool to match Time Machine.
Ab Carver Pro's avatar
Ab Carver Pro
If some one wants expert view regarding running a blog afterward i propose him/her to
pay a visit this website, Keep up the nice job.
Cathy Mayhue's avatar
Cathy Mayhue
I have always developed my PHP applications on windows since I started 12 years back. Initially installing it was really cumbersome as every thing had to be done manually right from installing APACHE, PHP and MySQL. But gradually installers like XAMPP and others made life of a PHP programmer on Windows very smooth.
Josh Lockhart's avatar
Josh Lockhart NMC team member
@Terry Still going strong with Windows :P

@Mathew I still rely on Vagrant for most of my day-to-day work. I experimented with Docker a while back, but still not comfortable enough to use it full time. Docker has improved drastically since I last used it though.

@Tomás Thanks! Will correct. Good catch.

@PK I use CrashPlan for incremental file backups and versioning. Works great.

Thanks for the comments everyone!
Craig's avatar
Craig
@PK - I'd disagree with the backup statement. Windows has had great backup options built in for years. Look in the control panel under backup and you will find 2 tools for this.

1. System Image Backup -> This will make a complete image of your machine to any drive or even network storage. If you need to reload your OS simply boot to the windows USB, select "recover from backup" and point it to your drive or network location of your backup image and it'll pull everything back the way you had it last.

2. File History -> Give it a list of folder you want it to monitor and tell it where you want it backed up to. It will keep a history of changes to all files within those folders and store them where you want, as frequently as you'd like.

I've personally used these tools for years. Using the system image backup tool I can complete a full system image reload over my network onto my machine (image size approximately 30-40GB) in under 10 minutes flat. Sub 10 minute recovery from any disaster is a nice thing to have.
Dave Stewart's avatar
Dave Stewart
Hi Josh,

I was a Windows user for 22 years, until I switched to OSX a couple of years ago, thinking it would help my overall web development pipeline, but now I spend so much time battling Apple's appalling window and file management, I'm very seriously considering switching back!

The one thing that would make me stay would be the Macbook's trackpad, but I hear the new precision trackpad on the XPS is a thing to behold.

Would you care to share your experience of using it, particularly on the road where you don't have the luxury of multiple screens, and perhaps using Windows 10's gestures?

Many thanks!
Dave

Leave a comment

Real Time Web Analytics