How to show loaded PHP extensions

Checking the loaded PHP extension set is one of the fastest ways to explain why database drivers, archive support, image processing, or outbound HTTP features are missing even when the interpreter itself still starts. A quick module check confirms whether the runtime that actually executes the code exposes the capability an application, script, or health check expects.

The PHP CLI can report active extensions in a few complementary ways. The -m switch prints the built-in and loaded PHP and Zend modules for the current binary, –ri shows the configuration block that phpinfo() exposes for one loaded extension, and extension_loaded() can return a direct loaded or not-loaded result inside an inline php -r check.

Extension state is tied to the SAPI that runs the code. The CLI binary, PHP-FPM pools, and the Apache module can each load different php.ini files and additional .ini fragments, so a module shown by php -m is authoritative only for that runtime. When the shell result and the web result do not match, compare the active configuration files before enabling or disabling anything.

Steps to show loaded PHP extensions:

  1. Print the loaded module list for the current CLI runtime.
    $ php -m
    [PHP Modules]
    bcmath
    bz2
    calendar
    Core
    ctype
    curl
    date
    dba
    dom
    exif
    filter
    json
    mbstring
    openssl
    PDO
    Phar
    [... additional PHP modules omitted ...]
    
    [Zend Modules]
    Zend OPcache

    The output includes built-in modules, shared extensions loaded from the active configuration tree, and a separate Zend section for Zend extensions such as Zend OPcache. The exact module list varies by build and loaded configuration files.

  2. Search the module list for one extension when only presence or absence matters.
    $ php -m | grep --ignore-case '^curl$'
    curl

    The exact-name pattern avoids partial matches such as curl_multi. No output means the current runtime did not load that module.

  3. Show the runtime details for one loaded extension by replacing curl with the target module name.
    $ php --ri curl
    
    curl
    
    cURL support => enabled
    cURL Information => 8.19.0
    Age => 11
    Features
    AsynchDNS => Yes
    IPv6 => Yes
    SSL => Yes
    HTTP2 => Yes
    HTTP3 => Yes
    
    Directive => Local Value => Master Value
    curl.cainfo => no value => no value

    If the target module is not loaded, PHP prints Extension 'imagick' not present. instead of the configuration block. Exact feature flags and linked library versions vary by build.

  4. Show the active configuration files when the loaded module list does not match another shell, service, or web request.
    $ php --ini
    Configuration File (php.ini) Path: "/usr/local/etc/php/8.5"
    Loaded Configuration File:         "/usr/local/etc/php/8.5/php.ini"
    Scan for additional .ini files in: "/usr/local/etc/php/8.5/conf.d"
    Additional .ini files parsed:      (none)

    The reported main file and scan directory show where extension= and zend_extension= directives come from for the current CLI binary. Exact paths vary by package source and runtime.

  5. Run an inline PHP check when a script, deployment hook, or health probe only needs a yes or no result.
    $ php -r 'printf("SAPI=%s\ncurl=%s\n", PHP_SAPI, extension_loaded("curl") ? "loaded" : "not loaded");'
    SAPI=cli
    curl=loaded

    The extension name passed to extension_loaded() is case-insensitive, but the result still applies only to the SAPI that executed the code.