Relocatable Apache & PHP7 on Windows

Creating a Relocatable Apache 2.4 with PHP 7.2

Several packaged versions of Apache and PHP (often bundled together with MariaDB or MySQL) are avail­able. You may, however, want more control, or to understand how to create your own version. This document describes the process to create a relocatable (portable) de­vel­op­ment environment with Apache and PHP.

REQUIREMENTS — You will need the following knowledge and/or functionality…
  • General Windows command-line experience. Administrator rights are not required.
  • Access to the internet for downloading files and 7-zip to extract them.

Introduction

Due to changes in the Visual C++ runtime library versions and structure, you must make sure that all the executables and DLLs you down­load are compiled with the same version of Visual C++. You can choose between VC++11 (came with Visual Studio 2012), and VC++14/15/16 (Visual Studio 2015/2017/2019 or Visual Studio Build Tools 2015/2017/2019).

Official PHP 7.3 compiled with VC++14, or VC++15 can be used, but must be com­pat­ib­le with the com­pi­ler used for Apache. VC++14 dlls are compatible with VC++15, and VC++16.

You also need to choose whether to use 32-bit (x86 / i686) or 64-bit (x64 / amd64) versions of everything — you can­not mix 32-bit and 64-bit ver­sions. This docu­ment will focus on 64-bit, but as long as you replace all 64-bit downloads with the corresponding 32-bit downloads, the instructions will remain the same.

In all cases, you will require the appropriate (VS2015/VS2017/VS2019) vcredist_x86/x64 re­dis­tri­bu­tab­le run­time li­bra­ry (VC_redist.x64.exe or VC_redist_x86.exe). This may already be installed on your system, but it will not cause problems if you try to re-install it.

In summary, we focus on: VC++16; Apache 2.4.39; PHP 7.3.6 — all 64-bit. Although PHP is compiled with VC++15, and Apache with VC++16, this will not be an issue.

Download Binaries

Create a directory anywhere, e.g. D:\rxapache. You can choose any name, but it should not contain spaces, to avoid potential issues. Subdirectories of this rxapache directory will contain the various components. We will refer to this directory as your rxapache dir­ec­tory (the rx is our convention for relocatable AKA “portable” applications).

Download & Unzip Apache

The recommended build of Apache for Windows can be found on Apache Lounge. Navigate to the VC16 Windows Binaries page, and download the Apache 2.4.39 64-bit binary (or newer version). You may also want to download the extra modules on the same page if you are familiar with them, but you do not need to. This setup does not require extra modules; you may need them for your own pur­poses, however.

Extract the down­loaded httpd-2.4.39-win64-VC15.zip file to the rxapache directory. Rename the resulting Apache24 directory to apa (we like 3-letter directory names). The ReadMe.txt and version files can be deleted if you so choose, but will not interfere in any way.

Apache Modules

Optional: For each additional module you want to use, extract the individual *.so file from each of the downloaded files to the apa\modules directory. Personally, we generally extract all of them, except for the mod_security *.so files. For those interested, the Apache Tomcat connector module is called mod_jk-1.2.26.

Download & Unzip PHP

Download the VC15 x64 Thread Safe, or newer 7.3.xx version, from the PHP 7.3 download page; then, create a php directory inside rxapache, and unzip the down­load­ed PHP file into this directory.

For PHP debugging, download the xdebug 2.7.2 extension. A later ver­sion may also work. Extract the XDebug-supplied php_xdebug.dll file, and op­tion­al­ly, the php_xdebug.pdb file, to the ext di­rec­to­ry, under the php di­rec­to­ry. In other words, in the D:\rxapache\php\ext\ di­rec­to­ry.

PHP Extensions

The ImageMagick extension, (imagick 3.4.4) can be useful. Download the Thread Safe VC15 x64 3.4.4 version. Copy all *.dll and *.pdb files (the *.pdb files are optional) to the php\ext directory inside rxapache. This extension requires dependencies, specifically, the ImageMagick 7 zip file. This can be used with­out PHP, so create an rxapache\utl directory, and under that, an imagick directory. Now extract the bin\* files from the ImageMagick zip file, to the imagick directory.

Several other PECL (PHP Extension Community Library) modules compiled for Windows are avail­able, but each will have separate, and potentially different, requirements.

PHP Manual

