Skip to the content
Documentation
Help Start
Reading in:
  • German: 9,059 of 9,059 pages
About the help in other languages
All help pages

PHP 8.0 support

Exponential 6 runs on PHP 8.0 and later, and from 6.0.15 it is usable without support on PHP 7.4 (see Why Exponential supports PHP 7.4). PHP 8.0 matters because it is the stock PHP of Red Hat Enterprise Linux 9 (and of…

Download as PDF

Address: https://doc.exponential.earth/exphelp/viewer/bc/6.0/php-8.0-support.md

On this page

PHP 8.0 support

Exponential 6 runs on PHP 8.0 and later, and from 6.0.15 it is usable without support on PHP 7.4 (see Why Exponential supports PHP 7.4). PHP 8.0 matters because it is the stock PHP of Red Hat Enterprise Linux 9 (and of AlmaLinux 9 and Rocky Linux 9). Read this page if you run Exponential on RHEL 9 without a newer PHP, if you write kernel or extension code, or if you wonder why a function newer than 8.0 is wrapped in function_exists().

In short

Oldest PHP8.0 for the kernel and the shipped extensions, under Apache with mod_php, PHP-FPM or Velocity; 7.4 usable without support for the kernel from 6.0.15, without Velocity.
VelocityExponential Velocity, the application server, runs on PHP 8.0 too, from its release 0.0.4.54 (until then it needed 8.1; see below).
What changed in 6.0.15The few places that needed PHP 8.1 or later were made to work on 8.0; CI checks 8.0 on every push.
Behaviour on 8.1 and laterUnchanged. Every fallback is used only where PHP lacks the function.
Composercomposer.json declares ^8.0 and requires Velocity at ~0.0.4.57; a plain composer install works on 8.0 and installs the engine too.

What was found and how it was fixed

The whole tree was checked with PHPCompatibility for PHP 8.0 (testVersion 8.0), every PHP file was linted with PHP 8.0.30, every class of the kernel and of 63 extensions was loaded with PHP 8.0.30, and a complete installation was served by PHP 8.0.30: the front page, 35 public pages, the administration interface logged in (dashboard, content views, setup, notification and e-mail preference pages, the layout editor) and the editor siteaccess, with no PHP error, warning or deprecation. The findings:

WhereWhatPHPFix
kernel/classes/expvelocityconfiglayout.phparray_is_list()8.1defined in lib/phpcompat.php when missing
kernel/classes/subitems/expsubitemscsvexport.phpfputcsv() with $eol (an ArgumentCountError on 8.0)8.1on 8.0 the line is written without $eol and its "\n" replaced by "\r\n"
lib/eztemplate/classes/eztemplatestringoperator.php (wash), kernel/common/ezsimpletagsoperator.php and 26 other kernel, library, ezjscore, ezoe and expservices fileshtmlspecialchars(), htmlentities(), html_entity_decode() and htmlspecialchars_decode() without $flags8.1 changed the defaultthe PHP 8.1 default ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 is passed explicitly, so single quotes are escaped on 8.0 too
kernel/classes/contentjob/*, kernel/classes/ini/expinieditor.phpfsync()8.1already behind function_exists(); on 8.0 the data is flushed (fflush()) and left to the operating system
kernel/classes/contentjob/expcontentjobworker.phpmemory_reset_peak_usage()8.2already behind function_exists()
lib/eztemplate/classes/eztemplatestringsoperator.phpstr_increment(), str_decrement()8.3already behind function_exists(); the operators return their input on older PHP
lib/ezdb/classes/ezdbquerycache.phphash( 'xxh128' )8.1already checks hash_algos(); md5 on 8.0

The htmlspecialchars() change is the one that matters for security: PHP 8.0's default leaves ' alone, so a {$value|wash} inside a single-quoted HTML attribute would not have been safe on 8.0. Passing the flags gives every PHP version the same output, the one 8.1 and later already produced. If you have compiled templates from before the change, clear the template cache once (php bin/php/ezcache.php --clear-id=template).

Found on the way, and broken on every PHP 8, not only on 8.0 (fixed in the same change or in the extension's repository):

WhereWhatFix
kernel/private/modules/oauth/authorize.phpimplode( $pieces, $glue ) (a TypeError since 8.0)arguments swapped
kernel/classes/datatypes/ezuser/ezldapuser.phpcrypt() without a salt (an ArgumentCountError since 8.0)a random password from random_bytes()
syndication: eZSyndicateType::onPublish()by-reference parameters against the by-value parent (a fatal error when the class loads)& removed
ezstarrating: ezsrRatingObjectTreeNode::makeObjectsArray()lacks the parameters the kernel's method has (a fatal error when the class loads)parameters added
ezstarrating ezsrratingobject.php, swark SwarkJSONEncodeOperator, SwarkVariableNamesOperatorimplode( $pieces, $glue )arguments swapped
birthday ezbirthday.phpeach(), removed in 8.0key() and current()
enhancedezbinaryfilesplit(), removed in 7.0explode()

Not changed, because they behave the same on 8.0 as on 8.5: optional parameters before required ones (a deprecation since 8.0 in a few old signatures), the mysqli error mode (8.0 does not throw by default, and the driver checks return values, which is what it expects), never as the return type of closures in xrowextract (8.0 reads it as a class name; the closures always exit, so it is never checked).

How the compatibility functions work

lib/phpcompat.php defines a function only when PHP does not have it, with the same result as PHP's own:

if ( !function_exists( 'array_is_list' ) )
{
    function array_is_list( array $array ) { ... }
}

autoload.php reads it before anything else, and only on PHP older than 8.1 (PHP_VERSION_ID < 80100), so on 8.1 and later the file is not even opened and the built-in functions run. Every entry point (index.php, the CLI scripts, cronjobs, the tests) starts with autoload.php, so they all have the functions.

Rules for new code:

  • A function newer than PHP 8.0 that can be written in PHP with the same result goes into lib/phpcompat.php.
  • One that cannot (fsync(), memory_reset_peak_usage(), imageavif() ...) is called behind function_exists(), with a fallback that is correct on 8.0.
  • No syntax newer than 8.0: enums, readonly, never, new in initializers, first-class callable syntax foo(...), intersection types, typed class constants. #[\Override] and other attributes are harmless.
  • An argument a function gained later (fputcsv()'s $eol in 8.1) is a fatal error on 8.0: branch on PHP_VERSION_ID.
  • phpcs.xml.dist runs PHPCompatibility with testVersion 8.0-, and the Quality workflow's job php80 lints every file and boots the kernel on PHP 8.0 (quality checks).

Exponential Velocity on PHP 8.0

From release 0.0.4.54 (20 October 2026) Velocity (vendor/se7enxweb/exponential-velocity) runs on PHP 8.0 to 8.5: its composer.json requires "php": ">=8.0" (it was >=8.1). Nothing extra is needed on 8.0, no polyfill package and no extension. Until 0.0.4.54 the engine declared 8.1 as its minimum, so on PHP 8.0 a site had to be served by Apache or PHP-FPM; that limit is gone. So:

  • Apache or PHP-FPM serving the site: PHP 8.0 or later (PHP 7.4 usable without support).
  • Velocity: PHP 8.0 or later, including the stock PHP 8.0 of RHEL 9.

What differs on PHP 8.0, and only this:

  • AVIF image output needs PHP 8.1; on 8.0 the image negotiation stops at WebP.
  • The dashboard's per-request memory peak needs PHP 8.2; on 8.0 the column is empty.
  • $_FILES has no full_path, as in PHP 8.0 itself.
  • A class declared with eval() that has static properties makes its worker get replaced after that request; that is correct and costs one fork.

The engine handles the other differences itself: it reads declared static defaults from the source (PHP 8.0's getDefaultValue() returns the current value), calls setAccessible() on 8.0 for private and protected statics, and clears the stat cache for the dashboard's log tail. The zygote runs on 8.0. Extensions, systemd, SELinux and how to verify an installation are in the engine's PHP 8.0 and Red Hat Enterprise Linux page; the engine's minimums are in its requirements and the release in its changelog.

With that, Velocity is part of Exponential as of 6.0.15: the root composer.json requires it at ~0.0.4.57, so the kernel, the shipped extensions and the server share one minimum, PHP 8.0. The story for every reader: Velocity is part of Exponential 6.0.15.

Red Hat Enterprise Linux 9

  • Stock PHP 8.0: dnf install php php-fpm php-mysqlnd php-gd php-intl php-mbstring php-xml php-pdo php-opcache installs PHP 8.0 from AppStream. That is enough for Exponential under Apache, PHP-FPM or Velocity. The el9 rpm of Velocity (exponential-velocity-<release>-1.el9.noarch.rpm) depends on php-cli >= 8.0 and installs on it without enabling a module stream.
  • Newer PHP from AppStream modules: RHEL 9 also offers the module streams php:8.1, php:8.2 and php:8.3 (dnf module list php; switch with dnf module reset php and dnf module enable php:8.3, then dnf distro-sync). Each of them runs Exponential and Velocity too; none is needed for Velocity.
  • RHEL 8: the default PHP there is 7.2. Enable the 8.0 stream first (dnf module enable php:8.0) and install Velocity from the phar or with Composer; there is no el8 rpm.
  • Remi or Plesk: the Remi repository (php:remi-8.x module streams) and Plesk's /opt/plesk/php/8.x builds provide every version from 8.0 to 8.5 side by side.
  • Extensions the stock packages leave out (php-pecl-redis, php-pecl-apcu, oci8) come from EPEL, Remi or the vendor; Exponential uses them only when their features are configured.

Installing with Composer on PHP 8.0

composer.json declares "php": "^8.0 || ^8.1 || ..." since 6.0.15. The extensions that only declared ^8.1 in their metadata were released with ^8.0 (explayouts and its packages, the expsite packages, exp_enhanced_link, expchangeclass, expquery-translator, sevenx-themes-media 1.5.32, exponential-legacy-installer 2.2.4), and syndication 1.3.5, ezstarrating 6.0.9, swark 1.0.5, birthday 1.3.3 and enhancedezbinaryfile 4.4.5 were released with fixes for code no PHP 8 could load.

Velocity is required again, at ~0.0.4.57 (0.0.4.54 was the first release that runs on PHP 8.0). Between its move to "suggest" (because it needed PHP 8.1) and that release, it had to be added by hand; an installation made in that time adds it with:

composer require se7enxweb/exponential-velocity:~0.0.4.57
PackageDeclaresBlocks 8.0
google/recaptcha (via recaptcha)2.1.0 needs >=8.4no: the requirement is *, so Composer picks 1.3.x on 8.0

Every package composer.json requires allows PHP 8.0, so a plain composer install --no-dev works on RHEL 9's stock PHP. The CI job php80 installs exactly that way, so a package that raises its minimum again fails there.

Something wrong on this page? Report an error

Documentation license

This documentation is free documentation, licensed under the GNU Free Documentation License 1.3 or later.

Exponential Copyright © 1998-2026 Exponential Foundation and 7x