start here
Windows Setup
On Windows, PHP can run directly in PowerShell, through a local development stack, inside WSL, or inside containers. The important skill is proving which runtime your project is using.
Windows PHP setup problems usually come from PATH order, multiple PHP installs, missing DLL extensions, wrong php.ini, or mixing Windows PHP with WSL PHP without realising they are separate environments.
Common Windows PHP Setups
Typical options include:
- official PHP ZIP builds
- XAMPP, Laragon, WampServer, or similar stacks
- Herd or other modern local development apps
- WSL with Linux PHP
- Docker Desktop containers
Any of these can work. The professional habit is recording which one the project expects and then proving the active PHP runtime.
Find The Active PHP Binary
In PowerShell:
where php
php -v
Example output:
C:\php\php.exe
PHP 8.3.12 (cli)
If where php prints several paths, Windows will use the first one found on PATH. That first result is the one php runs from the terminal.
If php -v fails, PHP is either not installed, not on PATH, or the terminal session has not picked up the updated PATH yet.
PATH On Windows
PATH is the list of directories Windows searches when you type php.
You can inspect it in PowerShell:
$env:Path -split ';'
After changing PATH through Windows settings or an installer, close and reopen PowerShell. Existing terminals may not see the update.
Avoid leaving old PHP installs earlier on PATH. That is how a project accidentally runs C:\xampp\php\php.exe when you expected C:\php\php.exe.
php.ini And Extensions
Check the loaded configuration:
php --ini
Check extensions:
php -m
php -m | Select-String mbstring
Important Windows-specific detail: many extensions are DLL files loaded from extension_dir.
Check the configured extension directory:
php -i | Select-String "extension_dir"
If extension_dir points at the wrong folder, PHP may not load extensions even when the .dll files exist somewhere else.
Inside PHP:
<?php
declare(strict_types=1);
echo 'Loaded ini: ' . (php_ini_loaded_file() ?: 'none') . PHP_EOL;
echo 'extension_dir: ' . ini_get('extension_dir') . PHP_EOL;
foreach (['mbstring', 'pdo', 'openssl'] as $extension) {
echo $extension . ': ';
echo extension_loaded($extension) ? 'loaded' : 'missing';
echo PHP_EOL;
}
// Prints:
// Loaded ini: C:\php\php.ini
// extension_dir: ext
// mbstring: loaded
// pdo: loaded
// openssl: loaded
Composer On Windows
Composer uses a PHP runtime too. Check both:
php -v
composer --version
composer check-platform-reqs
If Composer reports missing extensions, do not immediately edit application code. First confirm:
- which
php.exeis active - which
php.iniis loaded - whether the extension is enabled
- whether
extension_dirpoints at the correct DLL folder
Windows PHP And WSL Are Separate
Windows PHP and WSL PHP are different runtimes.
PowerShell:
where php
php -v
WSL shell:
which php
php -v
Those commands can show different PHP versions, extensions, configuration files, and filesystem paths.
If a project runs inside WSL, install and verify PHP inside WSL. If it runs in PowerShell or a Windows stack, verify Windows PHP. Mixing the two is a common source of confusion.
Run A First Script
Create hello.php:
<?php
declare(strict_types=1);
echo 'Hello from PHP ' . PHP_VERSION . PHP_EOL;
// Prints:
// Hello from PHP 8.3.12
Run it:
php hello.php
php -l hello.php
Run A Local Web Request
Create public/index.php:
<?php
declare(strict_types=1);
header('Content-Type: text/plain');
echo 'Hello over HTTP' . PHP_EOL;
echo 'SAPI: ' . PHP_SAPI . PHP_EOL;
// Browser output:
// Hello over HTTP
// SAPI: cli-server
Start the built-in server:
php -S 127.0.0.1:8000 -t public
Open:
http://127.0.0.1:8000/
This proves Windows CLI PHP can serve a local request. It does not prove IIS, Apache, Nginx, WSL, or Docker are configured.
Windows Setup Checklist
For a project setup note, record:
- Whether the project uses Windows PHP, WSL, Docker, or a dev stack.
- What
where phpreturns. - What
php -vreturns. - What
php --inireturns. - What
extension_diris set to. - Which extensions the project requires.
- Whether
composer check-platform-reqspasses. - How to run the local server.
This gives the next developer a way to prove their environment instead of guessing.
What You Should Be Able To Do
After this lesson, you should be able to find the active PHP binary on Windows, inspect PATH, check php.ini, verify extension_dir, check loaded extensions, understand the Windows/WSL boundary, and run a basic PHP script and local server.
For junior PHP work, this matters because Windows can have several PHP runtimes installed at once. The useful skill is identifying the one your project is actually using.
Practice
Practice: Create A Windows PHP Setup Note
Create a short Windows setup note for a PHP project.
Task
Include PowerShell commands to show:
- active PHP binary
- PHP version
- loaded
php.inifiles - loaded extensions
- configured
extension_dir - Composer platform requirements
Also note whether the project is using Windows PHP, WSL, Docker, or a local development stack.
Show solution
A useful Windows setup note proves which runtime the project uses.
where php
php -v
php --ini
php -m
php -i | Select-String "extension_dir"
composer check-platform-reqs
Example notes:
Runtime choice: Windows PHP in PowerShell
Active PHP: C:\php\php.exe
Project does not use WSL for PHP commands
Composer platform check: passes
If the project uses WSL or Docker, run equivalent checks inside that environment. PowerShell PHP and WSL PHP are separate runtimes.
Task: Path And Binary
Create a checklist for diagnosing the wrong PHP version on Windows.
Requirements
Include:
- a command to show every visible
php.exe - a command to inspect PATH entries
- a command to show the active PHP version
- a note about reopening PowerShell after PATH changes
- a note about old dev stack PHP paths appearing before the expected PHP path
Afterward, add a short explanation of why the first where php result matters.
Show solution
where php
$env:Path -split ';'
php -v
php --ini
Example issue:
C:\xampp\php\php.exe
C:\php\php.exe
In that example, C:\xampp\php\php.exe wins because it appears first. If the project expects C:\php\php.exe, update PATH so the expected directory appears earlier, then open a new PowerShell window.
The first where php result matters because it is the executable Windows runs when you type php.
Task: Extension Dir Check
Create a Windows extension diagnostic.
Requirements
Include:
- a PowerShell command to show loaded extensions
- a PowerShell command to show
extension_dir - a PHP snippet that prints loaded
php.ini,extension_dir, and whethermbstring,pdo, andopensslare loaded
Use strict types in the PHP snippet. Keep example output inside the PHP code block as comments.
Afterward, add a short note explaining why the DLL folder matters on Windows.
Show solution
php -m
php -i | Select-String "extension_dir"
PHP diagnostic:
<?php
declare(strict_types=1);
echo 'Loaded ini: ' . (php_ini_loaded_file() ?: 'none') . PHP_EOL;
echo 'extension_dir: ' . ini_get('extension_dir') . PHP_EOL;
foreach (['mbstring', 'pdo', 'openssl'] as $extension) {
echo $extension . ': ';
echo extension_loaded($extension) ? 'loaded' : 'missing';
echo PHP_EOL;
}
// Prints:
// Loaded ini: C:\php\php.ini
// extension_dir: ext
// mbstring: loaded
// pdo: loaded
// openssl: loaded
The DLL folder matters because Windows PHP loads many extensions from extension_dir. If php.ini points at the wrong directory, extensions can stay missing even when the DLL files exist elsewhere on disk.