Skip to content

PHP Extensions and ionCube

Every CorePanel server starts with the extension set a normal PHP site needs. Beyond that, fifteen extensions can be added and removed from the panel — the ones mainstream hosting software asks for — and anything else in the Remi repository can still be installed by hand.

The one thing to hold on to before either route: an extension belongs to a PHP version, not to an account. There is one php-fpm master per version and one set of extensions behind it, so installing imagick for PHP 8.3 gives it to every account running 8.3. That is a property of PHP, not a CorePanel limitation — see It applies to a whole PHP version.

PHP → Extensions, in the admin area. Pick a version along the top; the list underneath is that version’s.

Each extension shows one of:

StateWhat it means
installedThe package is here and the interpreter loads it
installed, not loadedThe package is here but PHP does not load it — its .ini was disabled by hand
not in the repositoryYour package repository does not offer it for that version
not for this versionIt does not exist for that PHP branch at all. Normal, not a fault

The catalogue is fifteen extensions, not the repository’s ~180: imagick, redis, memcached, soap, ldap, imap, bcmath, posix, ioncube-loader, sodium, gmp, tidy, apcu, igbinary and mongodb. Anything else somebody installed over SSH is listed underneath as installed outside CorePanel — it works exactly as it did, it is simply not CorePanel’s to add or remove.

The same from a shell:

Terminal window
corepanel php extensions # every version
corepanel php extensions --php 8.3 # just one
corepanel php extensions install 8.3 imagick
corepanel php extensions remove 8.3 imagick

Removing an extension another installed package depends on is refused, and the message names what would have gone with it. dnf remove takes dependents along: the redis extension requires igbinary, so removing igbinary would quietly uninstall redis too — and the site that stops caching belongs to an account whose owner was never asked.

Remove the dependent extension first if that is genuinely what you want.

The other direction is not blocked, and is worth knowing about: removing an extension also removes its own dependencies, if nothing else needs them. Taking redis off a server removes igbinary and msgpack with it, because they were only ever there to support it. An extension you installed yourself is safe — the package manager leaves explicitly installed packages alone — and the console lists everything that went, either way.

The extensions actually loaded by one PHP version:

Terminal window
php84 -m # or php83, php82, php74

And the base set every version starts with:

Terminal window
rpm -q --requires corepanel-php

CorePanel does not manage php.ini or the php.d directory. It writes one file per account under /etc/opt/remi/php<version>/php-fpm.d/<username>.conf and nothing else, so anything you add to php.d is yours and survives updates.

Commercially encoded PHP — WHMCS, licensing systems and many paid scripts ship their source encrypted with ionCube and refuse to run without the Loader — is in the catalogue as ioncube-loader, so it installs from PHP → Extensions like anything else, once per version:

Terminal window
corepanel php extensions install 8.4 ioncube-loader

There is nothing to download from ionCube’s website and nothing to compile: the Loader is packaged in the Remi repository, which CorePanel enables during installation, and it exists for every PHP version CorePanel installs.

It is the one extension whose name in the panel is not the name PHP prints. php -m calls it ionCube Loader and php -v calls it the ionCube PHP Loader, because it is a zend_extension rather than an ordinary module. The panel handles that; it is worth knowing if you are reading the output yourself:

Terminal window
php84 -v

The output gains a line naming the ionCube PHP Loader. If it does not appear after a hand-install, the restart is usually what is missing — a zend_extension is read when the PHP process starts, so a running FPM master keeps serving without it. Installing from the panel restarts it for you.

Two files per PHP version, and that is the whole installation:

PathWhat it is
/etc/opt/remi/php84/php.d/01-ioncube_loader.iniThe zend_extension line that loads it
/opt/remi/php84/root/usr/lib64/php/modules/ioncube_loader.soThe Loader itself

The 01- prefix matters and is why the packaged version is the one to use: ionCube has to be loaded before OPcache, and the numbering guarantees that ordering. A Loader downloaded from ionCube and dropped into php.ini by hand is the usual cause of “it is installed but PHP does not see it”.