The PHP Manual can be down­load­ed in several formats, and is useful to include. We have chosen to download the Many HTML files version. Make the main web site directory called www under rxapache. Make another directory under www called php for miscellaneous PHP-related files. Extract the down­loaded php_manual.en.tar.gzip file contents to the php subdirectory under the www directory. Then, rename the ex­tract­ed di­rec­to­ry: php-chunked-xhtml, to doc, so that you now have: D:\rxapache\www\php\doc.

NOTEPHP Manual Alternatives

The PHP manual, once extracted, is quite big, so only download and extract it if you really need it. The CHM version of the help on the PHP Documentation page, is generally more convenient; plus it has an index, which makes for quick lookups. Another ex­cel­lent alternative is to use the Zeal offline documentation viewer; Zeal also offers a “portable” version.

If you followed all the above instructions, your directory structure should be as follows:

      d:\rxapache
      ├───apa
      │   ├───bin
      │   ├───cgi-bin
      │   ├───conf
      │   │   ├───extra
      ┆   ┆   ┆
      ├───log
      ├───php
      │   ├───dev
      │   ├───ext
      ┆   ┆   ┆
      ├───tmp
      ├───utl
      │   └───imagick
      └───www
          └───php
              └───doc
                  └───images

Configuration

Several configuration files must be edited. For PHP, this only involves one file, but for Apache, several files need to be modified (and an extra file for PHP created).

PHP Configuration

Inside the rxapache\php directory, you will find a php.ini-development file. Copy this to php.ini, and open in an editor.

The xdebug extension requires an absolute path. Just under the [PHP] tag in the php.ini file, add:

   zend_extension = "${rxPHP_BASE}\php\ext\php_xdebug.dll"

If you have a release or beta version, its name might be different, and you should change the above line accordingly.

Configure PHP to save its log file in the same directory as Apache's log files, relative to the httpd.exe process. Search for a commented line: ;error_log = …, then change it by removing the comment and change the value:

   error_log = "..\log\php_errors.log"

Save PHP session files in a tmp directory, relative to the rxapache directory.

   session.save_path = "${rxPHP_BASE}\tmp"

In order for PHP to display errors in HTML, and create references to functions locally, ensure the following three settings are enabled and set:

   html_errors = On
   docref_root = "/php/doc/"
   docref_ext = .html

NOTICEPHP Manual HTML Files

If you decided not to download and extract the PHP Manual as explained above, then you should omit setting the two docref… configuration variables.

If you want to use PHP to run a Wiki, like DokuWiki (see the DokuWiki recommendations), you may want to consider increasing some upload limits. Just reconsider these settings if you intend to use this for a public server.

   post_max_size = 32M
   file_uploads = On
   upload_max_size = 256M
   max_input_vars = 10000
   memory_limit = 128M

PHP does not seem to find extensions in the standard directory by default, so set it explicitly:

   extension_dir = "ext"

Enable the relevant extensions. The extensions required will depend on your personal preferences and intended use. We enabled the following extensions to ensure that we can use DokuWiki, or because we expect them to be useful for other purposes:

   extension=php_bz2.dll
   extension=php_curl.dll
   extension=php_fileinfo.dll
   extension=php_gd2.dll
   extension=php_openssl.dll
   extension=php_soap.dll
   extension=php_sockets.dll
   extension=php_sqlite3.dll
   extension=php_xmlrpc.dll

We have now finished the PHP configuration. We must still enable the Apache PHP module, but that is part of the Apache configuration below.

Apache Configuration

As with the PHP configuration, the settings described here are suitable for local development, and not necessarily for a public server.

In the rxapache\apa\conf\extra directory, create a httpd-php7.conf file to enable PHP7 as an Apache module. This must contain the following:

   LoadModule php7_module "../php/php7apache2_4.dll"
   AddType application/x-httpd-php-source .phps
   AddType application/x-httpd-php .php .php5 .php7 .phtml
   PHPIniDir "../php"

The default Apache configuration file is httpd.conf, inside the apa\conf directory. Open this file with an editor to modify some settings.

Apache determines many defaults from the ServerRoot setting. Although we can set it up on the command line as an argument to httpd.exe, it is easier to set it here:

   ServerRoot ${rxApa_BASE}/apa

Let Apache listen on all IPV4 addresses, and the chosen port. This is useful for the ServerName setting as well (although you can change it to your actual server name):

   Listen 0.0.0.0:${rxApa_PORT}
   Listen 127.0.0.1:${rxApa_PORT}
   ServerName 0.0.0.0:${rxApa_PORT}
   HostnameLookups Off

