localhost and Xampp

Virtual Hosts

Instead of using my-project.dev or my-project.local to differentiate domain names, I prefer to use subdomains like local.my-project.com.

This makes more clear for what domain I'm developing for and it's easier to develop domain specific features like a redirect for my-project.com or my-project.de domains.

Certificates for localhost with mkcert

create certificates for local development domains with mkcert.exe

https://web.archive.org/save/https://blog.filippo.io/mkcert-valid-https-certificates-for-localhost/

Options for DEV Environment

Most modern approach is Docker. Right now I don't have the mental capacity to mess with it, but if, then Devilbox would be the way to go.

Neard seems to be an all in one portable dev package with Apache, Node.js, versions of php and even browsers to test. I think this could be ok to start with a vanilla webproject, dev machine.

WAMP Server is similar to XAMPP and comes with several PHP versions, but those cannot be run in parallel.

XAMPP is my choice for local development right now, because it runs flawless so far and just needed the option to run PHP 5.6 and any version of PHP 7 in parallel.

This is done by run PHP 5.6 as Apache module as indented and run all other versions in cgi mode.

PHP 5.6 and 7.x parallel on XAMPP

Run PHP 5.6 as Apache Module and PHP 7.4 as CGI

  1. Download PHP 7.x Win32 Thread-Safe https://windows.php.net/download/

  2. Edit httpd-xampp.conf add:

#
# PHP-CGI setup
#

# Put Authorization Header back to HTTP Headers
# If you are using Apache with CGI/FastCGI, then you might get an error message about missing authorization headers. This is because Apache does not, by default, pass authorization headers to PHP.

SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0

# PHP Versions

ScriptAlias /php74/ "E:/xampp/php749/"

<IfModule actions_module>
Action application/x-httpd-php74-cgi "/php74/php-cgi.exe"
</IfModule>

# Make directory executable
<Directory "E:/xampp/php749/">
    AllowOverride None
    Options None
    Require all denied
    <Files "php-cgi.exe">
          Require all granted
    </Files>
    # Where to find php.ini
    SetEnv PHPRC "E:/xampp/php749"
</Directory>

ScriptAlias /php73/ "E:/xampp/php7321/"

<IfModule actions_module>
Action application/x-httpd-php73-cgi "/php73/php-cgi.exe"
</IfModule>

# Make directory executable
<Directory "E:/xampp/php7321/">
    AllowOverride None
    Options None
    Require all denied
    <Files "php-cgi.exe">
          Require all granted
    </Files>
    # Where to find php.ini
    SetEnv PHPRC "E:/xampp/php7321"
</Directory>
  1. Edit httpd-vhosts.conf
<VirtualHost *>
    DocumentRoot E:\WEB\tools.de
    ServerName local.tools.de

    # Run as CGI module
    <FilesMatch "\.php$">
    SetHandler application/x-httpd-php7-cgi
    </FilesMatch>
</VirtualHost>
  1. Edit php.ini

    • Enable dynamic extensions (sqlite, curl etc)
    • extension_dir = "ext"
    • Certificate information curl.cainfo="E:\xampp\cacert.pem"
    • Activate Xdebug https://xdebug.org/docs/install
  2. Set PATH to PHP 7.x to use latest PHP version on command line.

  3. Now with PHP 7.x on the cli, set max php version to composer file in project to not accidentally update libraries that need to run on PHP 5, to PHP 7.

{

    "config": {
        "platform": {
            "php": "5.6.1"
        }
    },
    "require": {
        "symfony/yaml": "^3.2",
    }
}

Check with composer outdated what needs to be updated.

