Current situation: PHP2Shell. Two critical PHP vulnerabilities (CVSS 9.2) allow malicious code without login. Patches since 21 October 2026.What to do now →

Understanding PHP Extensions

Extensions bring database drivers, encryption or caches into PHP. How the types differ, how to load and check them, and what they mean for updates and hardening.

Last updated 5 min readPHP knowledge

In short: PHP extensions are modules written in C that add functions to PHP, such as database drivers (PDO), encryption (Sodium, OpenSSL) or the bytecode cache OPcache. The PHP manual distinguishes core, bundled, external and PECL extensions. They are loaded via extension or zend_extension in the php.ini. Every extension runs inside the PHP process with its privileges. The rule is therefore: load only what is needed, and update together with PHP.

What are PHP extensions?

The core of PHP, the Zend Engine, can execute code, but much of what applications need sits in extensions. They are written in C and are either compiled directly into PHP or loaded at startup as a shared library (.so on Linux, .dll on Windows).

Important for decision-makers: extensions are not plugins of the application but part of the PHP runtime. They are installed by the hosting provider or server admin, not by the agency in the CMS. If an extension is missing, the application usually reports an error during installation or update.

Equally important is the distinction from Composer packages. Composer installs libraries that are written in PHP and sit in the project folder, such as a mail or PDF package. Extensions, by contrast, are compiled code that is loaded when PHP starts and applies to all applications on the server. Many Composer packages require certain extensions and note this in their composer.json with entries such as ext-intl or ext-sodium. Anyone who wants to check whether a project finds all the necessary extensions can run composer check-platform-reqs in the project folder.

What types of extensions are there?

The PHP manual assigns extensions to four groups:

Group Meaning according to the manual Examples from the manual
Core part of the PHP core, cannot be disabled Arrays, Date/Time, Hash, JSON, PCRE, SPL, Strings
Bundled shipped with PHP BC Math, Ctype, Fileinfo, Filter, GD, intl, mbstring, PDO, Sessions
External shipped with PHP, need external libraries cURL, DOM, GMP, LDAP, OpenSSL, Sodium, Zip
PECL available via PECL, partly with external libraries APCu, Memcached, MongoDB, Yaml

The assignment can change. With PHP 8.4, according to the release page, the extensions IMAP, OCI8, PDO_OCI and pspell were removed from the distribution and moved to PECL. Anyone who uses them needs a separate installation after the upgrade, which also has to be maintained.

How are extensions loaded?

According to the manual, shared extensions are loaded via the extension directive in the php.ini; Zend extensions, which reach deeper into the engine, via zend_extension. Both may only appear in the php.ini. The directory is defined by extension_dir, for which the manual recommends an absolute path.

; normal extensions
extension=pdo_mysql
extension=sodium
extension=intl

; Zend extension: OPcache (load before Xdebug if both are active)
zend_extension=opcache

Distributions such as Debian and Ubuntu place a small .ini file of its own for each extension in the scan directory, for example under /etc/php/8.3/mods-available/, and enable it per SAPI with phpenmod and phpdismod. How PHP reads these files is explained in The php.ini explained.

Extensions are usually installed through the package manager, for example as the package php8.3-intl. PECL extensions can be built with pecl or phpize. According to the manual, PECL is deprecated; the PHP Installer for Extensions (PIE) is recommended. Anyone who builds PHP entirely themselves will find notes under Compiling PHP from source.

Checking extensions: which ones are really loaded?

The following commands are purely read-only. Note that the command line can load different extensions than the website.

php -m                              # CLI modules
php-fpm8.3 -m                       # modules of PHP-FPM 8.3 (name depends on the distribution)
php --re sodium | head -n 5         # functions of an extension
php --ri opcache                    # configuration of an extension
php -r 'var_dump(extension_loaded("intl"));'

In code, applications use extension_loaded() to check whether an extension is present and get_loaded_extensions() to see which ones are loaded:

<?php
$benoetigt = ['pdo_mysql', 'mbstring', 'intl', 'sodium'];
$fehlend = array_diff($benoetigt, array_map('strtolower', get_loaded_extensions()));
echo $fehlend ? 'Fehlt: ' . implode(', ', $fehlend) : 'Alle Erweiterungen vorhanden';

Extensions and security: less is more

Extensions run in the same process as PHP and with the same privileges. A flaw in an extension can therefore weigh as heavily as a flaw in the core. Four rules follow:

  1. Load only what is needed. Every additional extension enlarges the attack surface. Check your list against the application's system requirements.
  2. Update together with PHP. Bundled extensions come with the PHP update. PECL and third-party extensions need their own updates and must match the new PHP version.
  3. No development tools in production. Debuggers and profilers such as Xdebug belong only in development environments.
  4. Block functions selectively. Where extensions bring functions for system commands, using disable_functions correctly helps.

With PHP2Shell, the flaws lie in the core of PHP, not in an extension. Switching off modules does not close them; what is needed is the update to 8.5.12, 8.4.27, 8.3.36 or 8.2.35 with a restart of all PHP processes. After the update you should check whether all extensions are loaded again, because missing modules often only show up with certain functions. How to keep dependencies under control in the long term is described in Keeping dependencies up to date.

How does PHP SOS help?

  • Take stock: For each SAPI we list all loaded extensions with origin and version.
  • Clear out: We compare the list with your application's needs and deactivate what is superfluous after testing.
  • Update: As part of server hardening we bring PHP and all third-party extensions to a maintained state.
  • Check after updates: We verify that all required modules are loaded again after every PHP update.

Frequently asked questions

What is the difference between extension and zend_extension?

With extension, PHP loads normal extensions such as database drivers. With zend_extension, according to the manual, Zend extensions are loaded that reach deeper into the engine, for example OPcache or Xdebug. Both directives may only appear in the php.ini.

How do I see which extensions are loaded?

On the command line with php -m; for the website via the function get_loaded_extensions() in a temporary test file or via php-fpm -m of the respective version. Note that the CLI and the web SAPI can load different extensions.

What is PECL and what is PIE?

PECL is a directory of PHP extensions provided through the PEAR package system. According to the PHP manual, PECL is deprecated; the PHP Installer for Extensions (PIE) is recommended instead.

Does disabling an extension close PHP2Shell?

No. The PHP2Shell flaws lie in the core of PHP, not in an extension that can be switched off. Fewer extensions reduce the attack surface in general but do not replace the update to a corrected version.

Sources

Immediate contact

Every hour counts. Write to us now.

Briefly describe your system, PHP version and observation. We will get back to you, clarify the situation and work remotely until the incident is closed and documented.

Immediate help