The DocumentRoot is the “main web site” directory, i.e., the directory you get with / in the URL. To allow for .htaccess files to over­ride settings, the AllowOverride must be set to All. The ExecCGI is not necessary if you do not intend to run CGI (.exe for example) pro­grams. It is not required for PHP.

   DocumentRoot "${rxApa_BASE}/www"
   <Directory "${rxApa_BASE/www">
      Options Indexes FollowSymLinks ExecCGI
      AllowOverride All
      Require all granted
   </Directory>

In the section starting with <IfModule mime_module>, add or enable (uncomment) the following:

   AddEncoding x-compress .Z
   AddEncoding x-gzip .gz .tgz

   AddType application/font-woff .woff
   AddType application/font-sfnt .ttf

   AddHandler cgi-script .cgi
   AddHandler cgi-script .exe
   AddHandler cgi-script .cmd
   AddHandler cgi-script .py
   AddHandler cgi-script .pl

   AddType text/html .shtml
   AddOutputFilter INCLUDES .shtml

Not all the above setting are mandatory, specifically:

For nice (fancy) directory listings, optionally include the autoindex module's configuration file. The httd-info.conf and httpd-manual.conf includes are also optional.

   Include conf/extra/httpd-autoindex.conf
   Include conf/extra/httpd-info.conf
   Include conf/extra/httpd-manual.conf
   Include conf/extra/httpd-default.conf
   <IfModule proxy_html_module>
      Include conf/extra/proxy-html.conf
   </IfModule>
   Include conf/extra/httpd-php7.conf

The default Apache modules are fine. As a minimum, you should enable the following extra modules:

   LoadModule rewrite_module modules/mod_rewrite.so
   LoadModule info_module modules/mod_info.so
   LoadModule status_module modules/mod_status.so

Manual & Status

References to manual in the httpd-manual.conf file, can be changed to a less generic name; we like: apache-manual. For consistency, the server-info and server-status names (only in the <Location…> tags), should be changed to apache-info and apache-status re­spec­tive­ly, in the httpd-info.conf file.

   # conf/extra/httpd-info.conf
   <Location /apache-status>
   <Location /apache-info>

The AliasMatch, and <Directory…> setting must be made relocateable:

   # conf/extra/httpd-manual.conf
   AliasMatch ^/apache-manual(…)?$ "${rxApa_BASE}/apa/manual$1"
   <Directory "${rxApa_BASE}/apa/manual">

       SetEnvIf Request_URI ^/apache-manual(…)/ prefer-language=$1
       RedirectMatch 301 ^/apache-manual(…)?$ /apache-manual/$1$2

The result is /apache-manual, /apache-info and /apache-status URLs you can use.

Autoindex

The httpd-autoindex.conf must also be made relocateable:

   # conf/extra/httpd-autoindex.conf
   Alias /icons/ "${rxApa_BASE}/apa/icons/"
   <Directory "${rxApa_BASE}/apa/icons">…

Now all references to /icons will point to the correct directory.

Batch Files

The following Command Prompt batch files (.cmd) create the appropriate environment variables used in the configuration files above, and start or stop the server.

Environment & PATH

The rxapache-env.cmd batch file is called by the others to set the environment variables and PATH. It can be run from an existing cmd.exe instance. It will also change the prompt to show that the settings are in effect.

rxapache-env.cmdSet Apache Environment
@echo off & setlocal enableextensions
:: Set Apache & PHP environment (also PATH). Does not open a new Cmd
:: Prompt instance. Once this batch file has been executed in an
:: existing Command Prompt, simply running `httpd.exe` should start
:: Apache correctly, assuming the required settings have been made in
:: `php.ini` & `httpd.conf`.
::
:: LICENCE: MIT — https://opensource.org/licenses/MIT
endlocal

:: Get this batch file's directory, and strip trailing backslash. All
:: other paths are set relative to this variable. Apache wants forward
:: slashes, and PHP configurations prefer backslashes on Windows. These
:: variables are used in the `php.ini`, `extras\httpd-php5.conf` and
:: `httpd.conf` files to provide portablility.
set rxPHP_BASE=%~dp0
set rxPHP_BASE=%rxPHP_BASE:~0,-1%
set rxApa_BASE=%rxPHP_BASE:\=/%

:: Set the preferred Port for Apache to listen to. This can be changed.
set rxApa_PORT=8182

