PHP7.3 install, PHP files sent to browser unprocessed (mod_php / FastCGI conflict, php engine off in virtualhosts)

tl;dr: After doing a PHP7.3 install, I lost all PHP processing although Apache was running OK and PHP appeared to have installed fine. The problem seems like it may be due to installing the mod_php package while installing PHP7.3 and other related PHP modules with yum.

My theory is that by also installing mod_php, this resulted in Virtualmin getting confused and, because FastCGI should be used (not mod_php), it helpfully added a line which disabled the PHP engine in every Apache VirtualHost declaration - perhaps as a ‘safety’ feature - even though I don’t think this was actually necessary.

To get PHP7.3 working via FastCGI, I had to do the following

  1. comment out LoadModule php7_module modules/libphp73.so in /etc/httpd/conf.modules.d. You could/should probably do this with a2dismod, I did it the cheat way for testing purposes. :slight_smile:

  2. Amend each VirtualHost declaration and comment out the php_admin_value engine Off line. I believe Virtualmin/Webmin added this to each virtualhost declaration automatically when it detected both FastCGI and mod_php methods available. This is required by Apache; once you unload mod_php and reload its config, Apache cannot reconcile what the variable is/was trying to set (because that variable is specific to mod_php), and so it will not reload/start. (Hint: this appears twice for each conf if you have SSL enabled for a virtual site).

  3. Reload Apache and test with suitable file (phpinfo
)