Path=C:\Program Files (x86)\Common Files\Oracle\Java\javapath;E:\xampp\Git\mingw32\bin;M:\foobar2000\encoders;E:\xampp\FTP;C:\ProgramData\Oracle\Java\javapath;E:\xampp\ImageMagick;E:\xampp\putty;E:\xampp\ghostscript\bin;E:\xampp\FTPSync;E:\xampp\PHPloy;E:\xampp\Git\cmd;E:\xampp\php7321;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;E:\xampp\Console2;C:\Program Files (x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS Client\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\QuickTime\QTSystem\;C:\ProgramData\ComposerSetup\bin;C:\Users\mo\AppData\Local\Pandoc\;C:\Users\mo\AppData\Roaming\npm;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;E:\xampp\nodejs\;%SYSTEMROOT%\System32\OpenSSH\;C:\Program Files (x86)\Gource\cmd;C:\ProgramData\chocolatey\bin;C:\Program Files\Microsoft SQL Server\120\Tools\Binn\;C:\Program Files (x86)\PDFtk\bin\;C:\Program Files\dotnet\

Composer

Change Composer Home Folder https://w3guy.com/change-composer-global-package-install-folder-windows/

PHP

PHP_CodeSniffer (PHPCS+PHPCBF)

PHP CodeSniffer and PHP-CS-Fixer are similar tools

PHPCS seems to be more common. PHP Code Beautifier (PHPCBF) fixes the file after a defined rule set. PHP_CodeSniffer just notifies.

1. Install globally via Composer

https://github.com/squizlabs/PHP_CodeSniffer

2. Set Paths

For Sublime Text phpcs extension, set the paths to the *.bat

{
    // phpcbf settings

    // Path to where you have the phpcbf installed
    "phpcbf_executable_path": "E:/xampp/Composer/vendor/bin/phpcbf.bat",

    "phpcbf_additional_args": {
        //"--standard": "Squiz",
        "-n": "",
        "-s": "",
        //"--standard": "E:/xampp/phpcs/ruleset.xml"
        "--standard": "E:/xampp/phpcs/MyPSR12/ruleset.xml"
    }
}

3. check installed path for rules:


E:\WEB>E:/xampp/Composer/vendor/bin/phpcs.bat --config-show

E:\WEB>E:/xampp/Composer/vendor/bin/phpcs.bat --config-set installed_paths E:\xampp\phpcs
Using config file: E:\xampp\Composer\vendor\squizlabs\php_codesniffer\CodeSniffer.conf

Config value "installed_paths" updated successfully; old value was "/e/xampp/phpcs/"

E:\WEB>E:/xampp/Composer/vendor/bin/phpcs.bat --config-show
Using config file: E:\xampp\Composer\vendor\squizlabs\php_codesniffer\CodeSniffer.conf

installed_paths: E:\xampp\phpcs

E:\WEB>E:/xampp/Composer/vendor/bin/phpcbf.bat E:\WEB\site\models\netzwerk.php --standard=MyPSR2 -n

💡 To debug rulesets and find out what to exclude run:

phpcs temp.php --standard=Generic,Squiz,PEAR,PSR2,Zend -s

via https://stackoverflow.com/a/44937114/814031

5. Rule sets

Ref: https://github.com/squizlabs/PHP_CodeSniffer/wiki

I want tabs and some formatting from MySource. This seems to be ok:

<?xml version="1.0"?>
<ruleset name="MyPSR12">
    <description>PSR12 with tabs instead of spaces.</description>
    <arg name="tab-width" value="4"/>
    <rule ref="MySource">
        <exclude name="Generic.WhiteSpace.DisallowTabIndent"/>
    </rule>

    <rule ref="Generic.WhiteSpace.DisallowSpaceIndent"/>
    <rule ref="Generic.WhiteSpace.ScopeIndent">
        <properties>
            <property name="indent" value="4"/>
            <property name="tabIndent" value="true"/>
        </properties>
    </rule>

    <rule ref="Squiz">
        <exclude name="Squiz.Commenting.LongConditionClosingComment"/>
        <exclude name="Squiz.Commenting.ClosingDeclarationComment.Missing"/>
    </rule>
</ruleset>

Xdebug

Slows everything down. If not needed, disable it in main php.ini!

#[XDebug]
#zend_extension = "php_xdebug-2.9.6-7.3-vc15.dll"

Xdebug Issue "End of script output before headers: php-cgi.exe"

Server error! The server encountered an internal error and was unable to complete your > request.

Error message: End of script output before headers: php-cgi.exe

If you think this is a server error, please contact the webmaster.

Error 500 local.tools.marcus-obst.de Apache/2.4.12 (Win32) OpenSSL/1.0.1l PHP/5.6.8

This is caused when using a number as key of a query string like info.php?0=foo - which is weird.

https://stackoverflow.com/questions/45790160/is-there-way-to-use-two-php-versions-in-xampp/45905822#comment112617006_49586592

CGI Mode and php.ini

  • add custom .user.ini to project root to overwrite certain settings
upload_max_filesize="5M"
track_errors = On

Troubleshooting

Error 500: malformed header from script. Bad header=<br>

If your webserver throws a HTML 500 error and Apache error_log file shows "malformed header from script. Bad header=
", then you probably have a misconfigured php.ini file in your website root directory.

Missing Authorization Header in PHP running in CGI-Mode

Edit httpd-xampp.conf add:

# PHP-CGI setup

SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0

ScriptAlias /php74/ "E:/xampp/php749/"

https://stackoverflow.com/a/54729344/814031

Howto

Tomcat

Issues

Error 503 in /examples folder

http://localhost/examples results in Error 503 because of Tomcat being installed

http://localhost/somethingelse/examples works

FIX

To fix it navigate to file: C:\xampp\apache\conf\extra\httpd-ajp.conf and comment out the following line with #: ProxyPass /examples ajp://127.0.0.1:8009/examples smax=0 ttl=60 retry=5 Then restart the server and enjoy these great Examples.