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.
From the panel
Section titled “From the panel”PHP → Extensions, in the admin area. Pick a version along the top; the list underneath is that version’s.
Each extension shows one of:
| State | What it means |
|---|---|
| installed | The package is here and the interpreter loads it |
| installed, not loaded | The package is here but PHP does not load it — its .ini was disabled by hand |
| not in the repository | Your package repository does not offer it for that version |
| not for this version | It 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:
corepanel php extensions # every versioncorepanel php extensions --php 8.3 # just onecorepanel php extensions install 8.3 imagickcorepanel php extensions remove 8.3 imagickRemovals that are refused
Section titled “Removals that are refused”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.
What is installed
Section titled “What is installed”The extensions actually loaded by one PHP version:
php84 -m # or php83, php82, php74And the base set every version starts with:
rpm -q --requires corepanel-phpCorePanel 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.
Encoded software: the ionCube Loader
Section titled “Encoded software: the ionCube Loader”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:
corepanel php extensions install 8.4 ioncube-loaderThere 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:
php84 -vThe 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.
What the package puts on disk
Section titled “What the package puts on disk”Two files per PHP version, and that is the whole installation:
| Path | What it is |
|---|---|
/etc/opt/remi/php84/php.d/01-ioncube_loader.ini | The zend_extension line that loads it |
/opt/remi/php84/root/usr/lib64/php/modules/ioncube_loader.so | The 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.
After migrating from cPanel
Section titled “After migrating from cPanel”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:
# on the cPanel server/opt/cpanel/ea-php81/root/usr/bin/php -mand 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.
It applies to a whole PHP version
Section titled “It applies to a whole PHP version”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.
Keeping it after updates
Section titled “Keeping it after updates”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.
Adding anything else by hand
Section titled “Adding anything else by hand”For an extension outside the fifteen, the same pattern covers the rest of the Remi
catalogue — the package name is php<version>-php-<extension>:
dnf install php84-php-pecl-yamlsystemctl restart php84-php-fpmThree things worth knowing before you do:
- Install it for each version you need. The packages are independent per version;
php84-php-soapdoes nothing for an account on PHP 8.3. - A wrong name only warns.
dnf installprints No match for argument and exits successfully, so a typo looks like a successful install. Confirm withphp84 -mrather than trusting the transaction. - The name changes between versions, and not predictably. Remi builds
imagickagainst ImageMagick 6 and 7 under different package names from PHP 8.2 onwards, ships threeredisclients for 7.4 and one for 8.4, and movedimapout to PECL in 8.4 (so it isphp83-php-imapbutphp84-php-pecl-imap). Check withdnf 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.
imagickis 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-im7there 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.