0

I am successfully running XAMPP on Windows 10 (xampp-windows-x64-8.0.10-0-VS16) which includes PHP 8. Now I've got the need to work on some elder project that is not ready for PHP 8. Found a few posts that explain how to setup the environment to support two versions of PHP. I followed the instructions described in Is there way to use two PHP versions in XAMPP?, specifically in answer titled "Why switch between PHP versions when you can use multiple PHP versions at the same time with a single xampp installation?", option 1 use PHP 7.4 only for specific directory

I can't get it to work. Here is what I've done so far:

  1. Downloaded PHP 7.4 (VC15 x64 Non Thread Safe (2021-Sep-21 16:58:34)) from php.net, and extracted the zip into a new directory "php74" within the "xampp" directory, i.e. d:\xamp\php74.
  2. Created file php.ini in *php74", and modified it.
  3. Edited the http-xampp.conf file as described.

With this setup (see below for config files), PHP 8 ready web site is (still) properly displayed in brwoser.

When accessing localhost/photos-local-dev/, I can see that Apache is trying to run PHP 7.4 for that web site, because the previous error meassage ...Call to undefined function get_magic_quotes_gpc()... is no longer shown. So the new directives in httpd-xampp.conf are active.

However, instead of passing index.php to PHP 7.4, the browser simply displays the index.php file as if it was an (almost) plain text file (don't watch the line breaks; I reformatted a bit for readability reasons):

0 && $page['start']>=count($page['items'])) { page_not_found('', duplicate_index_url(array('start'=>0))); } 
trigger_notify('loc_begin_index');//---------------------------------------------- change of image display order 
if (isset($_GET['image_order'])) { if ( (int)$_GET['image_order'] > 0){pwg_set_session_var('image_order', 
(int)$_GET['image_order']); } else {pwg_unset_session_var('image_order'); } redirect( duplicate_index_url( array(),//
nothing to redefine array('start') // changing display order goes back to section first page ) ); } if(isset(
$_GET['display'])) { $page['meta_robots']['noindex']=1; if (array_key_exists($_GET['display'],
ImageStdParams::get_defined_type_map())) {pwg_set_session_var('index_deriv', $_GET['display']); } } 
//-------------------------------------------------------------- initialization // navigation bar $page[
'navigation_bar'] = array(); if (count($page['items']) > $page['nb_image_page']) { $page['navigation_bar'] = 
create_navigation_bar( duplicate_index_url(array(), array('start')), count($page['items']), 

While trying to find the problem, I stumbled across the following lines in the httpd-xampp.conf:

<IfModule env_module>
    SetEnv MIBDIRS "D:/xampp/php/extras/mibs"
    SetEnv MYSQL_HOME "\\xampp\\mysql\\bin"
    SetEnv OPENSSL_CONF "D:/xampp/apache/bin/openssl.cnf"
    SetEnv PHP_PEAR_SYSCONF_DIR "\\xampp\\php"
    SetEnv PHPRC "\\xampp\\php"
    SetEnv TMP "\\xampp\\tmp"
</IfModule>

#
# PHP-Module setup
#
LoadFile "D:/xampp/php/php8ts.dll"
LoadFile "D:/xampp/php/libpq.dll"
LoadFile "D:/xampp/php/libsqlite3.dll"
LoadModule php_module "D:/xampp/php/php8apache2_4.dll"

If I inactivate the LoadFile and LoadModule lines, and then try to display the PHP 8 ready website again, the broswer shows the index.php as text, like above. This confirms that those loads are essential. So, can I add the corresponding directives pointing to PHP 7.4 module? How would Apache distinguish? But, alas, modules php7ts.dll, php7apach2_4.dll don't even exist in the PHP74 directory? These must be add-ons to PHP supplied by xampp, since they are not found in the official zip file.

Did anyone really get this to work? Some comments to above mentioned stack overflow q&a seem to indicate so.

So, what am I missing?

This is the httpd-xamp.conf:

#
# XAMPP settings
#

<IfModule env_module>
    SetEnv MIBDIRS "D:/xampp/php/extras/mibs"
    SetEnv MYSQL_HOME "\\xampp\\mysql\\bin"
    SetEnv OPENSSL_CONF "D:/xampp/apache/bin/openssl.cnf"
    SetEnv PHP_PEAR_SYSCONF_DIR "\\xampp\\php"
    SetEnv PHPRC "\\xampp\\php"
    SetEnv TMP "\\xampp\\tmp"
</IfModule>

#
# PHP-Module setup
#
LoadFile "D:/xampp/php/php8ts.dll"
LoadFile "D:/xampp/php/libpq.dll"
LoadFile "D:/xampp/php/libsqlite3.dll"
LoadModule php_module "D:/xampp/php/php8apache2_4.dll"

<FilesMatch "\.php$">
    SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch "\.phps$">
    SetHandler application/x-httpd-php-source
</FilesMatch>

<IfModule php_module>
    PHPINIDir "D:/xampp/php"
</IfModule>

<IfModule mime_module>
    AddType text/html .php .phps
</IfModule>

ScriptAlias /php-cgi/ "D:/xampp/php/"
<Directory "D:/xampp/php">
    AllowOverride None
    Options None
    Require all denied
    <Files "php-cgi.exe">
          Require all granted
    </Files>
</Directory>

# Added by phun to support PHP 7.4 in parallel to PHP 8 that came with xampp
# |
ScriptAlias /php74 "D:/xampp/php74/"
Action application/x-httpd-php74-cgi /php74/php-cgi.exe
<Directory "D:/xampp/php74">
    AllowOverride None
    Options None
    Require all denied
    <Files "php-cgi.exe">
          Require all granted
    </Files>
</Directory>
# |
# Added by phun to support PHP 7.4 in parallel to PHP 8 that came with xampp

<Directory "D:/xampp/cgi-bin">
    <FilesMatch "\.php$">
        SetHandler cgi-script
    </FilesMatch>
    <FilesMatch "\.phps$">
        SetHandler None
    </FilesMatch>
</Directory>

<Directory "D:/xampp/htdocs/xampp">
    <IfModule php_module>
        <Files "status.php">
            php_admin_flag safe_mode off
        </Files>
    </IfModule>
    AllowOverride AuthConfig
</Directory>

<IfModule alias_module>
    Alias /licenses "D:/xampp/licenses/"
    <Directory "D:/xampp/licenses">
        Options +Indexes
        <IfModule autoindex_color_module>
            DirectoryIndexTextColor  "#000000"
            DirectoryIndexBGColor "#f8e8a0"
            DirectoryIndexLinkColor "#bb3902"
            DirectoryIndexVLinkColor "#bb3902"
            DirectoryIndexALinkColor "#bb3902"
        </IfModule>
        Require local
        ErrorDocument 403 /error/XAMPP_FORBIDDEN.html.var
   </Directory>

    Alias /phpmyadmin "D:/xampp/phpMyAdmin/"
    <Directory "D:/xampp/phpMyAdmin">
        AllowOverride AuthConfig
        Require local
        ErrorDocument 403 /error/XAMPP_FORBIDDEN.html.var
    </Directory>

    Alias /webalizer "D:/xampp/webalizer/"
    <Directory "D:/xampp/webalizer">
        <IfModule php_module>
            <Files "webalizer.php">
                php_admin_flag safe_mode off
            </Files>
        </IfModule>
        AllowOverride AuthConfig
        Require local
        ErrorDocument 403 /error/XAMPP_FORBIDDEN.html.var
    </Directory>
</IfModule>

# Added by phun to support PHP 7.4 in parallel to PHP 8 that came with xampp
# |
<Directory "D:\xampp\htdocs\photos-local-dev">
    UnsetEnv PHPRC
    <FilesMatch "\.php$">
        SetHandler application/x-httpd-php74
    </FilesMatch>
</Directory>
# |
# Added by phun to support PHP 7.4 in parallel to PHP 8 that came with xampp

This is the condensed php.ini (comment and blank lines removed):

[PHP]
engine=On
short_open_tag=Off
precision=14
output_buffering=4096
zlib.output_compression=Off
implicit_flush=Off
unserialize_callback_func=
serialize_precision=-1
disable_functions=
disable_classes=
zend.enable_gc=On
zend.exception_ignore_args=Off
zend.exception_string_param_max_len=15
expose_php=On
max_execution_time=120
max_input_time=60
memory_limit=512M
error_reporting=E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors=On
display_startup_errors=On
log_errors=On
log_errors_max_len=1024
ignore_repeated_errors=Off
ignore_repeated_source=Off
report_memleaks=On
variables_order="GPCS"
request_order="GP"
register_argc_argv=Off
auto_globals_jit=On
post_max_size=40M
auto_prepend_file=
auto_append_file=
default_mimetype="text/html"
default_charset="UTF-8"
doc_root=
user_dir=
extension_dir="D:\xampp\php74\ext"
enable_dl=Off
file_uploads=On
upload_tmp_dir="D:\xampp\tmp"
upload_max_filesize=40M
max_file_uploads=20
allow_url_fopen=On
allow_url_include=Off
default_socket_timeout=60
extension=bz2
extension=curl
extension=fileinfo
extension=gd
extension=gettext
extension=mbstring
extension=exif      ; Must be after mbstring as it depends on it
extension=mysqli
extension=pdo_mysql
extension=pdo_sqlite
asp_tags=Off
display_startup_errors=On
track_errors=Off
y2k_compliance=On
allow_call_time_pass_reference=Off
safe_mode=Off
safe_mode_gid=Off
safe_mode_allowed_env_vars=PHP_
safe_mode_protected_env_vars=LD_LIBRARY_PATH
error_log="D:\xampp\php\logs\php_error_log"
register_globals=Off
register_long_arrays=Off
magic_quotes_gpc=Off
magic_quotes_runtime=Off
magic_quotes_sybase=Off
extension=php_openssl.dll
extension=php_ftp.dll
[CLI Server]
cli_server.color=On
[Date]
[filter]
[iconv]
[imap]
[intl]
[sqlite3]
[Pcre]
[Pdo]
pdo_mysql.default_socket="MySQL"
[Pdo_mysql]
pdo_mysql.default_socket=
[Phar]
[mail function]
SMTP=localhost
smtp_port=25
mail.add_x_header=Off
[ODBC]
odbc.allow_persistent=On
odbc.check_persistent=On
odbc.max_persistent=-1
odbc.max_links=-1
odbc.defaultlrl=4096
odbc.defaultbinmode=1
[MySQLi]
mysqli.max_persistent=-1
mysqli.allow_persistent=On
mysqli.max_links=-1
mysqli.default_port=3306
mysqli.default_socket=
mysqli.default_host=
mysqli.default_user=
mysqli.default_pw=
mysqli.reconnect=Off
[mysqlnd]
mysqlnd.collect_statistics=On
mysqlnd.collect_memory_statistics=On
[OCI8]
[PostgreSQL]
pgsql.allow_persistent=On
pgsql.auto_reset_persistent=Off
pgsql.max_persistent=-1
pgsql.max_links=-1
pgsql.ignore_notice=0
pgsql.log_notice=0
[bcmath]
bcmath.scale=0
[browscap]
[Session]
session.save_handler=files
session.save_path="D:\xampp\tmp"
session.use_strict_mode=0
session.use_cookies=1
session.use_only_cookies=1
session.name=PHPSESSID
session.auto_start=0
session.cookie_lifetime=0
session.cookie_path=/
session.cookie_domain=
session.cookie_httponly=
session.cookie_samesite=
session.serialize_handler=php
session.gc_probability=1
session.gc_divisor=1000
session.gc_maxlifetime=1440
session.referer_check=
session.cache_limiter=nocache
session.cache_expire=180
session.use_trans_sid=0
session.sid_length=26
session.trans_sid_tags="a=href,area=href,frame=src,form="
session.sid_bits_per_character=5
[Assertion]
zend.assertions=1
[COM]
[mbstring]
[gd]
[exif]
[Tidy]
tidy.clean_output=Off
[soap]
soap.wsdl_cache_enabled=1
soap.wsdl_cache_dir="/tmp"
soap.wsdl_cache_ttl=86400
soap.wsdl_cache_limit=5
[sysvshm]
[ldap]
ldap.max_links=-1
[dba]
[opcache]
[curl]
curl.cainfo="D:\xampp\apache\bin\curl-ca-bundle.crt"
[openssl]
openssl.cafile="D:\xampp\apache\bin\curl-ca-bundle.crt"
[ffi]
[Syslog]
define_syslog_variables=Off
[Session]
define_syslog_variables=Off
[Date]
date.timezone=Europe/Berlin
[MySQL]
mysql.allow_local_infile=On
mysql.allow_persistent=On
mysql.cache_size=2000
mysql.max_persistent=-1
mysql.max_link=-1
mysql.default_port=3306
mysql.default_socket="MySQL"
mysql.connect_timeout=3
mysql.trace_mode=Off
[Sybase-CT]
sybct.allow_persistent=On
sybct.max_persistent=-1
sybct.max_links=-1
sybct.min_server_severity=10
sybct.min_client_severity=10
[MSSQL]
mssql.allow_persistent=On
mssql.max_persistent=-1
mssql.max_links=-1
mssql.min_error_severity=10
mssql.min_message_severity=10
mssql.compatability_mode=Off
mssql.secure_connection=Off
phunsoft
  • 2,674
  • 1
  • 11
  • 22
  • Getting multiple native versions to work like this is always a pain. I'd recommend dropping XAMPP in favor of WSL2, as it gives you a much more native experience. If you then install Ubuntu, you can use their alternatives system to easily toggle from 7.4 to 8.0 and back. Or better, you can even use Docker in WSL2 and spin up arbitrarily versioned containers for each project. – Alex Howansky Oct 18 '21 at 20:32

1 Answers1

0

I am trying to do the same thing (add PHP 7.4 to a recent install of XAMPP that contains PHP 8.1), since Drupal doesn't seem to like 8.1. But I am trying to run separately configured sites (some using PHP 8.1 and some PHP 7.4).

The line

 SetEnv PHPRC "\\xampp\\php" 

is a global default. It still points to the PHP 8.1 directoy. If you want to just replace 8.1 with 7.4 globally you could change the folder to "php74" (presuming you have that new name).

Maybe including SetEnv PHPRC "\xampp\php74" in the section will overwrite THAT.

However, the "PHP module" load statements are all for THREAD SAFE PHP. You will find the DLLs in the "Thread Safe" version of the PHP 7.4 download. Apparently Windows 10 allows running thread safe. I used to run only NON-THREAD-SAFE on my earlier versions of Windows. So I was a little baffled by those module components as well. All of the instructions that I have seen presume NON-THREAD-SAFE PHP.

If you want to add site-specific PHP using configuration (with site specific site config between those brackets), you cannot very well just LEAVE the PHP 8 global path and module loads active in the global section of the config file.

That doesn't answer your question, but it points in the direction.

I would naturally tend to think that unloading the PHP 8 DLLs and loading the PHP 7.4 DLLs in the section for PHP 7.4 sites would solve the problem (if you want to keep global PHP 8) would work. But I don't know that there is an UNLOAD command for Config files (UnloadFile or UnloadModule).

Peter
  • 383
  • 4
  • 8