Because the .ini lives in the version’s shared php.d, one install covers both the web pools and the command line — so encoded software also runs from cron jobs and from SSH, with no extra step.

cPanel’s ea-php builds are its own packages and CorePanel’s versions come from Remi, so the two never share an extension set. Which extensions you end up with depends on how the server got here.

Transformed in place — PREPARE does the comparison for you. It reads what every cPanel interpreter loads, installs the difference from this catalogue before any account is registered, and names anything the catalogue does not carry. VERIFY checks it again afterwards, per version. Nothing on this page needs doing by hand.

Imported from another server — the accounts arrive, the extensions do not. Read the source server before you start, per version its accounts use:

Terminal window
# on the cPanel server
/opt/cpanel/ea-php81/root/usr/bin/php -m

and put the difference back from PHP → Extensions.

ioncube-loader, imap, bcmath, posix and soap are the five that come up most often — a WHMCS install is usually four of them at once. ionCube is the one worth checking first, because software encoded with it does not fail loudly when the loader is missing: it answers 200 OK with a polite page saying it cannot run, which is exactly what an uptime check reads as a healthy site.

Every extension on this page — the fifteen in the panel and anything installed by hand — is enabled per PHP version, not per account. Installing one for PHP 8.4 enables it for every account running PHP 8.4.

This is a property of PHP itself, not a CorePanel limitation. There is one php-fpm master per version and it loads its extensions when it starts; an FPM pool can override php.ini settings per account, but it cannot load or unload a module. Giving one account its own extension set would mean giving it its own PHP process, and that is not what a shared server is.

In practice it costs little. An extension no site uses is inert — it adds a small amount of memory per PHP process and does not change how ordinary PHP runs. The one to think twice about is removal: it takes the extension away from every account on the version at once.

dnf update keeps every extension current along with everything else, and CorePanel never removes one — an update only touches files the panel owns.

One case does need you: a PHP version you install later starts with the base set only. Extensions are per version, so a server where 8.3 has imagick and redis gets neither when you add 8.4 — the panel will show them as available on the new version, and one click each puts them there. The same applies to anything installed by hand, the ionCube Loader included.

For an extension outside the fifteen, the same pattern covers the rest of the Remi catalogue — the package name is php<version>-php-<extension>:

Terminal window
dnf install php84-php-pecl-yaml
systemctl restart php84-php-fpm

Three things worth knowing before you do:

  • Install it for each version you need. The packages are independent per version; php84-php-soap does nothing for an account on PHP 8.3.
  • A wrong name only warns. dnf install prints No match for argument and exits successfully, so a typo looks like a successful install. Confirm with php84 -m rather than trusting the transaction.
  • The name changes between versions, and not predictably. Remi builds imagick against ImageMagick 6 and 7 under different package names from PHP 8.2 onwards, ships three redis clients for 7.4 and one for 8.4, and moved imap out to PECL in 8.4 (so it is php83-php-imap but php84-php-pecl-imap). Check with dnf repoquery 'php84-php-*<name>*' rather than assuming the name you used last time. Sparing you exactly this is why the fifteen in the panel are a declared table of (version, package) pairs rather than a guess.
  • It changes between EL majors too. imagick is the one that does today: AlmaLinux and Rocky 8 and 9 get the ImageMagick 6 build (-im6), because that is the ImageMagick the distribution ships and everything else on the host links against. RHEL 10 dropped it, so Remi builds only -im7 there and that is what the panel installs. You do not have to think about this from the panel or the CLI — the right one is picked for your server — but it matters if you are typing a package name yourself.

Whatever you install by hand shows up in the panel as installed outside CorePanel, so nothing you add disappears from view.

If an extension is not in Remi at all, prefer a pecl build over editing php.ini by hand, and always drop the resulting .ini in the version’s php.d directory so ordering and updates keep working the way they do for everything else.