A portable Apache HTTP for Windows

Creating a portable environment inside a thumb drive.

If you are currently using WAMP or XAMPP as your local development environment, you might think this post doesn't make sense since it is already available and ready to be used. Thinking that you don't need to setup everything, just open their own installers and your good to go.

But the problem, for me, is that they are not portable enough. Although XAMPP has a portable version for every new release, the XAMPP Team does not recommend altering any files under /conf directory. Another problem for the XAMPP Portable is that it doesn't support multiple PHP versions unlike WAMP does currently. This may be cumbersome if you are working on a new project on PHP 7 and needs also to maintain applications written in PHP 5.

Lastly, when updating XAMPP or WAMP we need to wait for the latest versions to be released and it may take time if you upgrade to an existing installation. I also found some applications, other than XAMPP and WAMP, that implemented the portability nicely but are using outdated versions of libraries.

So in this post, we will try to create a portable Apache HTTP server with PHP and MariaDB that should also meet the following requirements:

Prerequisites

Download the following files first from their respective download pages:

Regarding on what version to be downloaded in PHP, select the Thread Safe (TS) version since it will be installed to an Apache HTTP server. The details of it can be found here:

Since with mod_php, PHP gets loaded right into Apache, if Apache is going to handle concurrency using its Worker MPM (that is, using Threads) then PHP must be able to operate within this same multi-threaded environment -- meaning, PHP has to be thread-safe to be able to play ball correctly with Apache!

Also install the C++ Redistributable Visual Studio package as it was required by the Windows version of Apache HTTP server but it might be installed by default on most modern systems.

Apache HTTP server

Extract the contents of downloaded Apache HTTP Server (Apache24) to the chosen directory. In this example, the directory is D:\Workstation\Apache. Afterwards, secure a backup of httpd.conf from the conf directory and rename it as httpd.conf.bak. This is needed because it will be used as the original file and also as a backup file when modifying the mentioned file. After renaming, open the httpd.conf.bak file with the chosen text editor and do the following:

Find this chunk of comment (in the httpd.conf.bak file, it was in line 238):

#
# Note that from this point forward you must specifically allow
# particular features to be enabled - so if something's not working as
# you might expect, make sure that you have specifically enabled it
# below.
#

Below that line number, add the following lines:

AddHandler application/x-httpd-php .php
AddType application/x-httpd-php .php .html0
LoadModule PHP_MODULE

It should looked like this after the update:

#
# Note that from this point forward you must specifically allow
# particular features to be enabled - so if something's not working as
# you might expect, make sure that you have specifically enabled it
# below.
#

AddHandler application/x-httpd-php .php
AddType application/x-httpd-php .php .html0
LoadModule PHP_MODULE

PHP for Apache HTTP

To setup the PHP for Apache HTTP, create a directory named D:\Workstation\PHP\$VERSION wherein the $VERSION is the version of the downloaded PHP package. Then copy the contents of the downloaded files and paste it to the mentioned directory. Also in the same directory, copy php.ini-development and paste it as php.ini. Take note that this is also the same step to create multiple PHP versions to the development environment.

Running the server

To run the Apache HTTP server (httpd.exe) with the selected PHP version, create a script named as PHP_$VERSION.bat ($VERSION is a variable that is mentioned earlier) in the D:\Workstation\Binaries directory and paste the following code:

@ECHO OFF

CLS

SET DLL_NAME=php7apache2_4
SET MODULE_NAME=php7_module
SET VERSION_NUMBER=7.2.10

TITLE Apache HTTP Server v2.4.34

SET APPPATH=%CD:Binaries=Programs%
SET APACHE_DIR=%APPPATH%\Apache
SET PHP_DIR=%APPPATH%\PHP\%VERSION_NUMBER%
SET PHP_MODULE=%PHP_DIR%\%DLL_NAME%.dll
SET HTDOCS=%CD:Binaries=Cleopatra%\Apache

ECHO Updating httpd.conf configuration...

DEL "%APACHE_DIR%\conf\httpd.conf" >NUL
COPY "%APACHE_DIR%\conf\httpd.conf.bak" "%APACHE_DIR%\conf\httpd.conf" >NUL