:: Prefix some directories to the current `PATH` variable.
set PATH=%rxPHP_BASE%\utl;%rxPHP_BASE%\utl\imagick;%PATH%
set PATH=%rxPHP_BASE%\apa\bin;%rxPHP_BASE%\php;%rxPHP_BASE%\php\ext;%PATH%

:: Change the prompt to show the Apache & PHP environment is active.
set PROMPT=[rxApache+PHP7] $p$_$g$s

:EXIT

Apache Console

The rxapache-cmd.cmd batch file is suitable for “double-clicking” from a file manager, and will open a new Command Prompt console, with the appropriate environment variables and path set. The prompt is modified to reflect the configuration.

rxapache-cmd.cmdNew Command Prompt with Relocateable Apache Environment
@echo off & setlocal enableextensions
:: Opens new Command Prompt window with Apache+PHP environment and PATH
::
:: LICENCE: MIT — https://opensource.org/licenses/MIT
setlocal enabledelayedexpansion

:: The following batch file only sets the environment and PATH.
call %~dp0rxapache-env.cmd

:: Open a new command prompt window, with appropriate title
:: (notice trailing space after `$p$_$g `).
set PROMPT=[rxApache+PHP7] $p$_$g 
start "rxApache+PHP7 [%rxApa_PORT%]" /D %rxPHP_BASE% cmd.exe /K "httpd ^-v & php -v"

goto :EXIT

:EXIT
endlocal

Start Apache

The rxapache-start.cmd batch file is used to start Apache in a minimised console. It calls the above rxapache-env.cmd batch file.

rxapache-start.cmdStart Apache Server
@echo off & setlocal enableextensions
:: Opens new minimised Command Prompt window with running Apache+PHP
::
:: LICENCE: MIT — https://opensource.org/licenses/MIT
setlocal enabledelayedexpansion

:: The following batch file only sets the environment and PATH.
call %~dp0rxapache-env.cmd

:: Open a new command prompt window, with appropriate title.
start "rxApache+PHP7 [%rxApa_PORT%]" /D %rxPHP_BASE% /MIN httpd -e info -w

endlocal

Stop Apache

The rxapache-stop.cmd batch file is used to stop the Apache server. Apache saves the process ID of the executable in the logs dir­ec­tory, under the name httpd.pid. This can be passed to the standard Windows utility taskkill.exe.

rxapache-stop-cmdStop Apache Server
@echo off & setlocal enableextensions
:: Stops running Apache from `httpd.pid` file in `logs` directory.
::
:: LICENCE: MIT — https://opensource.org/licenses/MIT
setlocal enabledelayedexpansion

:: The following batch file only sets the environment and PATH.
call %~dp0rxapache-env.cmd
if not exist "%rxPHP_BASE%\apa\logs\httpd.pid" (
   echo.
   echo Cannot find running Apache (no %rxPHP_BASE%\apa\logs\httpd.pid^)
   goto EXIT
   )
set /p rxApa_HTTPD=<%rxPHP_BASE%\apa\logs\httpd.pid
taskkill /PID %rxApa_HTTPD%

:EXIT
endlocal

You could alternatively consider just placing apachectl stop in this batch file. If it works for you, it certainly will be much simpler.

Conclusion

Finally! You now have a working Apache, as long as you followed the instructions without errors. You can now create HTML and PHP files in rxapache\www, or subdirectories under it. To test your new Apache web server, you can place the following in a phpinfo.php file under www, and navigate to it in your browser (http://localhost:8182/phpinfo.php if you used the same port settings above). It should show all PHP configuration settings and loaded module information.

phpinfo.phpTraditional PHP Test
<?php phpinfo(); ?>

If not, make sure the server is running, that you are using the correct port, and that the URL is cor­rect. Otherwise, retrace your steps or investigate the log files.

WARNINGDo Not Use in Production

A final reminder that this is a development setup on a local network. Do not run this configuration on a public IP address. Apart from configuration, it is perfectly viable as a public server, provided you make the configuration more secure.


2019-06-18: Updated for Apache 2.4.39 & PHP 7.3.6 [brx].
2018-10-27: Updated for Apache 2.4.37 & PHP 7.2.11 [brx].
2018-05-22: Updated for Apache 2.4.33 & PHP 7.2.5 [brx].
2018-01-11: Edited. [jjc]
2018-01-09: Updated for Apache 2.4.29 & PHP 7.2.1 [brx].
2017-09-14: Created. [brx]