Installing NES for PHP
How to install NES for PHP on Debian, Ubuntu, RHEL, Amazon Linux 1, Amazon Linux 2 and Amazon Linux 2023
Supported Platforms
Pick your operating system and PHP version for the packages it gets, or explore every platform.
x86_64aarch64php7.4-*1:7.4.33+nes7.4.5-1~ubuntu24.047.4.33-nesWindows Server (x64, and x86 for PHP 7.2) is installed from a zip: see Windows.
Current Releases
The current releases, and what php -v shows once one is installed:
v7.4.33-nes-7.4.5PHP (php -v)7.4.33-nesDebian and Ubuntu package namesphp7.4-*Debian and Ubuntu package version1:7.4.33+nes7.4.5-1~<distribution>Extensions
Each version keeps its PHP's extension API. An extension built for the same PHP
version with the same thread-safety keeps loading without a rebuild. php -i
shows the build's API version and thread-safety in its Extension Build line
(API<PHP API version>,NTS for the standard builds).
20190902Shared by every NES for PHP 7.4 build.320190902Used by Zend extensions such as OPcache and Xdebug.NTSStandard Linux builds are non-thread-safe.API20190902,NTSWhat php -i shows on this build.php7.4-<extension>Package naming for Ubuntu 24.04.php -i on the server where the extension was built. Access
NES for PHP requires an access token for the NES registry. See Access for how to get one and where a release's files are.
Choose your PHP version
The steps below are the same for every PHP version. Two shell variables carry
the difference: line, the PHP version you run, and tag, its current NES
release (the tabs above have both). Set them once in the shell you install from:
line=7.4 # or 8.2, 8.1, 8.0, 7.3, 7.2, 7.1 or 5.6
case $line in
8.2) tag=v8.2.35-nes-8.2.1 ;;
8.1) tag=v8.1.34-nes-8.1.3 ;;
8.0) tag=v8.0.30-nes-8.0.1 ;;
7.4) tag=v7.4.33-nes-7.4.5 ;;
7.3) tag=v7.3.33-nes-7.3.2 ;;
7.2) tag=v7.2.34-nes-7.2.4 ;;
7.1) tag=v7.1.33-nes-7.1.2 ;;
5.6) tag=v5.6.40-nes-5.6.2 ;;
esac
PHP 8.0, PHP 8.1 and PHP 8.2 have steps of their own: see PHP 8.0 on Ubuntu 22.04, PHP 8.1 on Amazon Linux 2023, PHP 8.1 on Ubuntu 18.04 and PHP 8.2 on RHEL 8.
PHP 7.1 is published for Amazon Linux 2 (x86_64 and aarch64), Amazon Linux 1 (x86_64) and RHEL 6 (x86_64, also CentOS 6) only. It turns LOAD DATA LOCAL INFILE off by default: mysqli.allow_local_infile defaults to 0, and a PDO MySQL connection allows it only when it is opened with PDO::MYSQL_ATTR_LOCAL_INFILE => true. Code that loads local files sets mysqli.allow_local_infile = On in php.ini, or passes that option, and should do so only for a server it trusts. See the PHP 7.1 release notes for its other behaviour changes.
Debian and Ubuntu
The packages keep the usual names (php<X.Y>-cli, php<X.Y>-fpm,
libapache2-mod-php<X.Y> and the rest, with <X.Y> your PHP version, $line
below), paths and configuration files, and replace the php<X.Y> packages a
host already has. This section is for PHP 7 and PHP 5.6; PHP 8.0 and PHP 8.1
have steps of their own, see PHP 8.0 on Ubuntu 22.04
and PHP 8.1 on Ubuntu 18.04.
Ubuntu 18.04 and Ubuntu 16.04 are past Canonical's standard support: NES for PHP fixes PHP and what the packages bundle, not the distribution's own packages.
- PHP 7.2 on Ubuntu 18.04. Upgrade with
sudo apt-get --with-new-pkgs upgrade: a plainapt-get upgradekeeps the PHP packages back on Bionic. The upgrade removes nothing, and Ubuntu's own PECL packages (php-apcu, php-redis, php-memcached, php-imagick and the rest) stay installed and keep loading. Bionic's system libraries (OpenSSL 1.1.1, libxml2, libzip, libpq 10, curl) get fixes only through Ubuntu Pro (ESM). In particular, without ESM, libpq 10 does not reject invalid multibyte input inPQescapeLiteral()andPQescapeIdentifier(), so the CVE-2025-1094 hardening ofpg_escape_*(),pg_insert(),pg_update()andPDO::quote()is absent. ZipArchive has no encryption support with Bionic's libzip 1.1.2. - PHP 7.4 on Ubuntu 18.04 and 16.04. The pgsql and pdo_pgsql escaping fix for CVE-2025-1735 relies on libpq to report a string that is invalid in the connection's encoding. The public archive's libpq 10 (10.23) on Ubuntu 18.04 and libpq 9.5 on Ubuntu 16.04 do not do that (CVE-2025-1094), so there the check is only as good as the host's
libpq5. A host that still has Ondřej Surý's former PPA packages of PHP 7.4 upgrades as on the other Ubuntu releases; those packages can no longer be downloaded, so that path is not tested. - PHP 7.4 on Ubuntu 16.04. PHP uses OpenSSL 1.0.2g, which has no TLS 1.3.
password_hash()has no Argon2 (PASSWORD_ARGON2I,PASSWORD_ARGON2ID): Ubuntu 16.04 has no libargon2, and its libsodium 1.0.8 has no Argon2 either. Xenial's apt 1.2 cannot read an armored key insigned-by, so the Ubuntu 16.04 archive also holds the key unarmored,nes-php.gpg, and itsnes-php.listnamessigned-by=/opt/nes-php/nes-php.gpg, notnes-php.asc. Copy that file as below; an apt source you write yourself must namenes-php.gpgtoo. - Verify. Ubuntu 18.04's GnuPG 2.2.4 and Ubuntu 16.04's GnuPG 1.4.20 have no
gpg --show-keys: check the downloads with the commands of the PHP 5.6, Ubuntu 16.04 and 18.04 tab below.
Download and verify
In an empty directory, download the signing key, the checksums and the repository for your distribution:
# Published for PHP 7.4 and 7.2 only
base=https://registry.nes.herodevs.com/bin/nes/php/$tag
auth="<your-contact-email>:<your-nes-access-token>"
arch=$(dpkg --print-architecture)
for f in RPM-GPG-KEY-php-nes SHASUMS256.txt SHASUMS256.txt.asc "php-$tag.debian12.$arch.repo.tar.xz"; do
curl -fSLO -u "$auth" "$base/$f"
done
Then verify the downloads:
gpg --show-keys RPM-GPG-KEY-php-nes # must show CA44E935A3995EB733AF292B18DD1E9212F3C6A2
gpg --import RPM-GPG-KEY-php-nes
gpg --verify SHASUMS256.txt.asc SHASUMS256.txt
sha256sum -c --ignore-missing SHASUMS256.txt
Install
Add the repository, then upgrade the PHP packages the host has:
sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.*.repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/nes-php.list /etc/apt/sources.list.d/nes-php.list
sudo apt update
sudo apt upgrade
On a host without PHP, install the packages you need instead, for example
sudo apt install php$line-cli php$line-fpm php$line-mysql (on PHP 5.6,
sudo apt-get install php5.6-cli php5.6-fpm php5.6-mysql).
PHP 7.4 on Debian 13 has no php7.4-imap. Remove it (sudo apt-get remove php7.4-imap) before you upgrade a host that has it.
Check the installation:
php -v
Configure
Each PHP SAPI reads its own php.ini in /etc/php/<X.Y>/cli/,
/etc/php/<X.Y>/fpm/ or /etc/php/<X.Y>/apache2/. php-fpm is the
php<X.Y>-fpm service and listens on /run/php/php<X.Y>-fpm.sock:
sudo systemctl enable --now php$line-fpm
Upgrade
Set tag to the new release, download and verify its repository as above, then:
sudo rm -rf /opt/nes-php && sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.*.repo.tar.xz -C /opt/nes-php --strip-components=1
sudo apt update
sudo apt upgrade
Uninstall
Remove the NES packages, the ones whose version contains nes:
sudo apt purge $(dpkg-query -W -f '${db:Status-Abbrev} ${Package} ${Version}\n' | awk '$1 ~ /^i/ && $3 ~ /[.+]nes[0-9]/ && $2 != "php-common" { print $2 }')
sudo rm /etc/apt/sources.list.d/nes-php.list
sudo rm -rf /opt/nes-php
To go back to the PHP packages you used before instead, keep their
repository configured and install their versions with
sudo apt install --allow-downgrades <package>=<version> (on PHP 5.6,
sudo apt-get install --allow-downgrades <package>=<version>).
PHP 8.0 on Ubuntu 22.04
NES for PHP 8 is for Ubuntu 22.04 on x86_64 (amd64). A release is one signed
apt repository in one archive, which holds the release signing key and a
repo/ directory with the packages and their signed index. The packages keep
Ubuntu's names (php8.0-cli, php8.0-fpm, libapache2-mod-php8.0 and the
rest) and paths: /usr/bin/php8.0, /etc/php/8.0/<sapi>/php.ini and
/usr/lib/php/20200930/ for extensions.
Download and verify
In an empty directory, download the signing key, the checksums and the repository, then verify them:
tag=v8.0.30-nes-8.0.1
base=https://registry.nes.herodevs.com/bin/nes/php/$tag
auth="<your-contact-email>:<your-nes-access-token>"
for f in RPM-GPG-KEY-php-nes SHASUMS256.txt SHASUMS256.txt.asc "php-$tag.ubuntu2204.amd64.repo.tar.xz"; do
curl -fSLO -u "$auth" "$base/$f"
done
gpg --show-keys RPM-GPG-KEY-php-nes # must show CA44E935A3995EB733AF292B18DD1E9212F3C6A2
gpg --import RPM-GPG-KEY-php-nes
gpg --verify SHASUMS256.txt.asc SHASUMS256.txt
sha256sum -c --ignore-missing SHASUMS256.txt
Install
On a host without PHP 8.0, extract the archive to /opt/nes-php and add it as
an apt source. apt reads an armored key only when its file name ends in
.asc, so the key goes to /usr/share/keyrings/nes-php.asc. Then install
php-common and the packages you need:
sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.ubuntu2204.amd64.repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/RPM-GPG-KEY-php-nes /usr/share/keyrings/nes-php.asc
echo 'deb [arch=amd64 signed-by=/usr/share/keyrings/nes-php.asc] file:/opt/nes-php/repo ./' | sudo tee /etc/apt/sources.list.d/nes-php.list
sudo apt-get update
sudo apt-get install --no-remove --no-install-recommends php-common php8.0-cli php8.0-fpm
php8.0 -v
Other PHP versions on the host, such as Ubuntu's own PHP 8.1, keep working,
and the php command keeps pointing where it did. Run php8.0, or point
php at it with sudo update-alternatives --set php /usr/bin/php8.0.
Upgrade from other PHP 8.0 packages
Ubuntu 22.04 has no PHP 8.0 of its own. A host that has PHP 8.0.30 packages from another repository can upgrade to these: the NES versions sort above the other builds of 8.0.30. First keep the packages you have, so you can roll back. Their versions must still be in their repository:
mkdir -p ~/php-8.0-rollback && cd ~/php-8.0-rollback
apt-get download $(dpkg-query -W -f '${db:Status-Abbrev} ${Package}=${Version}\n' | awk '$1 ~ /^i/ && $2 ~ /^(php8\.0|libapache2-mod-php8\.0|libphp8\.0-embed)/ { print $2 }')
Then add the NES repository as above, without the install line, and upgrade:
sudo apt-get install --no-remove --no-install-recommends $(dpkg-query -W -f '${db:Status-Abbrev} ${Package}\n' | awk '$1 ~ /^i/ && $2 ~ /^(php8\.0|libapache2-mod-php8\.0|libphp8\.0-embed)/ { print $2 }')
sudo service php8.0-fpm restart
sudo service apache2 restart
With --no-remove, apt stops instead of removing a package. Extension
packages from the other repository that NES does not ship are not part of the
upgrade: remove them first, and build the extension against php8.0-dev
instead (phpize8.0 and php-config8.0).
To roll back, install the packages you kept, then take the NES source out, so that apt does not upgrade again:
cd ~/php-8.0-rollback
sudo apt-get install --allow-downgrades --no-remove --no-install-recommends ./*.deb
sudo rm /etc/apt/sources.list.d/nes-php.list
sudo apt-get update
sudo service php8.0-fpm restart
sudo service apache2 restart
Configure
php-fpm is the php8.0-fpm service (sudo service php8.0-fpm start) and
listens on /run/php/php8.0-fpm.sock, owned by www-data. Apache runs PHP
through libapache2-mod-php8.0 with the prefork MPM:
sudo a2dismod mpm_event
sudo a2enmod mpm_prefork php8.0
sudo apache2ctl -t
sudo service apache2 restart
Turn an extension on or off with phpenmod -v 8.0 and phpdismod -v 8.0.
PHP 8.2 on RHEL 8
NES for PHP 8 provides PHP 8.2.35 for RHEL 8, AlmaLinux 8, Rocky Linux 8 and
UBI 8, on x86_64 and aarch64. A release is one signed dnf
repository archive per architecture, php-<release>.el8.<arch>.repo.tar.xz.
Each archive holds the release signing key, a nes-php.repo repository file, a
repo/ directory with the signed RPMs and the module metadata, and the signed
source RPM in src/. The release also has the PHP source tarball,
php-<release>.tar.xz. PHP 8.2 has no packages for other distributions, no
container images and no Windows zip.
The packages are the php:nes-8.2 module stream. They keep Red Hat's names
(php, php-cli, php-fpm, php-mysqlnd and the rest), paths and
configuration files: /etc/php.ini, /etc/php.d/, /etc/php-fpm.d/ and
/usr/lib64/php/modules/ for extensions. The extension API is PHP 8.2's (PHP
API 20220829), so an extension built for PHP 8.2 loads without a rebuild. Every
package's Release is <N>.nes82.el8, with <N> the release's number: in
8.2.1, for example, php-cli-8.2.35-1.nes82.el8.x86_64. No Epoch is raised, and php-pear keeps
Red Hat's Epoch 1 (php-pear-1:1.10.18-1.nes82.el8).
The stream has the packages of Red Hat's php:8.2 stream, less
php-pecl-xdebug3 and php-pecl-rrd, plus php-sodium. Like Red Hat's, it
has no imap, pdo_firebird, pdo_dblib, tidy or pspell extension.
Before you install
- OpenSSL.
php-commonrequiresopenssl-libs >= 1:1.1.1k-12, the RHEL 8 OpenSSL with implicit rejection for RSA PKCS#1 v1.5 decryption. This is the fix for the Marvin attack onopenssl_private_decrypt()(CVE-2024-2408). Updated RHEL 8.9 hosts and later have it. On a host with an older build, update it first withsudo dnf upgrade openssl-libs. The RHEL 8.6 and 8.8 Extended Update Support builds of the same version are not verified to carry the fix: on those hosts, passOPENSSL_PKCS1_OAEP_PADDINGtoopenssl_public_encrypt()andopenssl_private_decrypt()in place of the default PKCS#1 v1.5 padding. - EPEL.
php-sodiumneedslibsodiumfrom EPEL 8. Enable EPEL before you install it (Getting started with EPEL).phprecommendsphp-sodium, so with EPEL enabled, dnf installs it withphp.
Download and verify
Set tag to the PHP 8.2 release, v8.2.35-nes-8.2.1. In an empty directory,
download the signing key, the checksums and the repository for your
architecture, then verify them:
tag=v8.2.35-nes-8.2.1
base=https://registry.nes.herodevs.com/bin/nes/php/$tag
auth="<your-contact-email>:<your-nes-access-token>"
arch=$(uname -m)
for f in RPM-GPG-KEY-php-nes SHASUMS256.txt SHASUMS256.txt.asc "php-$tag.el8.$arch.repo.tar.xz"; do
curl -fSLO -u "$auth" "$base/$f"
done
gpg --show-keys RPM-GPG-KEY-php-nes # must show CA44E935A3995EB733AF292B18DD1E9212F3C6A2
gpg --import RPM-GPG-KEY-php-nes
gpg --verify SHASUMS256.txt.asc SHASUMS256.txt
sha256sum -c --ignore-missing SHASUMS256.txt
Add the repository
Extract the archive to /opt/nes-php and add its repository file. tar needs
xz to extract it:
sudo rm -rf /opt/nes-php && sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.el8.$(uname -m).repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/nes-php.repo /etc/yum.repos.d/nes-php.repo
dnf checks every package's signature against the release signing key
(gpgcheck=1). The repository needs no priority: once php:nes-8.2 is
enabled, dnf hides the packages of every other php stream, so dnf upgrade
never takes Red Hat's builds back.
Install
On a host with no php stream enabled, enable the stream and install the packages you need:
sudo dnf module enable php:nes-8.2
sudo dnf install php-cli php-fpm php-mysqlnd
php -v
php -v shows PHP 8.2.35-nes. On a host where another php stream is
enabled, dnf module enable refuses: use dnf module switch-to php:nes-8.2,
below, instead.
PHP uses the system time zone database (tzdata), as Red Hat's build does. On a ubi-minimal 8 host, whose tzdata package has no /usr/share/zoneinfo, only UTC works until you run microdnf upgrade tzdata and microdnf reinstall tzdata.
Switch from Red Hat's PHP
On a host with Red Hat's php:8.2 stream, or another of its php streams, add
the repository as above, then switch:
sudo dnf module switch-to php:nes-8.2
php -v
The switch moves every installed package that the stream has to its NES build,
Red Hat's apcu-panel, php-pecl-apcu, php-pecl-zip, php-pear and
libzip included. Your edits to /etc/php.ini, /etc/php-fpm.conf and
/etc/php-fpm.d/*.conf are kept. With EPEL enabled, the switch also installs
php-sodium on a host that has php. Then restart php-fpm, and Apache httpd
if it loads PHP's module, so they run NES's build:
sudo systemctl restart php-fpm.
- Red Hat's
php:8.2builds ofphp-pecl-xdebug3andphp-pecl-rrdare not part of the stream. They stay installed across the switch and load into NES's PHP, which has the same extension API as Red Hat's PHP 8.2. Whilephp:nes-8.2is enabled, they cannot be newly installed. - The switch stops, and changes nothing, while an installed package has no
counterpart in the stream and requires its own PHP build: for example
php-xmlrpcfrom a PHP 7 stream, or a PECL extension built for another PHP version. Remove that package first.
Switch from NES's PHP 7.4 or PHP 7.2
On a host with NES's php:nes-7.4 or php:nes-7.2 stream, remove
php-xmlrpc first: PHP 8 has no xmlrpc extension, and the switch stops while
it is installed. Then add the PHP 8.2 repository as above, which replaces the
PHP 7 one in /opt/nes-php, and switch:
sudo dnf remove php-xmlrpc
sudo dnf module switch-to php:nes-8.2
php -v
Restart php-fpm, and Apache httpd if it loads PHP's module, as above.
php-json is part of PHP 8 and goes with the switch. Use switch-to, not
dnf module enable and dnf upgrade: some PHP 8.2 builds sort below the PHP 7
builds of the same version (APCu and PEAR), and only switch-to moves them.
Roll back to Red Hat's PHP 8.2
Remove the NES repository, then switch back to Red Hat's php:8.2 stream:
sudo rm /etc/yum.repos.d/nes-php.repo
sudo dnf module switch-to php:8.2 --allowerasing
sudo rm -rf /opt/nes-php
Every package returns to Red Hat's build. --allowerasing lets dnf remove
php-sodium, which Red Hat does not build: without it, the switch stops on
that package. On a host without php-sodium, it is not needed.
Configure
PHP reads /etc/php.ini and /etc/php.d/. php-fpm is the php-fpm service,
with Red Hat's defaults: the www pool runs as apache, listens on
/run/php-fpm/www.sock (which the apache and nginx users may use), uses
pm = dynamic with 50 children at most, and logs errors to
/var/log/php-fpm/www-error.log.
sudo systemctl enable --now php-fpm
php-pear is PEAR 1.10.18. With php-devel and a compiler, pecl install
builds an extension for NES's PHP 8.2.
Behaviour changes
php -vandPHP_VERSIONreport8.2.35-nes, soversion_compare(PHP_VERSION, '8.2.35', '>=')is false.PHP_VERSION_IDstays 80235: use it to check the PHP version.- Session upload progress is off:
/etc/php.inisetssession.upload_progress.enabled = Off, its compiled default isOff, and setting it toOnhas no effect. This mitigates CVE-2026-115560, which needs session upload progress and has no upstream fix yet; the fix will follow in a later release. - mysqlnd (mysqli and PDO MySQL) no longer sends a password in clear text with
the
mysql_clear_passwordauthentication plugin over a connection that is neither TLS nor a Unix socket: a server, or anyone between PHP and the server, could ask for that plugin and read the password. Such a connection now fails with error 2059 ("Authentication plugin 'mysql_clear_password' cannot be loaded: ..."). Connect accounts that use the plugin (PAM or LDAP authentication) over TLS or a Unix socket. Any TLS connection is accepted, so verify the server's certificate to keep the password from a man in the middle. To allow the plugin over plain TCP as before, set the environment variableLIBMYSQL_ENABLE_CLEARTEXT_PLUGIN=1for the PHP process: under php-fpm,env[LIBMYSQL_ENABLE_CLEARTEXT_PLUGIN] = 1in the pool configuration; for Apache's PHP module, the web server's own environment (SetEnvdoes not reach it). - A server that switches a
sha256_passwordlogin to a scramble shorter than 20 bytes, or to none, is now refused with error 2027 ("The server sent wrong length for scramble") instead of crashing the client. php-pecl-zipis PECL zip 1.22.8 (Red Hat's is 1.22.3), on the stream's ownlibzip1.7.3 build. The stream's libzip keys its entry-name hashing, so a crafted archive cannot makezip_open()take quadratic time (GHSA-m3wq-j48p-jxwh). ItsValueErrormessages say "must not be empty" where 1.22.3 said "cannot be empty". Reflection lists a#[\Deprecated]attribute onzip_open()and the other proceduralzip_*()functions, which PHP 8.2 cannot instantiate; the functions behave as before.php-gdis built on PHP's bundled libgd, not on RHEL 8'sgd2.2.5, and no longer requires thegdpackage. JPEG, PNG, WebP, FreeType and XPM are supported, as before.php-pecl-apcu,php-pecl-apcu-develandapcu-panelare APCu 5.1.28 (Red Hat's is 5.1.23).
See the PHP 8.2 release notes for the security fixes.
Upgrade to a later release
Set tag to the new release, download and verify its archive as above, then:
sudo rm -rf /opt/nes-php && sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.el8.$(uname -m).repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/nes-php.repo /etc/yum.repos.d/nes-php.repo
sudo dnf upgrade --refresh
Uninstall
Remove the NES packages, reset the module and remove the repository:
sudo dnf remove $(rpm -qa --qf '%{NAME} %{RELEASE}\n' | awk '$2 ~ /\.nes82\./ { print $1 }')
sudo dnf module reset php
sudo rm /etc/yum.repos.d/nes-php.repo
sudo rm -rf /opt/nes-php
To go back to Red Hat's PHP 8.2 instead, see Roll back to Red Hat's PHP 8.2.
RHEL 8, 9 and 10, AlmaLinux and Rocky Linux
The packages are the php:nes-<X.Y> module stream (php:nes-$line below),
with the usual package names (php-cli, php-fpm, php-mysqlnd and the
rest), paths and configuration files. This section is for PHP 7.4, PHP 7.3
and PHP 7.2; PHP 8.2 has steps of its own, see PHP 8.2 on RHEL 8.
PHP 7.4 and 7.2 packages have the Release <N>.nes.el<RHEL version>; PHP
7.3's, published for RHEL 8 only, have <N>.nes73.el8 (for example
php-cli-7.3.33-2.nes73.el8.x86_64).
Download and verify
In an empty directory, download the signing key, the checksums and the repository for your RHEL version:
# Published for PHP 7.4, 7.3 and 7.2 only
base=https://registry.nes.herodevs.com/bin/nes/php/$tag
auth="<your-contact-email>:<your-nes-access-token>"
arch=$(uname -m)
for f in RPM-GPG-KEY-php-nes SHASUMS256.txt SHASUMS256.txt.asc "php-$tag.el8.$arch.repo.tar.xz"; do
curl -fSLO -u "$auth" "$base/$f"
done
Then verify the downloads:
gpg --show-keys RPM-GPG-KEY-php-nes # must show CA44E935A3995EB733AF292B18DD1E9212F3C6A2
gpg --import RPM-GPG-KEY-php-nes
gpg --verify SHASUMS256.txt.asc SHASUMS256.txt
sha256sum -c --ignore-missing SHASUMS256.txt
Install
Add the repository:
sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.*.repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/nes-php.repo /etc/yum.repos.d/nes-php.repo
Then enable the php:nes-$line module stream. A host that has PHP from another
stream switches to it; a host without PHP enables it and installs the packages
you need:
sudo dnf module switch-to php:nes-$line
php-sodium needs libsodium from EPEL. Remove packages the stream does not have before switching: while one is installed, the switch stops and changes nothing.
- PHP 7.4 has no
php-imap,php-pdo-dblib,php-pdo-firebird,php-tidy,php-litespeedorphp-oci8, and on RHEL 8 noapcu-panel. - PHP 7.3 has no
php-imap,php-interbase,php-pdo-dblib,php-tidy,php-pspellorphp-recode. On a host with Red Hat'sphp:7.3, removeapcu-panel,php-recode,php-pecl-xdebugandphp-pecl-rrdfirst:sudo dnf remove apcu-panel php-recode php-pecl-xdebug php-pecl-rrd. Whilephp:nes-7.3is enabled, dnf does not offer Red Hat's builds of them. - PHP 7.2 has no
php-imap,php-interbase,php-pdo-dbliborphp-tidy, and on RHEL 8 nophp-recode.
PHP 7.2: the stream has no Argon2 password hashing, because the operating system has no libargon2, and its php-pecl-zip is the version PHP 7.2 ships. A host that moves from a third-party PHP 7.2 stream on RHEL 9 may lose both.
PHP 7.3: password_hash() has no Argon2 (PASSWORD_ARGON2I and PASSWORD_ARGON2ID are not defined), because RHEL 8 has no libargon2. The stream carries its own libzip 1.6.1 (libzip, libzip-devel, libzip-tools), which its php-pecl-zip links.
Check the installation:
php -v
On a ubi-minimal host, run microdnf reinstall tzdata after installing, or PHP's date functions fail with "Timezone database is corrupt".
Configure
PHP reads /etc/php.ini and /etc/php.d/. php-fpm is the php-fpm service
and listens on /run/php-fpm/www.sock:
sudo systemctl enable --now php-fpm
Upgrade
Set tag to the new release, download and verify its repository as above, then:
sudo rm -rf /opt/nes-php && sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.*.repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/nes-php.repo /etc/yum.repos.d/nes-php.repo
sudo dnf upgrade --refresh
Uninstall
Remove the NES packages, reset the module and remove the repository:
sudo dnf remove $(rpm -qa --qf '%{NAME} %{RELEASE}\n' | awk '$2 ~ /\.nes[0-9]*\./ { print $1 }')
sudo dnf module reset php
sudo rm /etc/yum.repos.d/nes-php.repo
sudo rm -rf /opt/nes-php
To go back to the distribution's PHP instead, enable the stream you want
after the reset and install its packages (dnf module list php lists them), for
example sudo dnf module switch-to php:<stream>.
PHP 7.2: RHEL 8 has a php:7.2 stream, RHEL 9 has none for PHP 7.2. PHP 7.3:
RHEL 8 has a php:7.3 stream.
RHEL 7
NES for PHP 7 provides PHP 7.4.33 for RHEL 7 and CentOS 7, on x86_64 and
aarch64. The packages have the names of Remi's php74 packages for el7
(php, php-cli, php-fpm, php-mysqlnd and the rest, and libzip5),
which they replace, and the usual paths and configuration files. RHEL 7's yum
has no module streams: the archive holds a plain yum repository at priority 5,
which needs yum-plugin-priorities. This section is for PHP 7.4; for PHP 5.6
on RHEL 7, see RHEL 6 and 7, CentOS and Oracle Linux.
Red Hat ended maintenance support for RHEL 7 on 2024-06-30. NES for PHP fixes PHP and the libraries it carries its own copy of (libzip, and PHP's own PCRE2 and libgd), not RHEL 7's own packages.
- PHP uses RHEL 7's own OpenSSL 1.0.2k, which has no TLS 1.3.
- The build has no libargon2:
password_hash()'s Argon2 algorithms (PASSWORD_ARGON2I,PASSWORD_ARGON2ID) come fromphp-sodium, as on RHEL 8. - The pgsql and pdo_pgsql escaping fix for CVE-2025-1735 relies on libpq to report a string that is invalid in the connection's encoding. CentOS 7's final libpq (9.2.24) does not do that (CVE-2025-1094), so on RHEL 7 and CentOS 7 the check is only as good as the host's
postgresql-libs.
Download and verify
In an empty directory, download the signing key, the checksums and the
repository for your architecture (tar needs xz: sudo yum install xz):
base=https://registry.nes.herodevs.com/bin/nes/php/$tag
auth="<your-contact-email>:<your-nes-access-token>"
arch=$(uname -m)
for f in RPM-GPG-KEY-php-nes SHASUMS256.txt SHASUMS256.txt.asc "php-$tag.el7.$arch.repo.tar.xz"; do
curl -fSLO -u "$auth" "$base/$f"
done
Then verify the downloads. RHEL 7's GnuPG 2.0 has no --show-keys and its
sha256sum has no --ignore-missing:
gpg --with-fingerprint RPM-GPG-KEY-php-nes # must show CA44E935A3995EB733AF292B18DD1E9212F3C6A2
gpg --import RPM-GPG-KEY-php-nes
gpg --verify SHASUMS256.txt.asc SHASUMS256.txt
ls | awk 'NR == FNR { have[$0]; next } $2 in have' - SHASUMS256.txt | sha256sum -c -
Install
php-mbstring and php-sodium need oniguruma and libsodium from EPEL 7,
as Remi's packages do. EPEL 7 reached its end of life with RHEL 7 and is
archived: a host that installs either package needs a repository for EPEL 7's
archive. Install yum-plugin-priorities, then add the repository:
sudo yum install yum-plugin-priorities
sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.el7.$(uname -m).repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/nes-php.repo /etc/yum.repos.d/nes-php.repo
On a host without PHP, install the packages you need:
sudo yum install php-cli php-fpm php-mysqlnd
php -v
The packages are signed with the release signing key's signing subkey. RHEL 7's rpm reads only a key's primary key, so the archive's nes-php.repo gives yum that subkey as a key of its own, RPM-GPG-KEY-php-nes-subkey. When yum asks to import it, check that its fingerprint is 3A4BDF48590EBCC891C2133CD75FFA42A9EAF7B9.
Move from Remi's PHP 7.4
Remi's builds of PHP 7.4.33 sort above NES's, so yum update does not move
a host from his packages. Add the repository as above. Then remove his
packages that NES does not build (php-imap, php-tidy, php-pdo-dblib,
php-pdo-firebird and php-litespeed), and move every PHP package, and
libzip5, to NES's builds with yum distro-sync:
sudo yum remove php-imap php-tidy php-pdo-dblib php-pdo-firebird php-litespeed # those installed
sudo yum distro-sync 'php*' libzip5
php -v
The repository's priority 5 makes yum take these packages from it. NES's
libzip5 is libzip 1.6.1 with a fix that Remi's newer build does not need,
and NES's php-pecl-zip requires it. Remi's php-pecl-igbinary stays
installed and keeps loading.
Configure
PHP reads /etc/php.ini and /etc/php.d/. php-fpm is the php-fpm service,
and its pool listens on 127.0.0.1:9000, as Remi's does. The Apache module,
for httpd's prefork MPM, is loaded by /etc/httpd/conf.d/php.conf; restart
httpd after you install or upgrade.
sudo systemctl enable php-fpm
sudo systemctl start php-fpm
Upgrade
Set tag to the new release, download and verify its repository as above, then:
sudo rm -rf /opt/nes-php && sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.el7.$(uname -m).repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/nes-php.repo /etc/yum.repos.d/nes-php.repo
sudo yum clean metadata
sudo yum update 'php*' libzip5
Uninstall
Remove the NES packages and the repository:
sudo yum remove $(rpm -qa --qf '%{NAME} %{RELEASE}\n' | awk '$2 ~ /\.nes\./ { print $1 }')
sudo rm /etc/yum.repos.d/nes-php.repo
sudo rm -rf /opt/nes-php
To go back to Remi's packages instead, remove the repository file and
/opt/nes-php, then run sudo yum distro-sync 'php*' libzip5 with his
repositories enabled.
RHEL 6 and 7, CentOS and Oracle Linux
The PHP 5.6 packages are for RHEL 6 and RHEL 7, and also serve CentOS 6, Oracle Linux 6, CentOS 7 and Oracle Linux 7.
They have the standard names (php, php-cli, php-fpm, php-mysqlnd and
the rest), paths and configuration files, and replace the PHP 5.6 packages
a host already has.
Download and verify
In an empty directory, download the signing key, the checksums and the repository for your RHEL version:
base=https://registry.nes.herodevs.com/bin/nes/php/$tag
auth="<your-contact-email>:<your-nes-access-token>"
arch=$(uname -m)
for f in RPM-GPG-KEY-php-nes SHASUMS256.txt SHASUMS256.txt.asc "php-$tag.el6.$arch.repo.tar.xz"; do
curl -fSLO -u "$auth" "$base/$f"
done
Then verify the downloads:
gpg --with-fingerprint RPM-GPG-KEY-php-nes # must show CA44E935A3995EB733AF292B18DD1E9212F3C6A2
gpg --import RPM-GPG-KEY-php-nes
gpg --verify SHASUMS256.txt.asc SHASUMS256.txt
ls | awk 'NR == FNR { have[$0]; next } $2 in have' - SHASUMS256.txt | sha256sum -c -
Install
The NES packages do not include php-oci8. If the host has it from its previous repository, remove it first (sudo yum remove php-oci8): while one is installed, yum update stops on its dependencies and changes nothing.
Add the repository, then upgrade the PHP packages the host has (tar needs
xz: sudo yum install xz):
sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.*.repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/nes-php.repo /etc/yum.repos.d/nes-php.repo
sudo yum update 'php*'
On a host without PHP, install the packages you need instead, for example
sudo yum install php-cli php-fpm php-mysqlnd.
The packages are signed with the release signing key's signing subkey. The rpm of RHEL 6 and 7 reads only a key's primary key, so the repository gives yum that subkey as a key of its own, RPM-GPG-KEY-php-nes-subkey. When yum asks to import it, check that its fingerprint is 3A4BDF48590EBCC891C2133CD75FFA42A9EAF7B9.
Check the installation:
php -v
Configure
PHP reads /etc/php.ini and /etc/php.d/. php-fpm is the php-fpm service.
The Apache module is loaded by /etc/httpd/conf.d/php.conf; restart httpd
after you install or upgrade.
sudo systemctl enable php-fpm
sudo systemctl start php-fpm
Upgrade
Set tag to the new release, download and verify its repository as above, then:
sudo rm -rf /opt/nes-php && sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.*.repo.tar.xz -C /opt/nes-php --strip-components=1
sudo yum clean metadata
sudo yum update 'php*'
Uninstall
Remove the NES packages and the repository:
sudo yum remove $(rpm -qa --qf '%{NAME} %{RELEASE}\n' | awk '$2 ~ /\.nes\./ { print $1 }')
sudo rm /etc/yum.repos.d/nes-php.repo
sudo rm -rf /opt/nes-php
To go back to the PHP 5.6 packages you used before, install them again from their repository.
RHEL 6
NES for PHP 7 provides PHP 7.1.33 for RHEL 6, on x86_64 only. The packages
serve CentOS 6 as well. They replace Remi's PHP 7.1 packages for el6
(remi-php71) under the same names (php, php-cli, php-fpm and the rest,
php-pear, php-pecl-apcu and php-pecl-zip), with the same paths and
configuration files. Their Release, 11.<N>.nes.el6, is newer than Remi's
10.el6.remi, so yum update moves a host from Remi's packages to NES's.
This section is for PHP 7.1; for PHP 5.6 on RHEL 6, see
RHEL 6 and 7, CentOS and Oracle Linux.
RHEL 6 is past the end of its maintenance support. NES for PHP fixes PHP and the libraries it carries its own copy of (PCRE, oniguruma, libgd and libzip), not RHEL 6's own packages: OpenSSL (1.0.1e, which PHP's OpenSSL extension is built against there), curl (which uses NSS), libxml2, ICU and the rest.
Download and verify
In an empty directory, download the signing key, the checksums and the
repository (tar needs xz: sudo yum install xz):
base=https://registry.nes.herodevs.com/bin/nes/php/$tag
auth="<your-contact-email>:<your-nes-access-token>"
for f in RPM-GPG-KEY-php-nes SHASUMS256.txt SHASUMS256.txt.asc "php-$tag.el6.x86_64.repo.tar.xz"; do
curl -fSLO -u "$auth" "$base/$f"
done
Then verify the downloads. RHEL 6's GnuPG 2.0 has no --show-keys and its
sha256sum has no --ignore-missing, so this checks the files you
downloaded:
gpg --with-fingerprint RPM-GPG-KEY-php-nes # must show CA44E935A3995EB733AF292B18DD1E9212F3C6A2
gpg --import RPM-GPG-KEY-php-nes
gpg --verify SHASUMS256.txt.asc SHASUMS256.txt
ls | awk 'NR == FNR { have[$0]; next } $2 in have' - SHASUMS256.txt | sha256sum -c -
Install
php-mcrypt, php-pdo-dblib and php-gd need EPEL 6 (for libmcrypt,
freetds and libwebp); no other package needs it. EPEL 6 is archived: a
host that installs one of these packages needs a repository for EPEL 6's
archive.
Add the repository:
sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.el6.x86_64.repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/nes-php.repo /etc/yum.repos.d/nes-php.repo
On a host with Remi's PHP 7.1 packages, remove apcu-panel,
php-interbase and php-litespeed if they are installed: NES builds none of
them, and Remi's require his exact php-common (apcu-panel his exact
php-pecl-apcu). Then upgrade:
sudo yum remove apcu-panel php-interbase php-litespeed # those installed
sudo yum update 'php*'
php -v
Remi's other PECL packages stay installed and keep loading, as they need only
PHP's API and ABI versions (php-pecl-igbinary is tested; one built against
Remi's APCu 5.1.19, such as php-pecl-apcu-bc, is not). NES's
php-pecl-apcu is APCu 5.1.28, and a host with Remi's newer php-pecl-zip
keeps it.
A host with RHEL 6's own PHP 5.3 removes it, and the extensions built for it, first. That move is not tested. Then, as on a host without PHP, install the packages you need:
sudo yum remove 'php*' # RHEL 6's own PHP 5.3 only
sudo yum install php-cli php-fpm
php -v
The packages are signed with the release signing key's signing subkey. RHEL 6's rpm reads only a key's primary key, so the archive's nes-php.repo gives yum that subkey as a key of its own, RPM-GPG-KEY-php-nes-subkey. When yum asks to import it, check that its fingerprint is 3A4BDF48590EBCC891C2133CD75FFA42A9EAF7B9. The repository's priority=5 matters only with yum-plugin-priorities installed.
Configure
PHP reads /etc/php.ini and /etc/php.d/. As on Remi's el6 packages,
php-fpm is a SysV service, php-fpm, that listens on 127.0.0.1:9000:
sudo chkconfig php-fpm on
sudo service php-fpm start
The httpd and nginx configurations for php-fpm are documentation in
/usr/share/doc/php-fpm-7.1.33/.
httpd 2.2 runs PHP through mod_php, loaded by /etc/httpd/conf.d/php.conf;
restart httpd after you install or upgrade. mod_php works with httpd's
prefork MPM, RHEL 6's default, only: there is no ZTS build (zts-php,
libphp7-zts.so), and under the worker MPM php.conf refuses PHP files
rather than serve their source. A host on httpd.worker moves to prefork or
to php-fpm first.
APCu's apc.mmap_hugepage_size has no effect: RHEL 6's kernel headers lack
the hugepage size flags.
Build an extension with pecl
pecl install of a recent PECL release (APCu 5.1.24 and later, for one)
needs Autoconf 2.64 or later, and RHEL 6's is 2.63. With php-devel
installed, install EPEL 6's autoconf268 and point pecl at it:
sudo yum install autoconf268
sudo PHP_AUTOCONF=autoconf268 PHP_AUTOHEADER=autoheader268 pecl install <package>
Upgrade
Set tag to the new release, download and verify its repository as above, then:
sudo rm -rf /opt/nes-php && sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.el6.x86_64.repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/nes-php.repo /etc/yum.repos.d/nes-php.repo
sudo yum clean metadata
sudo yum update 'php*'
Uninstall
Remove the NES packages and the repository:
sudo yum remove $(rpm -qa --qf '%{NAME} %{RELEASE}\n' | awk '$2 ~ /\.nes\./ { print $1 }')
sudo rm /etc/yum.repos.d/nes-php.repo
sudo rm -rf /opt/nes-php
To go back to Remi's packages instead, with remi-php71 enabled, run
sudo yum --disablerepo=nes-php distro-sync 'php*', then remove the
repository file and /opt/nes-php.
Amazon Linux 2
The packages replace the php<X.Y> amazon-linux-extras topic's packages under
the same names.
AWS ended standard support for Amazon Linux 2 on 2026-06-30. NES for PHP 7 patches PHP, not the operating system's own packages, such as OpenSSL or libcurl.
Download and verify
In an empty directory, download the signing key, the checksums and the repository:
# Published for PHP 7.4, 7.2 and 7.1 only
base=https://registry.nes.herodevs.com/bin/nes/php/$tag
auth="<your-contact-email>:<your-nes-access-token>"
arch=$(uname -m)
for f in RPM-GPG-KEY-php-nes SHASUMS256.txt SHASUMS256.txt.asc "php-$tag.amazonlinux2.$arch.repo.tar.xz"; do
curl -fSLO -u "$auth" "$base/$f"
done
Then verify the downloads:
gpg --with-fingerprint RPM-GPG-KEY-php-nes # must show CA44E935A3995EB733AF292B18DD1E9212F3C6A2
gpg --import RPM-GPG-KEY-php-nes
gpg --verify SHASUMS256.txt.asc SHASUMS256.txt
ls | awk 'NR == FNR { have[$0]; next } $2 in have' - SHASUMS256.txt | sha256sum -c -
Install
sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.*.repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/nes-php.repo /etc/yum.repos.d/nes-php.repo
sudo yum update
On a host without PHP, install the packages you need instead, for example
sudo yum install php-cli php-fpm php-mysqlnd.
Remove apcu-panel first (sudo yum remove apcu-panel) if it is installed. The steps are for a host without PHP or with the php<X.Y> topic of your PHP version; do not use them on a host with a PHP 8 topic.
Configure
PHP reads /etc/php.ini and /etc/php.d/. php-fpm is the php-fpm service:
sudo systemctl enable --now php-fpm
Upgrade
Set tag to the new release, download and verify its repository as above, then:
sudo rm -rf /opt/nes-php && sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.*.repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/nes-php.repo /etc/yum.repos.d/nes-php.repo
sudo yum clean metadata
sudo yum update
Uninstall
Return to the php<X.Y> topic's packages and remove the repository:
sudo yum --disablerepo=nes-php distro-sync 'php*'
sudo rm /etc/yum.repos.d/nes-php.repo
sudo rm -rf /opt/nes-php
Amazon Linux 1
NES for PHP 7 provides PHP 7.1.33 for Amazon Linux 1 (Amazon Linux AMI
2018.03) on x86_64. The packages replace Amazon's php71 packages under the
same names (php71, php71-cli, php71-fpm and the rest, and php7-pear),
and install beside Amazon's other PHP versions, as Amazon's do.
Amazon Linux 1 reached its end of life on 2023-12-31. NES for PHP 7 patches PHP and the libraries it carries its own copy of, not the operating system's own packages, such as OpenSSL (1.0.2k, which PHP's OpenSSL extension is built against there) or libcurl. PHP reads time zones from the system's tzdata, as Amazon's php71 does: Amazon Linux 1's last tzdata is 2023c, so PHP does not know a time zone change made after it.
Download and verify
In an empty directory, download the signing key, the checksums and the repository:
# Published for PHP 7.1 only, x86_64 only
base=https://registry.nes.herodevs.com/bin/nes/php/$tag
auth="<your-contact-email>:<your-nes-access-token>"
for f in RPM-GPG-KEY-php-nes SHASUMS256.txt SHASUMS256.txt.asc "php-$tag.amazonlinux1.x86_64.repo.tar.xz"; do
curl -fSLO -u "$auth" "$base/$f"
done
Then verify the downloads:
gpg --with-fingerprint RPM-GPG-KEY-php-nes # must show CA44E935A3995EB733AF292B18DD1E9212F3C6A2
gpg --import RPM-GPG-KEY-php-nes
gpg --verify SHASUMS256.txt.asc SHASUMS256.txt
ls | awk 'NR == FNR { have[$0]; next } $2 in have' - SHASUMS256.txt | sha256sum -c -
Install
The repository has priority 5 (yum-plugin-priorities, which the Amazon Linux
AMI installs), so its packages take the place of the packages of the same name
in Amazon's repositories. Their Release, 44.<N>.nes.amzn1, is also newer than
Amazon's own 1.43.amzn1, so yum update moves a host from Amazon's php71
packages to NES's:
sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.*.repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/nes-php.repo /etc/yum.repos.d/nes-php.repo
sudo yum update
On a host without PHP, install the packages you need instead, for example
sudo yum install php71-cli php71-fpm php71-mysqlnd.
Remove apcu71-panel first (sudo yum remove apcu71-panel) if it is installed: it requires Amazon's exact php71-pecl-apcu. NES's php71-pecl-apcu is APCu 5.1.28. Amazon's other PECL packages (php71-pecl-*) stay installed and keep loading.
php7-pear. NES's php7-pear is PEAR 1.10.18, with Amazon's pear7 and
pecl7 commands. Amazon Linux 1 has one php7-pear for all its PHP 7
versions, PEAR 1.10.12. With the NES repository, yum update replaces it with
NES's, also on a host that runs another PHP 7 version. With php71-devel and a
compiler, pecl7 install builds an extension for NES's PHP 7.1.
Configure
PHP reads /etc/php-7.1.ini and /etc/php-7.1.d/ (/etc/php.ini and
/etc/php.d point to them while PHP 7.1 is the selected alternative). php-fpm is the
php-fpm-7.1 service, with its pools in /etc/php-fpm-7.1.d/:
sudo chkconfig php-fpm-7.1 on
sudo service php-fpm-7.1 start
Upgrade
Set tag to the new release, download and verify its repository as above, then:
sudo rm -rf /opt/nes-php && sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.*.repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/nes-php.repo /etc/yum.repos.d/nes-php.repo
sudo yum clean metadata
sudo yum update
Uninstall
Return to Amazon's php71 packages and remove the repository:
sudo yum --disablerepo=nes-php distro-sync 'php71*' php7-pear
sudo rm /etc/yum.repos.d/nes-php.repo
sudo rm -rf /opt/nes-php
Amazon Linux 2023
The packages follow Amazon Linux's names for a PHP version: php<X.Y>,
php<X.Y>-cli, php<X.Y>-fpm and the rest. One PHP version is installed at a
time. This section is for PHP 7.4 and PHP 7.3; PHP 8.1 has steps of its own,
see PHP 8.1 on Amazon Linux 2023.
Download and verify
In an empty directory, download the signing key, the checksums and the repository:
# Published for PHP 7.4, 7.3 and 7.2 only
base=https://registry.nes.herodevs.com/bin/nes/php/$tag
auth="<your-contact-email>:<your-nes-access-token>"
arch=$(uname -m)
for f in RPM-GPG-KEY-php-nes SHASUMS256.txt SHASUMS256.txt.asc "php-$tag.amazonlinux2023.$arch.repo.tar.xz"; do
curl -fSLO -u "$auth" "$base/$f"
done
Then verify the downloads:
gpg --show-keys RPM-GPG-KEY-php-nes # must show CA44E935A3995EB733AF292B18DD1E9212F3C6A2
gpg --import RPM-GPG-KEY-php-nes
gpg --verify SHASUMS256.txt.asc SHASUMS256.txt
sha256sum -c --ignore-missing SHASUMS256.txt
Install
Bring the host to the latest Amazon Linux 2023 release, add the repository, then install the packages you need:
sudo dnf upgrade --releasever=latest
sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.*.repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/nes-php.repo /etc/yum.repos.d/nes-php.repo
sudo dnf install php$line-cli php$line-fpm php$line-mysqlnd
On a host with Amazon Linux's PHP 8, add --allowerasing and name the
php$line package for each PHP 8 package you have (for example
php$line-cli for php8.4-cli): dnf then replaces PHP 8.
Configure
PHP reads /etc/php.ini and /etc/php.d/. php-fpm is the php-fpm service:
sudo systemctl enable --now php-fpm
Upgrade
Set tag to the new release, download and verify its repository as above, then:
sudo rm -rf /opt/nes-php && sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.*.repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/nes-php.repo /etc/yum.repos.d/nes-php.repo
sudo dnf upgrade --refresh
Uninstall
sudo dnf remove $(rpm -qa --qf '%{NAME} %{RELEASE}\n' | awk '$2 ~ /\.nes\./ { print $1 }')
sudo rm /etc/yum.repos.d/nes-php.repo
sudo rm -rf /opt/nes-php
To go back to Amazon Linux's PHP 8 instead, install its packages with
--allowerasing, for example sudo dnf install --allowerasing php8.4-cli php8.4-fpm.
PHP 8.1 on Amazon Linux 2023
NES for PHP 8 provides PHP 8.1.34 for Amazon Linux 2023 on x86_64 and aarch64.
A release is one signed dnf repository archive per architecture,
php-<release>.amazonlinux2023.<arch>.repo.tar.xz. Each archive holds the
release signing key, a nes-php.repo repository file, a repo/ directory with
the signed RPMs and their metadata, and the signed source RPM in src/. The
release also has the PHP source tarball, php-<release>.tar.xz.
The packages have Amazon Linux's own names for PHP 8.1 (php8.1,
php8.1-cli, php8.1-fpm, php8.1-mysqlnd and the rest) and its paths and
configuration files: /etc/php.ini, /etc/php.d/, /etc/php-fpm.d/ and
/usr/lib64/php/modules/ for extensions. The extension API is PHP 8.1's (PHP
API 20210902), so an extension built for PHP 8.1 loads without a rebuild.
Add this repository only to hosts that run NES for PHP 8.1, or are moving to it. Its repository file has priority=5, ahead of Amazon Linux's own repositories (priority=10), so it also takes over the plain package names: dnf install php, php-cli or php-fpm installs NES's PHP 8.1. Its php-pear replaces Amazon Linux's shared php-pear on dnf upgrade, even on a host that runs another PHP version.
Download and verify
Set tag to the PHP 8.1 release, v8.1.34-nes-8.1.3. In an empty directory, download the signing
key, the checksums and the repository for your architecture, then verify them:
tag=v8.1.34-nes-8.1.3
base=https://registry.nes.herodevs.com/bin/nes/php/$tag
auth="<your-contact-email>:<your-nes-access-token>"
arch=$(uname -m)
for f in RPM-GPG-KEY-php-nes SHASUMS256.txt SHASUMS256.txt.asc "php-$tag.amazonlinux2023.$arch.repo.tar.xz"; do
curl -fSLO -u "$auth" "$base/$f"
done
gpg --show-keys RPM-GPG-KEY-php-nes # must show CA44E935A3995EB733AF292B18DD1E9212F3C6A2
gpg --import RPM-GPG-KEY-php-nes
gpg --verify SHASUMS256.txt.asc SHASUMS256.txt
sha256sum -c --ignore-missing SHASUMS256.txt
Add the repository
The packages are built against the newest Amazon Linux 2023 release, so bring
the host to it first. Then extract the archive to /opt/nes-php and add its
repository file as it is:
sudo dnf upgrade --releasever=latest
sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.amazonlinux2023.$(uname -m).repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/nes-php.repo /etc/yum.repos.d/nes-php.repo
Keep priority=5 in nes-php.repo. dnf takes a package name only from the
repositories with the best priority that have it, whatever its version: at
dnf's default priority (99), dnf would keep Amazon Linux's PHP 8.1 and never
offer these packages. dnf checks every package's signature against the release
signing key (gpgcheck=1).
Install
On a host without PHP, install the packages you need:
sudo dnf install php8.1-cli php8.1-fpm php8.1-mysqlnd
php -v
Upgrade from Amazon Linux's PHP 8.1
Amazon Linux 2023 has PHP 8.1 packages of its own, with the same names. On a host that runs them, add the repository as above, then upgrade:
sudo dnf upgrade --refresh
php -v
dnf replaces Amazon Linux's packages in place. Every NES package has Epoch 1
(php-pear has Epoch 2), so it sorts above every Amazon Linux build of the same
package, later ones included, and no Amazon Linux update replaces it again. The
upgrade keeps your edits to /etc/php.ini, /etc/php.d/ and
/etc/php-fpm.d/, and php-fpm restarts on the new build by itself.
- Amazon Linux's PECL extensions that NES does not build
(
php8.1-pecl-igbinary,php8.1-pecl-msgpack,php8.1-pecl-memcachedandphp8.1-pecl-redis6) stay installed and load into NES's PHP 8.1, which has the same extension API. - NES adds
php8.1-sodium, which Amazon Linux's PHP 8.1 does not have; dnf installs it withphp8.1. - Amazon Linux's
php8.1-*packages require their own PHP build, so a PHP 8.1 package that Amazon Linux adds later, and NES does not ship, does not install on a host with NES's PHP 8.1.
php-pear. NES's php-pear is PEAR 1.10.18, which reads the chunked responses of pecl.php.net. Amazon Linux has one php-pear for all its PHP versions, PEAR 1.10.13. With the NES repository, dnf upgrade replaces it with NES's, also on a host that runs another PHP version. With php8.1-devel and a compiler, pecl install builds an extension for NES's PHP 8.1.
Roll back to Amazon Linux's PHP 8.1
Remove the NES repository, then let dnf return every PHP package to Amazon Linux's newest build:
sudo rm /etc/yum.repos.d/nes-php.repo && sudo dnf distro-sync --allowerasing
sudo rm -rf /opt/nes-php
--allowerasing lets dnf remove php8.1-sodium, which only NES ships: without
it, distro-sync stops on that package. Every other package, php-pear
included, returns to Amazon Linux's build.
Move from another of Amazon Linux's PHP versions
One PHP version is installed at a time. On a host with another of Amazon
Linux's PHP 8 versions, add the repository as above, then install the php8.1
counterpart of each of its packages with --allowerasing, which removes the
other version's. For example, on a host with php8.4-cli and php8.4-fpm:
sudo dnf install --allowerasing php8.1-cli php8.1-fpm
Configure
PHP reads /etc/php.ini and /etc/php.d/. php-fpm is the php-fpm service;
its pools are in /etc/php-fpm.d/, and the default pool listens on
/run/php-fpm/www.sock. There is no Apache module: Apache httpd and nginx run
PHP through php-fpm.
sudo systemctl enable --now php-fpm
Behaviour changes
Two mitigations change how PHP 8.1 behaves:
- A script that runs out of
memory_limitnow ends its process at once, with exit status 1: no error handler, shutdown function or destructor runs, and buffered output is not sent. PHP logs the fatal error (toerror_log; with php-fpm, to the pool's error log), and php-fpm starts a new worker in its place. Raisememory_limitwhere a script needs more. This is the mitigation of CVE-2026-109618 and CVE-2026-109619. - Session upload progress is off:
/etc/php.inisetssession.upload_progress.enabled = Off, its compiled default isOff, and setting it toOnhas no effect. This mitigates CVE-2026-115560, which needs session upload progress and has no upstream fix yet; the fix will follow in a later release.
Upgrade to a later release
Set tag to the new release, download and verify its archive as above, then:
sudo rm -rf /opt/nes-php && sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.amazonlinux2023.$(uname -m).repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/nes-php.repo /etc/yum.repos.d/nes-php.repo
sudo dnf upgrade --refresh
Uninstall
Remove the NES packages and the repository:
sudo dnf remove $(rpm -qa --qf '%{NAME} %{RELEASE}\n' | awk '$2 ~ /\.nes\./ { print $1 }')
sudo rm /etc/yum.repos.d/nes-php.repo
sudo rm -rf /opt/nes-php
To go back to Amazon Linux's PHP 8.1 instead, see Roll back to Amazon Linux's PHP 8.1.
PHP 8.1 on Ubuntu 18.04
NES for PHP 8 provides PHP 8.1.34 for Ubuntu 18.04 (Bionic) on amd64 and
arm64. A release is one signed apt repository archive per architecture,
php-<release>.ubuntu1804.<arch>.repo.tar.xz, with <arch> amd64 or
arm64. Each archive holds the release signing key (nes-php.asc), an apt
source (nes-php.list) and a repo/ directory with the debs and their signed
index (InRelease).
The packages have Ondřej Surý's names for PHP 8.1 (php8.1, php8.1-cli,
php8.1-fpm, libapache2-mod-php8.1 and the rest) and paths:
/usr/bin/php8.1, /etc/php/8.1/<sapi>/php.ini and /usr/lib/php/20210902/
for extensions. They come with NES's own php-common and php-pear (PEAR
1.10.18). Every package has epoch 1, so it sorts above any other php8.1 build:
dpkg-query -W php8.1-cli shows 1:8.1.34+nes8.1.3-1~ubuntu18.04.
Ubuntu 18.04 is past Canonical's standard support. NES for PHP fixes PHP, not Ubuntu 18.04's own packages, and the NES php8.1 links the distribution's libraries, so some of their limits remain:
- OpenSSL 1.1.1 has no implicit rejection, so
openssl_private_decrypt()with PKCS#1 v1.5 padding stays exposed to the Marvin attack (CVE-2024-2408). UseOPENSSL_PKCS1_OAEP_PADDING. - libpq 10 does not reject invalid multibyte input when it escapes (CVE-2025-1094 is a PostgreSQL CVE):
pg_escape_literal(),pg_escape_identifier(),PDO::quote()and emulated prepares escape such input instead of failing, where a newer libpq makes them fail. Ubuntu 18.04's public archive has no libpq with that rejection. - With libzip 1.1.2,
ZipArchivehas no encryption (setEncryptionName(),setEncryptionIndex()), no progress or cancel callbacks, and noisCompressionMethodSupported()orisEncryptionMethodSupported(). - The other libraries are Bionic's too: ICU 60, Oniguruma 6.7, libsodium 1.0.16 (without Ristretto255), SQLite 3.22, curl 7.58 and libxml2 2.9.4. PCRE2 and GD are PHP's own bundled copies, as on Amazon Linux 2023.
Download and verify
Set tag to the PHP 8.1 release, v8.1.34-nes-8.1.3. In an empty directory,
download the signing key, the checksums and the repository for your
architecture, then verify them (gpg is in the gnupg package, tar needs
xz-utils). Bionic's GnuPG 2.2.4 has no --show-keys, so
--with-fingerprint shows the key:
tag=v8.1.34-nes-8.1.3
base=https://registry.nes.herodevs.com/bin/nes/php/$tag
auth="<your-contact-email>:<your-nes-access-token>"
arch=$(dpkg --print-architecture)
for f in RPM-GPG-KEY-php-nes SHASUMS256.txt SHASUMS256.txt.asc "php-$tag.ubuntu1804.$arch.repo.tar.xz"; do
curl -fSLO -u "$auth" "$base/$f"
done
gpg --with-fingerprint RPM-GPG-KEY-php-nes # must show CA44E935A3995EB733AF292B18DD1E9212F3C6A2
gpg --import RPM-GPG-KEY-php-nes
gpg --verify SHASUMS256.txt.asc SHASUMS256.txt
sha256sum -c --ignore-missing SHASUMS256.txt
Add the repository
Ubuntu 18.04 ships PHP 7.2, not PHP 8.1, so the NES php8.1 installs beside
Ubuntu's PHP 7.2. Extract the archive to /opt/nes-php, add its apt source,
then run apt-get --with-new-pkgs upgrade first:
sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.ubuntu1804.$(dpkg --print-architecture).repo.tar.xz -C /opt/nes-php --strip-components=1
sudo cp /opt/nes-php/nes-php.list /etc/apt/sources.list.d/nes-php.list
sudo apt-get update
sudo apt-get --with-new-pkgs upgrade
php-common and php-pear become NES's. Ubuntu's PHP 7.2 and its PECL
packages (php-apcu, php-redis and the others) keep working. apt checks
every package through the repository's InRelease, signed with the release
signing key.
Install
Then install the packages you need:
sudo apt-get install php8.1-cli php8.1-fpm
php8.1 -v
Installing php8.1-cli makes /usr/bin/php PHP 8.1, through the
alternatives' priority. To keep PHP 7.2 there, run
sudo update-alternatives --set php /usr/bin/php7.2.
Ubuntu's PECL packages are built for PHP 7.2 only. For PHP 8.1, build an
extension with pecl install, with php8.1-dev and the NES php-pear
installed.
Configure
Each PHP SAPI reads its own php.ini in /etc/php/8.1/cli/,
/etc/php/8.1/fpm/ or /etc/php/8.1/apache2/. php-fpm is the php8.1-fpm
service and listens on /run/php/php8.1-fpm.sock:
sudo systemctl enable --now php8.1-fpm
Turn an extension on or off with phpenmod -v 8.1 and phpdismod -v 8.1.
Upgrade to a later release
Set tag to the new release, download and verify its archive as above, then:
sudo rm -rf /opt/nes-php && sudo mkdir -p /opt/nes-php
sudo tar -xJf php-$tag.ubuntu1804.$(dpkg --print-architecture).repo.tar.xz -C /opt/nes-php --strip-components=1
sudo apt-get update
sudo apt-get --with-new-pkgs upgrade
Uninstall
Remove the NES php8.1 packages and the repository:
sudo apt-get purge $(dpkg-query -W -f '${db:Status-Abbrev} ${Package}\n' | awk '$1 ~ /^i/ && $2 ~ /^(php8\.1|libapache2-mod-php8\.1|libphp8\.1-embed)/ { print $2 }')
sudo rm /etc/apt/sources.list.d/nes-php.list
sudo apt-get update
sudo rm -rf /opt/nes-php
php-common and php-pear stay NES's builds, which Ubuntu's PHP 7.2 keeps
using. To return them to Ubuntu's, install Ubuntu's versions with
sudo apt-get install --allow-downgrades php-common=<version> php-pear=<version>
(apt-cache policy php-common php-pear lists them).
Verify Downloads
To verify the signing key, the checksum file and the downloaded files, see Verify Downloads.