php -m: list loaded PHP extensions (check if an extension is installed)
- tool
- PHP
- command
- php
- flag
- -m
- default
- -
php -m prints the names of every compiled-in and loaded extension of the PHP command-line interpreter, one per line, under [PHP Modules], followed by [Zend Modules] such as OPcache or Xdebug. Use it to check whether mbstring, intl, pdo_mysql or redis is available before running Composer or an app that needs it. A missing extension usually shows up at run time as Call to undefined function (for example mb_strlen()) or as a Composer platform requirement error.
Listing and checking
The example uses PHP 8.4 compiled to WebAssembly (php-wasm, from the WordPress Playground project), which ships with a fixed set of extensions:
npm init -y >/dev/null
npm install --silent --no-audit --no-fund @php-wasm/node@3.1.56 @php-wasm/universal@3.1.56 >/dev/null 2>&1
cat > php.mjs <<'JS'
// Minimal "php" command: copies *.php files into the virtual file system and runs the CLI
import fs from "node:fs";
import { PHP } from "@php-wasm/universal";
import { loadNodeRuntime } from "@php-wasm/node";
const php = new PHP(await loadNodeRuntime("8.4", { emscriptenOptions: { processId: 1 } }));
php.mkdir("/app");
for (const f of fs.readdirSync(".").filter((f) => f.endsWith(".php"))) php.writeFile(`/app/${f}`, fs.readFileSync(f));
php.chdir("/app");
const r = await php.cli(["php", ...process.argv.slice(2)]);
process.stdout.write(await r.stdoutText);
process.stdout.write(await r.stderrText);
process.exit(await r.exitCode);
JS
node php.mjs -m | head -12
echo "..."
node php.mjs -m | sed -n '/\[Zend Modules\]/,$p'
echo "== is it loaded?"
for ext in mbstring pdo_sqlite intl; do
if node php.mjs -m | grep -qix "$ext"; then echo "$ext: yes"; else echo "$ext: no"; fi
done
node php.mjs -r 'var_dump(extension_loaded("mbstring"), function_exists("mb_strlen"));'
echo "== details of one extension"
node php.mjs --ri jsonOutput
[PHP Modules] bcmath calendar Core ctype curl date dns_polyfill dom exif fileinfo filter ... [Zend Modules] Zend OPcache == is it loaded? mbstring: yes pdo_sqlite: yes intl: no bool(true) bool(true) == details of one extension json json support => enabled
The list is alphabetical within each section and mixes extensions built into the binary (Core, date, standard) with shared ones loaded from php.ini. grep -qix checks for an exact, case-insensitive line, which is what scripts and CI steps need.
Related options
| Command | Shows |
|---|---|
| php -m | All loaded extensions (PHP and Zend) |
| php --ri name | Information and settings of one extension, like its phpinfo() section |
| php --re name | Functions, classes, constants and ini entries of an extension |
| php -i | Full phpinfo() output in text form |
| php --ini | Which php.ini and extra .ini files are loaded |
| php -n -m | Extensions compiled into the binary, without any php.ini |
| php -r 'var_dump(extension_loaded("intl"));' | true or false from code |
Adding a missing extension
How you install an extension depends on how PHP was installed:
sudo apt install php8.4-intl # Debian/Ubuntu packages (one package per extension)
sudo dnf install php-intl # Fedora/RHEL
pecl install redis # PECL builds, then add extension=redis to php.ini
docker-php-ext-install intl pdo_mysql # official php Docker imagesOn Windows, the DLLs are in the ext folder of the PHP zip; enable them with lines such as extension=intl in php.ini. After installing, php -m must list the extension; if it does not, check that the right php.ini is loaded with php --ini, and test a single run with php -d extension=intl -m.
Pitfalls
- Several PHP versions can be installed side by side (
php8.2,php8.4);php -mreports the one thatphpresolves to on thePATH. - A broken
extension=line prints a startup warning such asUnable to load dynamic libraryon every run, before the module list. - Composer checks extensions of the PHP that runs Composer. If CI uses another PHP binary than production,
composer installcan pass in one and fail in the other.
FAQ
Why is an extension listed by php -m but missing in my web page?
The CLI and the web server (PHP-FPM, Apache mod_php) load separate php.ini files and may even be different PHP versions. Check the web side with phpinfo() or php-fpm -m, enable the extension in that configuration and reload the service.
How do I see the version and settings of one extension?
php --ri name prints the extension's information block, the same section phpinfo() shows, and php --re name lists its functions, classes and constants. Both fail with an error if the extension is not loaded.
Is the name case-sensitive?
php -m prints names as the extensions register them (for example Core, PDO, SimpleXML). extension_loaded() compares names case-insensitively, but grep does not, so use grep -i when you search the list.