PHP Install

La Lakshmi Priya Updated 17 Oct 2026
12 min read ·Lesson 14 of 22

To run PHP code, your computer (or a server) needs the PHP interpreter — the program that reads .php files and executes them. This lesson explains the different ways to install it, how to verify the installation, and how to configure PHP for development.


What Exactly Are You Installing?

A PHP installation contains several parts. Knowing them makes troubleshooting much easier.

ComponentWhat It IsWhy It Matters
PHP CLIThe php command you run in a terminalRuns scripts, the built-in server, and tools like Composer
PHP-FPMA background service that runs PHP for web servers such as NginxUsed on real servers and full local stacks
php.iniThe main configuration fileControls error display, memory limits, upload sizes, extensions, timezone
ExtensionsOptional modules (for example mbstring, pdo_mysql, curl)Add features such as database access, multibyte strings, and HTTP requests

Note: The CLI and PHP-FPM can use different php.ini files. A setting you change for the terminal may not apply to your web server. This is one of the most common sources of confusion and is covered under Common Mistakes below.


Choosing an Installation Method

MethodBest ForAdvantagesLimitations
Native install (Windows ZIP, Homebrew, apt)Learning and everyday developmentFast, uses the real php command, easy to updateYou manage extensions and configuration yourself
All-in-one stack (XAMPP, Laragon, MAMP)Quick start with Apache + MySQL includedOne installer gives PHP, a web server, and a databasePHP version may lag behind the latest release; hides how parts connect
DockerTeams and matching production exactlySame environment on every machine, easy version switchingRequires learning Docker basics

For this tutorial, a native install is recommended. It keeps things simple and teaches you how PHP is actually configured. You can add MySQL separately when you reach the database lessons.


Installing PHP on Windows

Step 1 — Download PHP

  1. Go to https://windows.php.net/download/.
  2. Under the latest PHP 8 version, download the x64 Non Thread Safe ZIP file.

Why "Non Thread Safe"? Thread-safe builds are only needed when PHP runs inside a multi-threaded web server module, such as Apache's mod_php on Windows. For the command line, the built-in server, and FastCGI setups, the Non Thread Safe build is the recommended choice because it avoids unnecessary locking overhead.

Step 2 — Extract the Files

Extract the ZIP to a short path without spaces, for example:

C:\php

You should now have C:\php\php.exe.

Step 3 — Add PHP to the PATH

The PATH environment variable tells Windows where to look for programs. Adding C:\php lets you type php in any terminal instead of the full path C:\php\php.exe.

  1. Press Start, search for "Edit the system environment variables", and open it.
  2. Click Environment Variables…
  3. Under User variables, select Path and click Edit.
  4. Click New and enter C:\php.
  5. Click OK on every window.
  6. Close and reopen your terminal. Already-open terminals keep the old PATH.

Step 4 — Create php.ini

The ZIP contains two template files:

  • php.ini-development — shows errors, suited to learning and development
  • php.ini-production — hides errors, suited to live servers

Copy php.ini-development and rename the copy to php.ini in the same folder.

Step 5 — Enable Common Extensions

Open C:\php\php.ini in a text editor and find this line:

;extension_dir = "ext"

Remove the leading semicolon:

extension_dir = "ext"

Then remove the semicolon in front of these extension lines:

extension=curl
extension=fileinfo
extension=intl
extension=mbstring
extension=openssl
extension=pdo_mysql
extension=sodium
extension=zip

Why the semicolons? In php.ini, a line starting with ; is a comment. The template ships with most extensions commented out so that you enable only what you need. extension_dir tells PHP the folder where the extension .dll files are stored.

Step 6 — Verify

php -v

Expected output (version numbers will vary):

PHP 8.5.x (cli) (built: ...) (NTS Visual C++ 2022 x64)
Copyright (c) The PHP Group
Zend Engine v4.5.x, Copyright (c) Zend Technologies

If you see 'php' is not recognized as an internal or external command, the PATH step did not take effect — see Common Mistakes.

Alternative: Laragon or XAMPP

If you prefer a graphical installer that also includes Apache and MySQL, Laragon and XAMPP are popular choices on Windows. Check which PHP version they bundle before installing, and note that their php.ini lives inside their own installation folder.


Installing PHP on macOS

macOS no longer ships with PHP. The standard way to install it is with Homebrew, a package manager for macOS.

Step 1 — Install Homebrew (if needed)

Follow the one-line installation command on https://brew.sh.

Step 2 — Install PHP

brew install php

This installs the latest stable PHP version along with common extensions.

To install a specific version instead:

brew install php@8.4

Versioned formulas are not linked automatically. Homebrew prints instructions after installation, usually:

brew link php@8.4 --force --overwrite

Step 3 — Verify

php -v

Step 4 — Find php.ini

php --ini

Example output:

Configuration File (php.ini) Path: /opt/homebrew/etc/php/8.5
Loaded Configuration File:         /opt/homebrew/etc/php/8.5/php.ini
Scan for additional .ini files in: /opt/homebrew/etc/php/8.5/conf.d