fart -C -q "%APACHE_DIR%\conf\httpd.conf" "LoadModule PHP_MODULE" "LoadModule %MODULE_NAME% \"%PHP_MODULE:\=/%\""
fart -C -q "%APACHE_DIR%\conf\httpd.conf" "c:/Apache24" %APACHE_DIR:\=/%
fart -C -q "%APACHE_DIR%\conf\httpd.conf" "${SRVROOT}/htdocs" %HTDOCS:\=/%
fart -C -q "%APACHE_DIR%\conf\httpd.conf" "PHP_DIR" %PHP_DIR:\=/%

ECHO Running Apache HTTP Server (with PHP v%VERSION_NUMBER%)...

%APACHE_DIR%\bin\httpd.exe

After pasting, kindly take note the following variables:

Lastly, extract the contents of Find And Replace Text (FART) library to D:\Workstation\Binaries.

Testing the script

To test if the Apache HTTP server is running with PHP, open the recently created script PHP $VERSION.bat to run the Apache HTTP server. Next, open a web browser and type localhost in URL, it should return a text of It works! which means the setting up of Apache HTTP server is successful.

While to test if PHP is included in the script, create a new file named phpinfo.php in D:\Workstation\Apache\htdocs and enter the following code:

<?php phpinfo(); ?>

It should display the current PHP version and the modules that were installed.

NOTE: If the path for the HTDOCS is changed from the script, it should return the output of index.php or index.html of the specified directory.

Updating the "php.ini" file

It is also possible to edit the php.ini of the specified PHP version. Following the steps in copying httpd.conf, copy the php.ini file and paste it as php.ini.bak. To edit the configuration before running the Apache HTTP server, kindly paste the code below:

SET CAINFO=%PHP_DIR%\extras\ssl\cacert.pem

ECHO Updating php.ini configuration...

DEL "%PHP_DIR%\php.ini" >NUL
COPY "%PHP_DIR%\php.ini.bak" "%PHP_DIR%\php.ini" >NUL

fart -q "%PHP_DIR%\php.ini" ";curl.cainfo =" "curl.cainfo = \"%CAINFO%\""
fart -q "%PHP_DIR%\php.ini" "extension_dir = \"ext\"" "extension_dir = \"%PHP_DIR:\=/%/ext\""

In the example, the full path of the SSL certificate is being updated into php.ini. This is useful when running applications that requires an SSL certificate locally in order to work.

Running PHP in the terminal

To change the current PHP version being served in the command prompt, just paste the following code below after "Setting environment variables":

ECHO Setting environment variables...

rapidee -C -R PATH %APPPATH%\PHP\5.3.22\
rapidee -C -R PATH %APPPATH%\PHP\5.4.12\
rapidee -C -R PATH %APPPATH%\PHP\5.6.37\
rapidee -C -R PATH %APPPATH%\PHP\7.0.32\
rapidee -C -R PATH %APPPATH%\PHP\7.1.22\
rapidee -C -R PATH %APPPATH%\PHP\7.2.10\

rapidee -C -A PATH %APPPATH%\PHP\7.2.10\

In the example, other paths related to other available PHP versions (including the current one) are being removed and being replaced with the new PHP version path. To check if the PHP version is updated, kindly run php -v in the command prompt:

C:\Users\Rougin>php -v

PHP 7.2.10 (cli) (built: Sep 13 2018 00:48:27) ( ZTS MSVC15 (Visual C++ 2017) x64 )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Xdebug v2.6.1, Copyright (c) 2002-2018, by Derick Rethans

Regarding MySQL or MariaDB

The said applications were not really connected to the Apache HTTP server and can be ran separately. However, preparing this one is also straightforward:

Room for improvements

The preparation may not be perfect and might be improved more, but it gets the job done. Having total control of the applications used, being able to switch PHP versions and easily upgrade its versions with a simple copy and paste really defines its flexibility and portability. If given a time, I might create a simple desktop application based on the scripts written in this post.