Setup Your Portable Dev Environment on Windows with PHP 8 & MySQL 8

With the first release candidate of PHP 8 out in the public our previous post about a dev environment based on PHP 7 and MySQL 5.7 (!) is officially outdated. It’s time to update your WAMP stack! As we are aiming at a portable development environment will won’t “install” the components in the usual way but put them together from ZIP versions and configure them all to work together nicely.

Starting with Apache

To host a PHP site we again use it as module in the Apache web server. As suggested by PHP developers first download the latest version of Apache from Unless there is a reason let’s say the 64 bit edition is the one to choose, compiled with Visual Studio 2019 (VS16).

Download Apache Web server

The downloaded archive contains a folder named Apache24, just extract all of its content to c:\wamp (We chose the name wamp as acronym for Windows-Apache-MySQL-PHP). After extraction the apache web server software our folder should look like this:

+- wamp
+- apache
+- all the apache stuff like bin, conf, etc...

For a properly working web server we need Microsofts “Visual C++ Redistributable for Visual Studio 2015–2019″ to be installed as runtime. See the instructions on the Apache Friends website. Grab a 64 bit copy from

Add PHP to the server

The release candidate of PHP for Windows is available There are multiple versions available — be sure to download a version that’s compatible with the former components: meaning a thread safe VC16 binary for 64 bit systems. The difference to Non Thread Safe binaries are explained in the left hand sidebar.

Once the download is done extract the contents of the archive to a php subdirectory of c:\wamp. And while we’re on it, add two more folders directly under c:\wamp: At first create a htdocs directory for all our website assets including PHP scripts and a tmp directory for temporary files like sessions. When you’re done our wamp directory has grown to:

+- wamp
+- apache
+- all the apache stuff like in, conf, etc...
+- htdocs (still empty)
+- php
+- all the php stuff like ext, extras and logs
+- tmp (still empty)

For now all files and folders are set. Time to configure the web server and PHP to play nicely together. We’ll use relative paths to create a portable installation. So you will be able to copy it to a different location on your hard drive or even a USB stick.

As usual let’s start with the file c:\wamp\php\php.ini. It’s not there yet but we have to make a copy of php.ini-development placed in the same location. First of all we configure the extensions. Search for “extension_dir“ and don’t be shocked to find more than one occurence. None of those occurences is active but commented out by default. Comments in the php.ini start with semicolon (;). Look for a the “; On windows:” right before the one of those extension_dir lines. Switch ; extension_dir = “ext” to extension_dir=“..\..\php\ext”
and please note: the semicolon at the beginning of the line has been removed to uncomment the declaration! The directory is defined relatively to the Apache configuration file httpd.conf. With the extension dir set up we can now activate available extensions by uncommenting its declarations.

Head over to a block of about 20 lines starting with ;extension=. Remove the leading semicolon of curl, mbstring, mysqli and sockets for now. Last but not least we define a directory for temporary files and session files. Assign “..\tmp” to both upload_tmp_dir as well as session.save_path. And don’t forget to uncomment the declarations as well.

The Apache web server main configuration canbe found at C:\wamp\apache\conf\httpd.conf. First of all we need to set the variable SRVROOT to a relative path. Several path configurations in the same file are based on that variable. Good for use it exists because in prior versions we had to set all those paths seperately. Search for “Define SRVROOT” in the configuration file. It is normally set to “C.\Apache24” or alike. Replace the complete line with Define SRVROOT “..".

Next configure the port the server should listen to. Its default is port 80 which is also the port your browser uses to access web servers on the internet. You can leave the default value when your port 80 is not in use by another application — some versions of Skye tend to use port 80. Search for the line “Listen 80” and change 80 to let’s say 81. It’s important to add the port number to local URLs in your browser like http://localhost:81/ and not use http://localhost/. Feel free to use any other free port instead, you often see 8000, 8080 or such in comparable cases.

Right after the port configuration in the configuration file you will find a list of LoadModule directives. By default PHP support is missing, so add another line with LoadModule php_module “../php/php8apache2_4.dll” at the end of the block. The path points at our php directory. Prior to PHP8 the module name contained the version number like php7_module. So adjust that when upgrading from our previous version.

Next look for a line starting with #ServerName. Completely replace it with the line ServerName localhost:81 (without the #) where the numeric port value matches the one you specified above when setting the Listen directive.