The paths shown are for Apple Silicon Macs. On Intel Macs, Homebrew uses /usr/local instead of /opt/homebrew.


Installing PHP on Linux (Ubuntu / Debian)

Step 1 — Install PHP and Common Extensions

sudo apt update
sudo apt install php-cli php-mbstring php-xml php-curl php-mysql php-intl php-zip php-gd

What each package provides:

PackagePurpose
php-cliThe php command-line interpreter
php-mbstringMultibyte (Unicode) string functions such as mb_strlen()
php-xmlDOM, SimpleXML, XMLReader, and XMLWriter
php-curlHTTP requests to other servers and APIs
php-mysqlMySQLi and PDO MySQL drivers
php-intlInternationalization: locale-aware formatting, transliteration
php-zipReading and creating ZIP archives
php-gdImage creation and manipulation

Note: Installing the plain php package on Ubuntu may also install Apache. Installing php-cli and individual extensions avoids pulling in a web server you may not want.

Ubuntu's official repositories contain one PHP version per Ubuntu release (for example, Ubuntu 24.04 provides PHP 8.3). For newer versions, many developers use the widely used PPA maintained by Ondřej Surý:

sudo add-apt-repository ppa:ondrej/php
sudo apt update
sudo apt install php8.4-cli php8.4-mbstring php8.4-xml php8.4-curl php8.4-mysql

With this PPA, package names include the version number, so several versions can be installed side by side.

Step 2 — Verify

php -v

Configuration File Locations

On Ubuntu, each PHP version and each mode has its own configuration directory:

/etc/php/8.3/cli/php.ini     ← used by the php command
/etc/php/8.3/fpm/php.ini     ← used by PHP-FPM (web server)
/etc/php/8.3/apache2/php.ini ← used by Apache mod_php

Switching Between Installed Versions

sudo update-alternatives --config php

This shows a numbered list of installed PHP versions and lets you choose which one the php command runs.


Using PHP With Docker

Docker runs PHP inside an isolated container, so you do not install PHP on your system at all. The official php images are published on Docker Hub.

Run a Script

docker run --rm -v "$PWD":/app -w /app php:8.4-cli php hello.php

What Each Part Does

PartMeaning
docker runStart a new container
--rmDelete the container when it finishes, so stopped containers do not pile up
-v "$PWD":/appMount the current folder into the container at /app, so PHP can see your files
-w /appSet the working directory inside the container
php:8.4-cliThe official image: PHP 8.4, command-line variant
php hello.phpThe command to run inside the container

Run the Development Server

docker run --rm -p 8000:8000 -v "$PWD":/app -w /app php:8.4-cli php -S 0.0.0.0:8000
  • -p 8000:8000 connects port 8000 on your computer to port 8000 in the container.
  • 0.0.0.0 makes the server listen on all network interfaces inside the container. Using localhost here would make it unreachable from your browser, because localhost inside a container refers to the container itself.

Changing the version is as simple as replacing 8.4 with another tag, which makes Docker useful for testing code against several PHP versions.

Note: On Windows Command Prompt, replace "$PWD" with "%cd%". In PowerShell, use ${PWD}.


Verifying Your Installation

These commands work on every platform.

CommandWhat It Shows
php -vThe installed PHP version
php -mAll loaded extensions
php --iniWhich php.ini file is loaded and where extra .ini files are scanned
php -iThe complete configuration (long output)
php -r "echo PHP_VERSION;"Runs a single line of PHP code directly

Check for a Specific Extension

# Linux / macOS
php -m | grep mbstring

# Windows (Command Prompt or PowerShell)
php -m | findstr mbstring

If the extension name is printed, it is loaded. No output means it is missing or disabled.

Test With a Script

Create check.php:

<?php
echo "PHP version: " . PHP_VERSION . PHP_EOL;
echo "Operating system: " . PHP_OS_FAMILY . PHP_EOL;
echo "Loaded php.ini: " . (php_ini_loaded_file() ?: "none") . PHP_EOL;
echo "mbstring loaded: " . (extension_loaded('mbstring') ? "yes" : "no") . PHP_EOL;

Run it:

php check.php

Output (example)

PHP version: 8.5.1
Operating system: Linux
Loaded php.ini: /etc/php/8.5/cli/php.ini
mbstring loaded: yes

How the Script Works

  • PHP_VERSION, PHP_OS_FAMILY, and PHP_EOL are predefined constants. PHP_OS_FAMILY returns Windows, Darwin (macOS), Linux, BSD, Solaris, or Unknown. PHP_EOL is the correct line ending for the current operating system.
  • The . operator joins strings together (string concatenation).
  • php_ini_loaded_file() returns the path of the loaded php.ini, or false if none was loaded.
  • ?: is the short ternary operator: if the left side is falsy (such as false), the right side "none" is used instead.
  • extension_loaded('mbstring') returns true or false, and the ternary ? "yes" : "no" turns that into readable text.

