Skip to content

/flags/php/php-m-list-modules

php -m: list loaded PHP extensions (check if an extension is installed)

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
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:

bash
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 json

Output

[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.

CommandShows
php -mAll loaded extensions (PHP and Zend)
php --ri nameInformation and settings of one extension, like its phpinfo() section
php --re nameFunctions, classes, constants and ini entries of an extension
php -iFull phpinfo() output in text form
php --iniWhich php.ini and extra .ini files are loaded
php -n -mExtensions 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:

bash
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 images

On 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 -m reports the one that php resolves to on the PATH.
  • A broken extension= line prints a startup warning such as Unable to load dynamic library on every run, before the module list.
  • Composer checks extensions of the PHP that runs Composer. If CI uses another PHP binary than production, composer install can 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.

Sources