As we are setting up a development server you can gratn access to xour servers filesystem. Look out for a line Require all denied in a <Directory /> block and alter it to state Require all granted. Do not use this in production as it might be a security risk! Alongside the filesystem listing add PHP support to default pages for directory indexes. When you do not specify a file name when accessing a website, the server responds with the index.html file when possible. PHP programmers are used to supplying index.php file, so add this in the module dir_module. Look out for DirectoryIndex index.html and put index.php in the middle, leaving it at DirectoryIndex index.php index.html.

Furthermore link the correct mime type to the php file extension. In the block <IfModule mime_module> just add another line at the end — before the closing tag: AddType application/x-httpd-php .php.

Last but not least specify the location of the PHP ini file by putting the following line at the very end of the file: PHPIniDir ../php

Running tests

After all configuration is done, let’s test if all works: Open the command line (Win+R) and change the directory to the Apache binary folder older

cd c:\wamp\apache\bin



to get the server started. All is good when there is no subsequent output but the prompt stays silent. In case of any onscreen messages something is wrong -> Google is your friend while debugging. In some cases you will see no output but when your Apache does not serve the following PHP file, shut down the server using CTRL+C and see the error prompt. But let’s assume everything is fine. Create a new file named phpinfo.php within the htdocs directory with the following one-liner content:

<?php phpinfo(); ?>

Save the file, open up a browser window and head over to http://localhost:81. The following output should appear:

PHP 8 (RC) up and running

Notice the Version number on top! Your Apache runs PHP 8!!

What about the database?

MySQL runs seperately from the Apache server. The community edition of the database server is freely available at the MySQL Dev Site. In consistency with all other components download a 64 bit version which is the default by now. Choose the ZIP archive instead of the MSI installer as we want it to run as portable as the rest.

Although indicated you don’t have to register or login. An unobstrusive “No thanks, just start my download” link is situated further down the page. Once finished extract the contents of the downloaded archive to a mysql folder within c:\wamp. This is the final structure of our WAMP environment

+- wamp
+- apache
+- htdocs
+- mysql
+- php
+- tmp

There is no config file (formally named my-default.ini) in the mysql directory. MySQL will look for such files in various locations. Use the following application to know where:


The output contains a prioritized list of directories. When none of them contains a file named my.ini, create a new one in c:\wamp with the bare minimum content:

transaction_isolation = READ-COMMITTED

Alongside create a file named mysqld.bat in c:\wamp to start the database server later on. It only contains this line:

mysql\bin\mysqld.exe --defaults-extra-file="my.ini"

But one step after the other: The easiest way to initialize MySQL — before running it — is to change into the mysql folder and execute

bin\mysqld --initialize --console

During init the server creates a data directory (as direct subdirectory in c:\wamp\mysql\data) and populates the system database. It also creates a root account with a random yet expired password. The console output shows the default password (in a [Note] line), hence the — console option.

In case the data directory is not created where it belongs copy the wrongly created files to the right place an initialize again with basedir and datadir options set in the prompt.

bin\mysqld --initialize --basedir=c:\wamp\mysql --datadir=c:\wamp\mysql\data --console

After that you can start your server by invoking bin\mysqld or starting the mysqld.bat file created a moment ago, and connect using the root account (in another command line) and the default password.

bin\mysql -uroot -p

The thing is: you can’t do anything until you change the expired password. Fortunately this is a one-liner as well.

mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourPassword';

One more thing: the IDE

To begin coding, we recommend to use Visual Studio Code, which can be configured to run in Portable Mode as well. Just head over to and grab a 64 bit copy of the ZIP file. Extract it to c:\wamp\vscode — you might be tempted to use code as directory name but we think that’s misleading. So the final setup of out wamp directory looks like this:

+- wamp
+- apache
+- htdocs
+- mysql
+- php
+- tmp
+- vscode
+- my.ini
+- mysqld.bat

After extracting you just have to create a data folder within the vscode directory, next to the Code.exe. That’s it! When the data folder exists, the application will use it to store extensions, session data, and preferences there.

One step further is to disable the telemetry data sent to Microsoft. Open up VSCode, enter the Preferences > Settings. Search for the term “telemetry” and uncheck “Enable Crash Reporter” and “Enable Telemetry”.

That’s it.

Thanks for reading and have fun with your dev environment. Best way to stay tuned is following us on Twitter. Comments are very welcome.

The tech staff of OneBitAhead GmbH, putting the web stack to work. Here to discuss daily bits & bytes. #javascript #nodejs #webcomponents #rdbms #php

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store