Managing multiple PHP versions on a single Apache server isn’t just a convenience—it’s often a necessity for developers and system administrators who need to maintain legacy applications while developing new projects with modern PHP features. Whether you’re supporting older client websites that require PHP 7.4 while building new applications with PHP 8.3, or testing code compatibility across different versions, Apache’s flexible configuration system makes it possible to run multiple PHP versions simultaneously.
This comprehensive guide will walk you through every step of setting up, configuring, and managing multiple PHP versions on Apache, from basic installation to advanced per-site configuration. By the end, you’ll have a robust development environment that can handle diverse PHP requirements without conflicts or performance issues.
Why You Might Need Multiple PHP Versions on a Single Server
Modern web development often requires juggling multiple PHP versions for various practical reasons:
Legacy Application Support: Older applications may depend on deprecated PHP features or functions that don’t exist in newer versions. WordPress sites, custom CMS platforms, and enterprise applications often require specific PHP versions to function correctly.
Development and Testing: Testing your application across multiple PHP versions ensures compatibility and helps identify potential issues before deployment. This is particularly crucial when planning PHP upgrades for production environments.
Client Requirements: Web agencies and hosting providers frequently manage multiple client projects, each with different PHP version requirements based on their specific application needs and update schedules.
Framework Compatibility: Different PHP frameworks have varying minimum version requirements. Laravel 10 requires PHP 8.1+, while older Symfony versions may need PHP 7.4 for maintenance releases.
Overview of Apache’s Role in Managing PHP Versions
Apache HTTP Server provides several mechanisms for handling PHP execution:
- Module-based execution: PHP runs as an Apache module (mod_php), sharing memory with the web server
- CGI/FastCGI execution: PHP runs as separate processes, offering better security and resource isolation
- PHP-FPM integration: Fast Process Manager provides advanced process management and performance optimization
Each approach offers different advantages for version management, with PHP-FPM generally providing the most flexibility for running multiple versions simultaneously.
Understanding PHP Version Management
The Importance of PHP Compatibility for Web Applications
PHP compatibility extends beyond simply having the right version number. Consider these critical factors:
Syntax Changes: Each PHP version introduces new syntax features and may deprecate older ones. For example, PHP 8.0 introduced named arguments and union types, while removing some legacy features.
Function Availability: Core functions are added, modified, or removed between versions. The mysql_*
functions were removed in PHP 7.0, requiring applications to use mysqli
or PDO instead.
Performance Improvements: Newer PHP versions typically offer significant performance gains. PHP 8.0 provides up to 25% better performance than PHP 7.4 in many scenarios.
Security Updates: Only supported PHP versions receive security patches. Running outdated versions exposes your applications to known vulnerabilities.
How Apache Handles PHP with Modules and Handlers
Apache processes PHP requests through several possible mechanisms:
- Module Handler: PHP code executes within the Apache process using
mod_php
- CGI Handler: Apache spawns separate PHP processes for each request
- FastCGI Handler: Persistent PHP processes handle multiple requests
- Proxy Handler: Apache forwards requests to PHP-FPM pools
Understanding these handlers is crucial for configuring multiple PHP versions effectively.
Installing Multiple PHP Versions
Using apt or yum to Install Multiple PHP Versions
For Ubuntu/Debian Systems:
First, add the Ondřej Surý repository, which maintains multiple PHP versions:
# Add the repository
sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo apt update
# Install multiple PHP versions
sudo apt install php7.4 php7.4-cli php7.4-fpm php7.4-mysql php7.4-curl
sudo apt install php8.1 php8.1-cli php8.1-fpm php8.1-mysql php8.1-curl
sudo apt install php8.3 php8.3-cli php8.3-fpm php8.3-mysql php8.3-curl
For CentOS/RHEL Systems:
Enable the Remi repository for access to multiple PHP versions:
# Install EPEL and Remi repositories
sudo yum install epel-release
sudo yum install https://rpms.remirepo.net/enterprise/remi-release-8.rpm
# Enable specific PHP versions
sudo yum module reset php
sudo yum module enable php:remi-7.4
sudo yum install php php-cli php-fpm php-mysql php-curl
# Install additional versions
sudo yum install php81 php81-php php81-php-fpm php81-php-mysql
sudo yum install php83 php83-php php83-php-fpm php83-php-mysql
Verifying PHP Versions Installed on Your System
Confirm your installations with these verification commands:
# Check all installed PHP versions
ls /usr/bin/php*
# Test specific versions
/usr/bin/php7.4 --version
/usr/bin/php8.1 --version
/usr/bin/php8.3 --version
# Check PHP-FPM services
sudo systemctl status php7.4-fpm
sudo systemctl status php8.1-fpm
sudo systemctl status php8.3-fpm
Expected output should show version information for each installed PHP version without errors.
Installing and Enabling Apache PHP Modules
Installing libapache2-mod-php for Each PHP Version
Install Apache modules for each PHP version you plan to use:
# Install Apache PHP modules
sudo apt install libapache2-mod-php7.4
sudo apt install libapache2-mod-php8.1
sudo apt install libapache2-mod-php8.3
# For CentOS/RHEL
sudo yum install php74-php-apache
sudo yum install php81-php-apache
sudo yum install php83-php-apache
Using a2enmod and a2dismod to Manage Active PHP Modules
Apache can only load one PHP module at a time. Manage active modules with these commands:
# Disable all PHP modules first
sudo a2dismod php7.4
sudo a2dismod php8.1
sudo a2dismod php8.3
# Enable your preferred default version
sudo a2enmod php8.1
# Restart Apache to apply changes
sudo systemctl restart apache2
Important: Only one mod_php
version can be active at a time. For true multi-version support, use PHP-FPM instead of Apache modules.
Using update-alternatives to Set Default PHP Version
Configuring CLI PHP Version with update-alternatives
The update-alternatives
system allows you to manage which PHP version runs when you type php
in the command line:
# Install alternatives for PHP CLI
sudo update-alternatives --install /usr/bin/php php /usr/bin/php7.4 74
sudo update-alternatives --install /usr/bin/php php /usr/bin/php8.1 81
sudo update-alternatives --install /usr/bin/php php /usr/bin/php8.3 83
# Configure the default PHP version
sudo update-alternatives --config php
This command displays a menu where you can select your preferred default PHP version:
Selection Path Priority Status
------------------------------------------------------------
0 /usr/bin/php8.3 83 auto mode
1 /usr/bin/php7.4 74 manual mode
* 2 /usr/bin/php8.1 81 manual mode
3 /usr/bin/php8.3 83 manual mode
Why CLI PHP Version Is Different from Apache’s PHP Handler
The command-line PHP version operates independently from Apache’s PHP handler:
- CLI PHP: Handles command-line scripts, cron jobs, and composer operations
- Apache PHP: Processes web requests through the configured handler
- Different configurations: Each can use different php.ini files and extensions
This separation allows you to use PHP 8.1 for web requests while maintaining PHP 7.4 for legacy command-line tools.
Configuring Apache to Use Different PHP Versions per Site
Using Virtual Hosts for Multiple PHP Configurations
Create separate virtual hosts to assign different PHP versions to different websites:
# Site using PHP 7.4
<VirtualHost *:80>
ServerName legacy-site.local
DocumentRoot /var/www/legacy-site
# Use PHP 7.4 via PHP-FPM
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php/php7.4-fpm.sock|fcgi://localhost"
</FilesMatch>
ErrorLog ${APACHE_LOG_DIR}/legacy-site_error.log
CustomLog ${APACHE_LOG_DIR}/legacy-site_access.log combined
</VirtualHost>
# Site using PHP 8.1
<VirtualHost *:80>
ServerName modern-site.local
DocumentRoot /var/www/modern-site
# Use PHP 8.1 via PHP-FPM
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php/php8.1-fpm.sock|fcgi://localhost"
</FilesMatch>
ErrorLog ${APACHE_LOG_DIR}/modern-site_error.log
CustomLog ${APACHE_LOG_DIR}/modern-site_access.log combined
</VirtualHost>
Assigning PHP Versions Using and SetHandler
The <FilesMatch>
directive allows precise control over which files use specific PHP handlers:
# Handle different file extensions with different PHP versions
<FilesMatch "\.php$">
SetHandler "proxy:unix:/var/run/php/php8.1-fpm.sock|fcgi://localhost"
</FilesMatch>
<FilesMatch "\.php74$">
SetHandler "proxy:unix:/var/run/php/php7.4-fpm.sock|fcgi://localhost"
</FilesMatch>
# Directory-specific PHP version
<Directory "/var/www/legacy-app">
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php/php7.4-fpm.sock|fcgi://localhost"
</FilesMatch>
</Directory>
Setting Up PHP-FPM with Apache for Version Control
Installing and Running PHP-FPM Pools for Each Version
PHP-FPM (FastCGI Process Manager) provides the most flexible solution for multiple PHP versions:
# Install PHP-FPM for each version
sudo apt install php7.4-fpm php8.1-fpm php8.3-fpm
# Enable and start FPM services
sudo systemctl enable php7.4-fpm
sudo systemctl enable php8.1-fpm
sudo systemctl enable php8.3-fpm
sudo systemctl start php7.4-fpm
sudo systemctl start php8.1-fpm
sudo systemctl start php8.3-fpm
# Verify FPM processes are running
sudo systemctl status php7.4-fpm
sudo systemctl status php8.1-fpm
sudo systemctl status php8.3-fpm
Linking Apache Sites to Specific PHP-FPM Versions
Enable the required Apache modules for PHP-FPM communication:
# Enable necessary Apache modules
sudo a2enmod proxy
sudo a2enmod proxy_fcgi
sudo a2enmod rewrite
# Restart Apache
sudo systemctl restart apache2
Configure each site to use its designated PHP-FPM pool:
<VirtualHost *:80>
ServerName app.example.com
DocumentRoot /var/www/app
# PHP 8.1 FPM configuration
<FilesMatch \.php$>
SetHandler "proxy:fcgi://127.0.0.1:9001"
</FilesMatch>
# Alternative unix socket configuration
# <FilesMatch \.php$>
# SetHandler "proxy:unix:/var/run/php/php8.1-fpm.sock|fcgi://localhost"
# </FilesMatch>
</VirtualHost>
PHP-FPM Pool Configuration Example (/etc/php/8.1/fpm/pool.d/app.conf
):
[app]
user = www-data
group = www-data
listen = 127.0.0.1:9001
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
Testing PHP Version Per Site
Creating phpinfo() Pages to Confirm PHP Versions
Create test files to verify each site uses the correct PHP version:
<?php
// Create this file as /var/www/legacy-site/phpinfo.php
echo "<h1>PHP Version Information</h1>";
echo "<p><strong>PHP Version:</strong> " . PHP_VERSION . "</p>";
echo "<p><strong>SAPI:</strong> " . php_sapi_name() . "</p>";
echo "<p><strong>Server:</strong> " . $_SERVER['HTTP_HOST'] . "</p>";
// Display full phpinfo() for detailed configuration
phpinfo();
?>
Access these test pages through your browser:
http://legacy-site.local/phpinfo.php
http://modern-site.local/phpinfo.php
Each should display its configured PHP version and confirm the expected handler (FPM, CGI, or Module).
Troubleshooting Version Conflicts and Apache Restarts
Common issues and their solutions:
503 Service Unavailable Errors:
# Check PHP-FPM service status
sudo systemctl status php8.1-fpm
# Check PHP-FPM logs
sudo tail -f /var/log/php8.1-fpm.log
# Restart if necessary
sudo systemctl restart php8.1-fpm
Wrong PHP Version Displaying:
# Verify Apache configuration syntax
sudo apache2ctl configtest
# Check which modules are loaded
apache2ctl -M | grep php
# Restart Apache to apply changes
sudo systemctl restart apache2
Permission Errors:
# Check socket permissions
ls -la /var/run/php/
# Verify www-data can access sockets
sudo chown www-data:www-data /var/run/php/php*.sock
Managing .htaccess and Directory-Level PHP Settings
Overriding PHP Configurations with .htaccess
When using mod_php (not recommended with multiple versions), you can override PHP settings per directory:
# .htaccess file in specific directory
# Note: This only works with mod_php, not PHP-FPM
# Increase memory limit for this directory
php_value memory_limit 256M
# Set error reporting
php_value error_reporting "E_ALL & ~E_NOTICE"
# Configure upload limits
php_value upload_max_filesize 50M
php_value post_max_size 50M
Using .user.ini for Per-Directory PHP Settings
For PHP-FPM and CGI modes, use .user.ini
files instead:
; .user.ini file in application directory
; This works with PHP-FPM and CGI modes
memory_limit = 256M
upload_max_filesize = 50M
post_max_size = 50M
max_execution_time = 300
error_reporting = E_ALL & ~E_NOTICE
.user.ini Configuration Rules:
- Must be in the same directory as PHP files
- Takes effect after
user_ini.cache_ttl
seconds (default: 300) - Cannot override certain security-sensitive settings
- Applies to the directory and all subdirectories
Best Practices for Version Management and Security
Keeping All PHP Versions Updated
Maintain security across all installed PHP versions:
# Update all packages regularly
sudo apt update && sudo apt upgrade
# Check for security updates specifically
sudo apt list --upgradable | grep php
# Update specific PHP versions
sudo apt install --only-upgrade php7.4*
sudo apt install --only-upgrade php8.1*
sudo apt install --only-upgrade php8.3*
Security Monitoring Strategy:
- Subscribe to PHP security announcements at php.net
- Monitor your distribution’s security advisories
- Use automated tools like
unattended-upgrades
for critical security patches - Test updates in staging environments before production deployment
Disabling Unused Versions and Modules
Remove unnecessary PHP versions to reduce attack surface:
# Disable unused PHP-FPM services
sudo systemctl stop php7.4-fpm
sudo systemctl disable php7.4-fpm
# Remove unused PHP packages (be careful!)
sudo apt autoremove php7.4*
# Disable Apache modules
sudo a2dismod php7.4
sudo systemctl restart apache2
Monitoring Performance and Compatibility
Performance Monitoring:
- Use tools like New Relic or Datadog to monitor PHP performance across versions
- Monitor FPM pool statistics with tools like
php-fpm-status
- Track memory usage and response times for each version
Compatibility Testing:
- Run automated tests against all supported PHP versions
- Use tools like PHPStan or Psalm for static analysis
- Implement continuous integration with multiple PHP version testing
Resource Management:
# Monitor PHP-FPM processes
sudo ps aux | grep php-fpm
# Check memory usage per version
sudo systemctl status php8.1-fpm --no-pager -l
# Monitor socket connections
sudo netstat -ln | grep 9000
Conclusion
Successfully managing multiple PHP versions on Apache requires careful planning and systematic configuration, but the flexibility it provides makes the effort worthwhile. By using PHP-FPM pools with Apache’s proxy modules, you can achieve true version isolation while maintaining optimal performance and security.
The key steps covered in this guide—installing multiple PHP versions, configuring PHP-FPM pools, setting up virtual hosts with version-specific handlers, and implementing proper monitoring—provide a robust foundation for handling diverse PHP requirements on a single server.
Remember to document your configuration thoroughly, including which sites use which PHP versions and why. This documentation becomes invaluable when planning upgrades or troubleshooting issues. Regular testing and monitoring ensure your multi-version setup continues to serve your applications reliably while maintaining security standards.
Start with a simple two-version setup to familiarize yourself with the process, then expand as your requirements grow. With proper implementation, you’ll have a flexible development and hosting environment that can adapt to changing PHP ecosystem demands while maintaining backward compatibility for legacy applications.