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 example
<?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.exe is active
  • which php.ini is loaded
  • whether the extension is enabled
  • whether extension_dir points 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 example
<?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 example
<?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:

  1. Whether the project uses Windows PHP, WSL, Docker, or a dev stack.
  2. What where php returns.
  3. What php -v returns.
  4. What php --ini returns.
  5. What extension_dir is set to.
  6. Which extensions the project requires.
  7. Whether composer check-platform-reqs passes.
  8. 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.ini files
  • 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 whether mbstring, pdo, and openssl are 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 example
<?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.