start here
Managing Multiple PHP Versions
Real PHP developers often work on more than one project. One project may require PHP 8.2, another may require PHP 8.3, and a new project may already use PHP 8.5 features.
Managing multiple versions is about control. You need to know which version each project expects, which version your shell is running, which version the web server is running, and which extensions are available for that version.
The Project Decides The Version
The first place to check is usually composer.json.
{
"require": {
"php": "^8.3",
"ext-mbstring": "*",
"ext-pdo": "*"
}
}
Then verify the active runtime:
php -v
composer check-platform-reqs
If Composer says your PHP version is not supported, do not change application code. Change or select the correct runtime.
Find Every Visible PHP Binary
On macOS or Linux:
which php
which -a php
php -v
On Windows PowerShell:
where php
php -v
The first path is the one your terminal uses. Other paths may belong to Homebrew, XAMPP, Laragon, MAMP, system packages, custom builds, or version managers.
Switching Versions
How you switch depends on your setup:
- Homebrew can link a different formula.
- Linux packages may provide versioned binaries such as
php8.2andphp8.3. - Windows may switch by changing PATH order.
- Tools such as Herd, Valet, asdf, phpenv, or containers can manage versions per project.
- Docker pins the version in the image tag, such as
php:8.3-fpm.
The exact tool matters less than the verification:
php -v
php --ini
php -m
composer check-platform-reqs
Run those after switching.
CLI And Web Versions Can Differ
One common mistake is switching CLI PHP but leaving the web runtime unchanged.
Example:
CLI: PHP 8.3
FPM: PHP 8.2
That can produce bugs where Composer works but the website fails, or the browser cannot use a syntax feature that works in terminal scripts.
Check CLI:
php -v
php --ini
Check FPM or the web runtime through service status, pool configuration, or a small web-only diagnostic route:
<?php
declare(strict_types=1);
header('Content-Type: text/plain');
echo 'PHP: ' . PHP_VERSION . PHP_EOL;
echo 'SAPI: ' . PHP_SAPI . PHP_EOL;
echo 'Loaded ini: ' . (php_ini_loaded_file() ?: 'none') . PHP_EOL;
Do not leave this public in production. Use it temporarily in a safe environment or behind access control.
Extensions Are Version-Specific
Installing an extension for PHP 8.2 does not automatically make it available for PHP 8.3.
Check extensions after every version switch:
php -m
php -m | grep mbstring
php -m | grep pdo
From PHP:
<?php
declare(strict_types=1);
foreach (['mbstring', 'intl', 'pdo'] as $extension) {
echo $extension . ': ';
echo extension_loaded($extension) ? 'loaded' : 'missing';
echo PHP_EOL;
}
// Prints:
// mbstring: loaded
// intl: loaded
// pdo: loaded
If a project fails after switching PHP versions, missing extensions are one of the first things to check.
Containers Make Versions Explicit
Containers are often the cleanest way to pin project runtime versions.
FROM php:8.3-fpm
That image tag makes the expected version visible. You still need to install required extensions in the image and run checks inside the container:
php -v
php -m
composer check-platform-reqs
Do not rely on host PHP when the project actually runs in a container.
Upgrade Checks
When moving a project from one PHP version to another, verify more than syntax.
Useful checks:
php -v
composer check-platform-reqs
composer update --dry-run
php -l public/index.php
Also run the project's test suite and static analysis if available.
Look for:
- removed or deprecated features
- changed extension availability
- dependencies that do not support the new PHP version
- FPM service still running the old version
- CI using a different version from local development
Version Notes Belong In The Project
A project should record:
- required PHP version
- local version switching tool
- container image tag, if any
- required extensions
- how to verify CLI PHP
- how to verify web PHP
- how to run Composer platform checks
This avoids tribal knowledge and makes onboarding faster.
What You Should Be Able To Do
After this lesson, you should be able to identify a project's required PHP version, find all visible PHP binaries, switch or select the correct runtime, verify extensions, distinguish CLI from web PHP, and explain why containers can make version management clearer.
For junior PHP work, this matters because version mismatches waste time and cause misleading bugs. Good developers prove the runtime before blaming the application.
Practice
Practice: Prove The Project PHP Version
Create a short version-management checklist for a PHP project.
Task
Include:
- where to find the required PHP version in
composer.json - commands to show the active CLI PHP version
- commands to show all visible PHP binaries
- a command to check Composer platform requirements
- a note about checking the web runtime separately from CLI
- a note about extension availability after switching versions
Include one small PHP web diagnostic snippet that prints PHP_VERSION, PHP_SAPI, and loaded php.ini.
Show solution
{
"require": {
"php": "^8.3"
}
}
Then check the active CLI runtime:
php -v
which php
which -a php
composer check-platform-reqs
php -m
On Windows PowerShell, use:
where php
php -v
composer check-platform-reqs
Temporary web diagnostic:
<?php
declare(strict_types=1);
header('Content-Type: text/plain');
echo 'PHP: ' . PHP_VERSION . PHP_EOL;
echo 'SAPI: ' . PHP_SAPI . PHP_EOL;
echo 'Loaded ini: ' . (php_ini_loaded_file() ?: 'none') . PHP_EOL;
CLI checks do not prove the web runtime. PHP-FPM, Apache, Docker, WSL, and local development apps may run a different PHP version or load different extensions. After switching versions, always check extensions again because they are installed and enabled per runtime.