Kirby, Apache, and PHP on Windows
I have finally cobbled together a native Windows development environment. This time—due to restrictions on access placed on the work computer, as well as donkiness from the Microsoft Store—I’ve circumvented the Windows Subsystem for Linux route I used to use.
I also like the command line more than MSIs or installer bundles. Deleting directories is easier to me than digging around in Control Panel’s uninstallers and keeping your fingers crossed.
Install the package manager
The first step is grabbing Scoop, a Windows package manager. It doesn’t have the reach of Homebrew, but their operations are very similar. Scoop requires at least version 5 of PowerShell, and you don’t have to run as administrator.
Where Scoop falls down in comparison to Brew (again, besides the range of packages available) is that it relies on Git for maintaining manifests, but doesn’t install Git itself. So, you need Git to update Scoop, but Scoop doesn’t install Git. Type this instead:
scoop install git
scoop bucket add extras
scoop update
Git will install 7Zip as a dependency. Scoop uses “bucket” as nomenclature for bundles of packages. Then the update process will grab the most recent manifests for the main
bucket as well as the extras
bucket we just added.
Install PHP
I’m only interested in PHP 8.0, so I don’t need the versions
bucket that would let me install other releases. scoop install php
will do the magic here.
Again—and I’m going to keep pointing out where Homebrew does things, because I primarily use macOS and Homebrew is fantastic—Scoop uses symlinks for configuration directories. As long as you place your configuration files in the appropriate place, they won’t be overwritten by version changes.
For PHP, you’ll want to make edits only in ~/scoop/apps/php/current/cli
. You can either edit php.ini directly or add custom .ini files into conf.d.
In the extensions section of php.ini, you need to explicitly set
extension_dir=c:\Users\[user]\scoop\apps\php\current\ext
The php.ini file will accept Windows-style paths.
Activate the curl, gd, fileinfo, and mbstring extensions. If you’re going to use a database, activate the appropriate extension. Since I’m using Kirby, a flat-file CMS, I haven’t bothered.
php —m
at the command line will show you what modules you have installed for CLI PHP.
Save the file, and restart PowerShell. Since we need Composer for Kirby installation and maintenance, run scoop install composer
. To confirm your PHP’s set up correctly, run
composer create-project getkirby/plainkit
in whatever your project directory is. If you need another extension enabled, Composer will error out and let you know in the terminal. Just uncomment the correct extension and try again.
Apache
This is the configuration that took some doing. There were a lot of HTML 500 error codes until I managed to zero in on the Apache configuration responsible for pulling configuration in from the custom php.ini files we set up earlier.
First, scoop install apache
. If you’re going to run Apache as a service—which is useful, if you don’t want to keep a terminal window open constantly—then scoop install sudo
as well. The sudo utility acts like the Unix version, elevating privileges for a single command.
sudo httpd -k install -n apache
creates a Windows service named apache, and then you can you can adjust the service with
sudo net start|stop apache
Scoop symlinks Apache configuration into
~/scoop/apps/apache/current/conf
Open httpd.conf and adjust ServerName
to localhost
and DocumentRoot
to whatever folder you’re using. Apache won’t accept Windows-style paths, so make sure to use forward slashes and Unix-style pathing.
In the LoadModules
section, activate mod_filter
, mod_rewrite
, and mod_vhost
. At the bottom of the directives, add the following:
LoadModule php_module c:/Users/[user]/scoop/apps/php/current/php8apache2_4.dll
Note that in PHP 8, there’s no version number in php_module
.
You need to add SetHandler
and ApplicationType
directives, but the crucial discovery is to explicitly set the PHPIniDir
directive to the current
symlink in Scoop.
You’ll want to uncomment the
loadconf httpd/extra/vhosts.conf
directive and add VirtualHost information to extra/vhosts.conf
. I use .test domains, so I add the following to c:\Windows\system32\drivers\hosts
:
127.0.0.1 domain.tests
Why is that important?
If you don’t set PHPIniDir
, no matter how many times you restart Apache or adjust php.ini, the server’s never going to pick up those changes.
Testing adjustments to php.ini is as easy as creating a PHP file in your document root. Add <?php phpinfo();
and load the file in your browser. If you see a blank line for the configuration directory, Apache’s looking in the wrong place for your php.ini.
Caveats and tips
- Don’t adjust php.ini and also create a custom.ini file. Keep your changes in one place.
- Once you’ve gotten things working, add the
~/scoop/persist
directory to version control. - Don’t activate extensions you don’t need, either in Apache or PHP.
httpd -t
will test your configuration files at the command line. It will also stop parsing at the first error, so expect to use it a lot.- If the test flag still can’t help you—like the HTTP 500 codes I got despite Apache CLI telling me syntax was fine—check the logs.
- Check, double-check, and triple-check your paths. PHP can use Windows-style, Apache requires Unix-style, and add trailing slashes for directories.
June 29th, 2021 #development #programming