A missing PHP extension can remove database drivers, outbound HTTP support, image handling, or cache adapters even when the interpreter still starts cleanly. Enabling the right module restores the capability an application expects without replacing PHP itself or guessing at the wrong runtime.
Packaged Ubuntu and Debian builds keep each optional module definition under /etc/php/<version>/mods-available and load it per SAPI through runtime-specific /conf.d symlinks for environments such as cli, fpm, and apache2. phpquery reports which versions and SAPIs exist plus whether a module is enabled, while phpenmod creates the live symlink back to the shared module file for the selected runtime.
Current distro packages often enable a newly installed module automatically for every detected SAPI, so the usual job is to confirm the installed branch, install the matching package only when the module file is missing, and run phpenmod only when the target runtime still shows the module as disabled. Keep -v and -s explicit so the change stays limited to the intended PHP branch and SAPI, and expect custom source builds, Homebrew installs, bundled stacks such as XAMPP, and built-in extensions without a separate .ini file to require a different enablement path.
Steps to enable a PHP extension on Ubuntu or Debian:
- List the installed PHP versions and available SAPIs before changing the module state.
$ phpquery -V 8.3 $ phpquery -S -v 8.3 apache2 cli
Replace 8.3 with the installed branch on the host. Current Ubuntu 24.04 packages commonly report 8.3, while current Debian 12 packages commonly report 8.2.
Related: How to check PHP version
- Check whether the module definition already exists under the versioned mods-available directory.
$ ls -l /etc/php/8.3/mods-available/curl.ini -rw-r--r-- 1 root root 68 Jan 27 03:09 /etc/php/8.3/mods-available/curl.ini
If the file is missing, install the matching extension package before trying phpenmod. Built-in extensions without a separate .ini file are not enabled through this helper flow.
- Install the version-matched extension package when the module definition is not already present.
$ sudo apt-get install --yes php8.3-curl Reading package lists... Done Building dependency tree... Done Reading state information... Done The following NEW packages will be installed: php8.3-curl 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Setting up php8.3-curl (8.3.6-0ubuntu0.24.04.x) ... Creating config file /etc/php/8.3/mods-available/curl.ini with new version
Use the explicit versioned package such as php8.3-curl on hosts with multiple PHP branches so the module lands in the intended runtime tree.
- Check the extension state for the target SAPI before enabling it.
$ phpquery -v 8.3 -s cli -m curl No module matches curl (Disabled for cli by local administrator)
A fresh package install often already reports Enabled for cli by maintainer script, Enabled for apache2 by maintainer script, or the matching status for the active runtime. If the query already reports Enabled, the module is active for that runtime and the next action is runtime verification.
Related: How to show loaded PHP extensions
- Enable the extension for the selected PHP version and SAPI when the previous check reports it as disabled.
$ sudo phpenmod -v 8.3 -s cli curl $ phpquery -v 8.3 -s cli -m curl curl (Enabled for cli by local administrator)
If -v or -s is omitted, phpenmod applies the change to every installed PHP version or every detected SAPI instead of only the intended runtime.
phpenmod creates the runtime-specific conf.d symlink back to /etc/php/8.3/mods-available/curl.ini.
- Reload the matching service after enabling the extension for PHP-FPM or the Apache module.
$ sudo systemctl reload apache2
The CLI SAPI does not need a service reload because the next shell invocation reads the updated module list immediately. Use sudo systemctl reload php8.3-fpm when the extension was enabled for fpm instead of apache2.
- Verify that the intended runtime now loads the extension.
$ phpquery -v 8.3 -s cli -m curl curl (Enabled for cli by local administrator) $ php -m | grep --ignore-case '^curl$' curl
Repeat the phpquery check with -s apache2 or -s fpm when the application runs behind a web server, because each SAPI reads its own configuration tree.
Related: How to show loaded PHP extensions
Related: How to find PHP configuration files
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