I hope this helps. I had already noticed the “php_admin_value engine Off” setting but what prompted me to try commenting it sooner was this old thread - Ubuntu 16.04 and php_admin_value engine Off php 7 (https://www.virtualmin.com/node/40518 on the old forum) where @Eric mentioned ‘this is something the installer does now’. I think somewhere/somehow it mistakenly picked up on the IfModule declaration, which would not have applied anyway, and incorrectly added the engine Off statements, resulting in a self-inflicted lack of PHP :rofl:

Don’t forget that browser caches can interfere if you’re doing iterative testing to fix this kind of problem. I needed to rename files between testing and server restarts. I also made various phpinfo files with sequential names so I could switch between them when testing. I found Chrome, even in Incognito, was blindly serving from its own internal cache (giving false results) for a while after I fixed the problem.


And now the longer version
!
This is a question which turned into a discussion and request for feedback from experts regarding my method. :slight_smile:

After getting Webmin and Virtualmin running on a new CentOS 7.7 box, I added my usual group of starter repos (EPEL, extras, rpmfusion, centos-sclo-rh, centos-sclo-sclo, ius, Remi, centosplus) and did initial software updates.

I then updated via yum to the rh-php72 family of packages which sourced from centos-sclo-rh. I also uninstalled the initial PHP5 install

I read about issues with multiple PHP version coexistence, so removed the rh-php72* packages and decided to install Remi’s PHP7.3 packages from the remi-safe repo.

    Install     php73-2.0-1.el7.remi.x86_64                                      @remi-safe
    Install     php73-php-bcmath-7.3.13-1.el7.remi.x86_64                        @remi-safe
    Dep-Install php73-php-cli-7.3.13-1.el7.remi.x86_64                           @remi-safe
    Dep-Install php73-php-common-7.3.13-1.el7.remi.x86_64                        @remi-safe
    Install     php73-php-dba-7.3.13-1.el7.remi.x86_64                           @remi-safe
    Install     php73-php-dbg-7.3.13-1.el7.remi.x86_64                           @remi-safe
    Install     php73-php-devel-7.3.13-1.el7.remi.x86_64                         @remi-safe
    Install     php73-php-embedded-7.3.13-1.el7.remi.x86_64                      @remi-safe
    Install     php73-php-enchant-7.3.13-1.el7.remi.x86_64                       @remi-safe
    Install     php73-php-gd-7.3.13-1.el7.remi.x86_64                            @remi-safe
    Install     php73-php-intl-7.3.13-1.el7.remi.x86_64                          @remi-safe
    Install     php73-php-json-7.3.13-1.el7.remi.x86_64                          @remi-safe
    Install     php73-php-mbstring-7.3.13-1.el7.remi.x86_64                      @remi-safe
    Install     php73-php-mysqlnd-7.3.13-1.el7.remi.x86_64                       @remi-safe
    Dep-Install php73-php-pdo-7.3.13-1.el7.remi.x86_64                           @remi-safe
    Install     php73-php-pecl-igbinary-3.1.0-1.el7.remi.x86_64                  @remi-safe
    Install     php73-php-pecl-ip2location-8.0.1-3.el7.remi.x86_64               @remi-safe
    Install     php73-php-pecl-mcrypt-1.0.3-1.el7.remi.x86_64                    @remi-safe
    Install     php73-php-pecl-mysql-1.0.0-0.20.20180226.647c933.el7.remi.x86_64 @remi-safe
    Install     php73-php-pecl-redis4-4.3.0-1.el7.remi.x86_64                    @remi-safe
    Install     php73-php-process-7.3.13-1.el7.remi.x86_64                       @remi-safe
    Install     php73-php-soap-7.3.13-1.el7.remi.x86_64                          @remi-safe
    Install     php73-php-xml-7.3.13-1.el7.remi.x86_64                           @remi-safe
    Dep-Install php73-runtime-2.0-1.el7.remi.x86_64                              @remi-safe

I ran virtualmin check-config which detected the new PHP version;

The following PHP versions are available : 7.3.13 (/bin/php73-cgi), 7.3 (mod_php)

The following PHP-FPM versions are available on this system : 7.3.13 (php73-php-fpm)

*The first time round, it said it also generated a new php.ini, however the file already existed and didn’t appear to be changed.

After disabling mod_php, running virtualmin check-config shows the following:

The following PHP versions are available : 7.3.13 (/bin/php73-cgi)

The following PHP-FPM versions are available on this system : 7.3.13 (php73-php-fpm)

PHP versions have changed to 7.3 since last check. Regenerating any missing php.ini files.

Just in case, I’ve symlinked php-cgi to php-cgi73 where relevant (for safety/default purposes) but I’ve directly referenced php-cgi73, php73 and so on in places like fcgi-bin configs and Apache configs where required.

For sites created prior to PHP7.3 being installed, I also added and chmodded php7.3.fcgi with necessary modifications to each existing virtual server. After installing PHP7.3, I updated the path to php.ini in the Webmin -> Others -> PHP config section and it parsed OK.

I also added a couple of new test servers to see whether Virtualmin would correctly generate the .conf virtualhost statement; it did so correctly, putting in FCGIWrapper, AddHandler and RemoveHandler lines in each virtualhost definition. However existing sites’ virtualhost definitions were not modified. Perhaps a good thing, perhaps bad.

I’ve also seen other posts discussing this and have already performed the steps to comment out any SetHandler lines as discussed in the Virtualmin documentation. The only live SetHandler is wrapped in an if statement for mod_php (which I’m not currently using).

Contents of /etc/httpd/conf.d/php73-php.conf:

#
# The following lines prevent .user.ini files from being viewed by Web clients.
#
<Files ".user.ini">
    <IfModule mod_authz_core.c>
        Require all denied
    </IfModule>
    <IfModule !mod_authz_core.c>
        Order allow,deny
        Deny from all
        Satisfy All
    </IfModule>
</Files>

#
# Allow php to handle Multiviews
#
AddType text/html .php

#
# Add index.php to the list of files that will be served as directory
# indexes.
#
DirectoryIndex index.php

# mod_php options
<IfModule  mod_php7.c>
    #
    # Cause the PHP interpreter to handle files with a .php extension.
    #
    <FilesMatch \.(php|phar)$>
        SetHandler application/x-httpd-php
    </FilesMatch>

    #
    # Uncomment the following lines to allow PHP to pretty-print .phps
    # files as PHP source code:
    #
    #<FilesMatch \.phps$>
    #    SetHandler application/x-httpd-php-source
    #</FilesMatch>

    #
    # Apache specific PHP configuration options
    # those can be override in each configured vhost
    #
    php_value session.save_handler "files"
    php_value session.save_path    "/var/opt/remi/php73/lib/php/session"
    php_value soap.wsdl_cache_dir  "/var/opt/remi/php73/lib/php/wsdlcache"

    #php_value opcache.file_cache   "/var/opt/remi/php73/lib/php/opcache"
</IfModule>

After the PHP 7.3 installation, apachectl -M indicated the php7_module (shared) was loaded.

At that point, attempting to invoke a phpinfo() from the root of any site didn’t work. Each time, a file was offered for download when the URL was accessed, whose contents were raw unprocessed PHP code.

Apache always served static content fine; the Webmin and Virtualmin interfaces are also fine (obviously not relying on PHP).

Only by making the changes described earlier in this post was I able to get PHP processing to function.

After symlinking php to the php73 binary, Running php -v and php -f phpinfo.php at a prompt indicated PHP was functional through the course of my testing;

# php -f phpi.php
phpinfo()
PHP Version => 7.3.13

System => Linux servername.tld 3.10.0-1062.9.1.el7.x86_64 #1 SMP Fri Dec 6 15:49:49 UTC 2019 x86_64
Build Date => Dec 17 2019 10:29:15
Server API => Command Line Interface
Virtual Directory Support => disabled
Configuration File (php.ini) Path => /etc/opt/remi/php73
Loaded Configuration File => /etc/opt/remi/php73/php.ini
Scan this dir for additional .ini files => /etc/opt/remi/php73/php.d
Additional .ini files parsed => /etc/opt/remi/php73/php.d/20-bcmath.ini,
/etc/opt/remi/php73/php.d/20-bz2.ini,
/etc/opt/remi/php73/php.d/20-calendar.ini,
/etc/opt/remi/php73/php.d/20-ctype.ini,
/etc/opt/remi/php73/php.d/20-curl.ini,
/etc/opt/remi/php73/php.d/20-dba.ini,
/etc/opt/remi/php73/php.d/20-dom.ini,
/etc/opt/remi/php73/php.d/20-enchant.ini,
/etc/opt/remi/php73/php.d/20-exif.ini,
/etc/opt/remi/php73/php.d/20-fileinfo.ini,
/etc/opt/remi/php73/php.d/20-ftp.ini,
/etc/opt/remi/php73/php.d/20-gd.ini,
/etc/opt/remi/php73/php.d/20-gettext.ini,
/etc/opt/remi/php73/php.d/20-iconv.ini,
/etc/opt/remi/php73/php.d/20-intl.ini,
/etc/opt/remi/php73/php.d/20-json.ini,
/etc/opt/remi/php73/php.d/20-mbstring.ini,
/etc/opt/remi/php73/php.d/20-mysqlnd.ini,
/etc/opt/remi/php73/php.d/20-pdo.ini,
/etc/opt/remi/php73/php.d/20-phar.ini,
/etc/opt/remi/php73/php.d/20-posix.ini,
/etc/opt/remi/php73/php.d/20-shmop.ini,
/etc/opt/remi/php73/php.d/20-simplexml.ini,
/etc/opt/remi/php73/php.d/20-soap.ini,
/etc/opt/remi/php73/php.d/20-sockets.ini,
/etc/opt/remi/php73/php.d/20-sqlite3.ini,
/etc/opt/remi/php73/php.d/20-sysvmsg.ini,
/etc/opt/remi/php73/php.d/20-sysvsem.ini,
/etc/opt/remi/php73/php.d/20-sysvshm.ini,
/etc/opt/remi/php73/php.d/20-tokenizer.ini,
/etc/opt/remi/php73/php.d/20-xml.ini,
/etc/opt/remi/php73/php.d/20-xmlwriter.ini,
/etc/opt/remi/php73/php.d/20-xsl.ini,
/etc/opt/remi/php73/php.d/30-mcrypt.ini,
/etc/opt/remi/php73/php.d/30-mysqli.ini,
/etc/opt/remi/php73/php.d/30-pdo_mysql.ini,
/etc/opt/remi/php73/php.d/30-pdo_sqlite.ini,
/etc/opt/remi/php73/php.d/30-wddx.ini,
/etc/opt/remi/php73/php.d/30-xmlreader.ini,
/etc/opt/remi/php73/php.d/40-igbinary.ini,
/etc/opt/remi/php73/php.d/40-ip2location.ini,
/etc/opt/remi/php73/php.d/50-mysql.ini,
/etc/opt/remi/php73/php.d/50-redis.ini

As described at the start of this post, I got PHP processing working again by forcibly disabled the php7_module module from loading, commenting the php_admin_value engine Off line which had been added to every virtualhost declaration, then restarted Apache. My belief is this may have occurred due to a bit of self-negating logic in web/virtualmin and how it was detecting whether mod_php was available to Apache or not, because by default PHP should run through the FastCGI wrapper.

As @Joe suggested in the previous thread discussing a similar problem (https://forum.virtualmin.com/t/ubuntu-16-04-and-php-admin-value-engine-off-php-7/53432/7?u=chriswoods), I looked at each virtual site’s “Website Options” in Server Configuration->Website Options->PHP script execution mode and in each case, “FCGId” is selected; I have the options of “CGI wrapper”, “FCGId” and “FPM”.

I’m keen to hear if anyone has had similar issues and reached the same conclusion, hopefully simply inhibiting php7_module will mean the PHP engine off variables won’t be (re)added to virtualhosts.

Joe et al, have I worked around this the best way, or is there a better way to accomplish what I’ve done above?

1 Like

Yeah, don’t ever ever ever install mod_php! :wink:

Thanks for writing all of this up. I know some other folks have run into similar problems. It is much simpler than this, generally speaking, but I guess we don’t have good docs for how to do it.

But, never installing any version of mod_php is a big part of maintaining your sanity when upgrading or changing PHP packages. I’d like to make it a “Conflict” in our packages because it causes so much trouble and confusion, but that’d make people angry. I may do so, anyway, for CentOS 8 (we’re already gonna make people mad by removing fCGId and suexec CGI execution modes and making PHP only run under PHP-FPM, might as well go all the way in exchange for a much simpler UX).

1 Like

No worries, hopefully Google indexes it all and returns it for people stricken with the same issue. I made a few assumptions based on my primitive understanding of the software, feel free to point out any incorrect assertions. :+1:

I don’t see CentOS 7 going away any time soon! I’ll also be happy to experiment with PHP-FPM down the line as you build it in.