A missing php.ini ("none") is a common reason why extensions are not loaded, so this script quickly reveals configuration problems.


Configuring php.ini for Development

During development, you want PHP to report every problem loudly. Open the php.ini file shown by php --ini and make sure these values are set:

error_reporting = E_ALL
display_errors = On
display_startup_errors = On
log_errors = On
date.timezone = Asia/Kolkata

What Each Setting Does

SettingEffectWhy
error_reporting = E_ALLReport every type of error, warning, notice, and deprecationSmall warnings often reveal real bugs, such as undefined variables
display_errors = OnShow errors in the outputYou see problems immediately instead of a blank page
display_startup_errors = OnShow errors that happen while PHP itself startsReveals broken extension configuration
log_errors = OnAlso write errors to the error logUseful for problems that occur in background requests
date.timezoneDefault timezone for date functionsEnsures date() shows your local time; use your own zone, such as America/New_York or Europe/London

php.ini-development already contains most of these values. The timezone usually needs to be set manually; when it is not set, PHP uses UTC.

After saving:

  • The CLI reads php.ini every time it starts, so the next php command uses the new settings.
  • PHP-FPM and Apache read it only at startup, so you must restart them (for example, sudo systemctl restart php8.3-fpm).

Warning: Never use display_errors = On on a live production server. Error messages can reveal file paths, database names, and query details to attackers. Production configuration is covered in Error Reporting in Production.


Viewing Configuration With phpinfo()

phpinfo() prints a complete HTML report of the PHP configuration.

<?php
phpinfo();

Save it as info.php, start the development server, and open http://localhost:8000/info.php. The page lists the PHP version, loaded php.ini, enabled extensions, and every configuration value.

This is useful because the web server's configuration may differ from the CLI's. phpinfo() shows the configuration as the web server sees it.

Warning: Delete info.php after use. On a public server, this page gives attackers a detailed map of your environment.


Choosing a Code Editor

Any text editor works, but a good editor catches mistakes as you type.

  • Visual Studio Code (free) — install a PHP extension such as PHP Intelephense for autocompletion, error detection, and go-to-definition.
  • PhpStorm (paid, free for students and some open-source projects) — a full IDE with deep PHP support, refactoring, and debugging tools.

Configure the editor to save files as UTF-8 without BOM. A byte-order mark (BOM) at the start of a file is invisible but is sent as output before your PHP code runs, which can cause the "headers already sent" error discussed in the PHP Tags lesson.


Common Mistakes

'php' is not recognized / php: command not found

Why it happens: The folder containing the PHP executable is not in PATH, or the terminal was opened before PATH was updated.

Fix: Recheck the PATH entry, then close all terminal windows and open a new one. In VS Code, restart the editor, because its integrated terminal inherits the environment from when VS Code started.

Editing the Wrong php.ini

What happens: You change a setting, but nothing changes.

Why it happens: There may be several php.ini files — one for the CLI, one for PHP-FPM, one for Apache, or one per installed version.

Fix: For the CLI, run php --ini. For the web server, check the "Loaded Configuration File" line in phpinfo(). Edit the file that is actually loaded.

"Loaded Configuration File: (none)"

Why it happens: On Windows, the template was not copied to php.ini, or it was saved as php.ini.txt.

Fix: Copy php.ini-development to php.ini in the PHP folder and enable file name extensions in File Explorer to confirm the name.

"Call to undefined function mb_strlen()" (or another extension function)

Why it happens: The extension providing the function is not installed or not enabled.

Fix: Check php -m. On Windows, uncomment the extension= line and confirm extension_dir is set. On Linux, install the package (for example php-mbstring). Restart PHP-FPM or Apache if the error appears in the browser.

Changes Not Applied to the Website

Why it happens: PHP-FPM and Apache keep the configuration they loaded at startup.

Fix: Restart the service after editing its php.ini.

Different Versions in the Terminal and the Browser

What happens: php -v shows 8.4, but phpinfo() shows 8.3.

Why it happens: The CLI and the web server are using different PHP installations.

Fix: Decide which version you want and configure both to use it — for example, by pointing Nginx to the matching PHP-FPM socket or selecting the version in your local stack's settings.


Best Practices

  • Develop on the same major and minor version as production. Code using PHP 8.4 features fails on a PHP 8.2 server. Check your hosting provider's version before choosing language features.
  • Install only the extensions you need. Fewer extensions mean less memory use and a smaller attack surface.
  • Keep PHP updated within its branch. Patch releases (8.4.1 → 8.4.2) contain bug and security fixes and are designed not to break compatibility.
  • Use development settings locally and production settings on servers. Start from the matching template file rather than mixing them.
  • Record your PHP requirements in the project. When you start using Composer, declare the required version (for example "php": ">=8.2") in composer.json so others know which version the project needs.

Official reference: https://www.php.net/manual/en/install.php

0 Comments

Reviewed before they appear

No comments yet.

PHP
Ask about this post
AI Ask about this post

Ask questions about PHP Install and get answers drawn from it.

Signed-in readers only.