Install PHP 8.4 on openSUSE 15 with PHP-FPM

PHP 8.4 is available for production use with lots of new features, improvements and deprecated ones as well. In this guide we show Linux users how they can install and use PHP 8.4 on openSUSE 15 Linux system. PHP is a server-side HTML embedded scripting language designed primarily for web development but also can also be used as a general-purpose programming language.

We assume you already have a newly installed and running openSUSE machine which can be in the Cloud, on premise virtualization platform, on VirtualBox or Vagrant provisioned machine.

Some of the features released with PHP 8.4 are as briefly described below. The examples used in this blog are from PHP 8.4.0 Release notes.

  • Property Hooks: Property hooks eliminate the need to write docblock comments that could become out of sync by supporting computed properties that are natively understood by IDEs and static analysis tools. Additionally, they make it possible to reliably pre- or post-process values without having to verify that the class contains a matching getter or setter.
  • Asymmetric Visibility: In order to expose a property’s value without permitting alteration from outside of a class, boilerplate getter methods are no longer necessary because the scope to write to and read a property can now be controlled individually.
# In earlier versions
class PhpVersion
{
    private string $version = '8.3';

    public function getVersion(): string
    {
        return $this->version;
    }

    public function increment(): void
    {
        [$major, $minor] = explode('.', $this->version);
        $minor++;
        $this->version = "{$major}.{$minor}";
    }
}
# In PHP 8.4 versions
class PhpVersion
{
    public private(set) string $version = '8.4';

    public function increment(): void
    {
        [$major, $minor] = explode('.', $this->version);
        $minor++;
        $this->version = "{$major}.{$minor}";
    }
}
  • #[\Deprecated] Attribute : The new #[\Deprecated] attribute makes PHP’s existing deprecation mechanism available to user-defined functions, methods, and class constants.
#In earlier PHP versions
class PhpVersion
{
    /**
     * @deprecated 8.3 use PhpVersion::getVersion() instead
     */
    public function getPhpVersion(): string
    {
        return $this->getVersion();
    }

    public function getVersion(): string
    {
        return '8.3';
    }
}

$phpVersion = new PhpVersion();
// No indication that the method is deprecated.
echo $phpVersion->getPhpVersion();
#In PHP 8.4 versions
class PhpVersion
{
    #[\Deprecated(
        message: "use PhpVersion::getVersion() instead",
        since: "8.4",
    )]
    public function getPhpVersion(): string
    {
        return $this->getVersion();
    }

    public function getVersion(): string
    {
        return '8.4';
    }
}

$phpVersion = new PhpVersion();
// Deprecated: Method PhpVersion::getPhpVersion() is deprecated since 8.4, use PhpVersion::getVersion() instead
echo $phpVersion->getPhpVersion();
  • New ext-dom features and HTML5 support: The new DOM API provides a number of features to make dealing with documents easier, fixes a number of long-standing compliance flaws in the behavior of the DOM capability, and supports processing HTML5 documents in a standards-compliant manner.
# In earlier PHP versions
$dom = new DOMDocument();
$dom->loadHTML(
    <<<'HTML'
        <main>
            <article>PHP 8.4 is a feature-rich release!</article>
            <article class="featured">PHP 8.4 adds new DOM classes that are spec-compliant, keeping the old ones for compatibility.</article>
        </main>
        HTML,
    LIBXML_NOERROR,
);

$xpath = new DOMXPath($dom);
$node = $xpath->query(".//main/article[not(following-sibling::*)]")[0];
$classes = explode(" ", $node->className); // Simplified
var_dump(in_array("featured", $classes)); // bool(true)

# In PHP 8.4
$dom = Dom\HTMLDocument::createFromString(
    <<<'HTML'
        <main>
            <article>PHP 8.4 is a feature-rich release!</article>
            <article class="featured">PHP 8.4 adds new DOM classes that are spec-compliant, keeping the old ones for compatibility.</article>
        </main>
        HTML,
    LIBXML_NOERROR,
);

$node = $dom->querySelector('main > article:last-child');
var_dump($node->classList->contains("featured")); // bool(true)
  • Object API for BCMath: When working with arbitrary precision numbers, the new BcMath\Number object allows for standard mathematical operators and object-oriented usage. These objects can be used in string contexts like echo $num since they implement the Stringable interface and are immutable.
#In earlier PHP versions
$num1 = '0.12345';
$num2 = 2;
$result = bcadd($num1, $num2, 5);

echo $result; // '2.12345'
var_dump(bccomp($num1, $num2) > 0); // false

#In PHP Version 8.4
use BcMath\Number;

$num1 = new Number('0.12345');
$num2 = new Number('2');
$result = $num1 + $num2;

echo $result; // '2.12345'
var_dump($num1 > $num2); // false
#In earlier PHP versions
$animal = null;
foreach (['dog', 'cat', 'cow', 'duck', 'goose'] as $value) {
    if (str_starts_with($value, 'c')) {
        $animal = $value;
        break;
    }
}

var_dump($animal); // string(3) "cat"

#In PHP 8.4
$animal = array_find(
    ['dog', 'cat', 'cow', 'duck', 'goose'],
    static fn (string $value): bool => str_starts_with($value, 'c'),
);

var_dump($animal); // string(3) "cat"
  • new MyClass()->method() without parentheses: Properties and methods of a newly instantiated object can now be accessed without wrapping the new expression in parentheses.
#In earlier PHP versions
class PhpVersion
{
public function getVersion(): string
{
return 'PHP 8.3';
}
}

var_dump((new PhpVersion())->getVersion());

#In PHP 8.4
class PhpVersion
{
public function getVersion(): string
{
return 'PHP 8.4';

Update System

Before any installations we advise users to ensure their Linux system is up-to-date. On openSUSE 15 use below commands to update the system.

sudo zypper refresh
sudo zypper update -y

Then check your openSUSE variant:

$ cat /etc/os-release
NAME="openSUSE Leap"
VERSION="15.6"
ID="opensuse-leap"
ID_LIKE="suse opensuse"
VERSION_ID="15.6"
PRETTY_NAME="openSUSE Leap 15.6"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:opensuse:leap:15.6"
BUG_REPORT_URL="https://bugs.opensuse.org"
HOME_URL="https://www.opensuse.org/"
DOCUMENTATION_URL="https://en.opensuse.org/Portal:Leap"
LOGO="distributor-logo-Leap"

Add PHP repository to your openSUSE 15 system.

For openSUSE 15.7:

sudo zypper addrepo https://download.opensuse.org/repositories/devel:languages:php/15.7/devel:languages:php.repo
sudo zypper refresh

For openSUSE Leap 15.6:

sudo zypper addrepo https://download.opensuse.org/repositories/devel:languages:php/openSUSE_Leap_15.6/devel:languages:php.repo
sudo zypper refresh

For SLE 15 SP6:

sudo zypper addrepo https://download.opensuse.org/repositories/devel:languages:php/SLE_15_SP6/devel:languages:php.repo
sudo zypper refresh

For SLE 15 SP5:

sudo zypper addrepo https://download.opensuse.org/repositories/devel:languages:php/SLE_15_SP5/devel:languages:php.repo
sudo zypper refresh

Accept the repository signing key:

New repository or package signing key received:

  Repository:       devel:languages:php (openSUSE_Leap_15.6)
  Key Fingerprint:  E1E2 F102 BC77 314F 4A4B 7542 BED0 FF75 7D17 C956
  Key Name:         devel:languages:php OBS Project <devel:languages:[email protected]>
  Key Algorithm:    RSA 4096
  Key Created:      Thu May  2 10:49:48 2024
  Key Expires:      Sat Jul 11 10:49:47 2026
  Rpm Name:         gpg-pubkey-7d17c956-6633459c



    Note: Signing data enables the recipient to verify that no modifications occurred after the data
    were signed. Accepting data with no, wrong or unknown signature can lead to a corrupted system
    and in extreme cases even to a system compromise.

    Note: A GPG pubkey is clearly identified by its fingerprint. Do not rely on the key's name. If
    you are not sure whether the presented key is authentic, ask the repository provider or check
    their web site. Many providers maintain a web page showing the fingerprints of the GPG keys they
    are using.

Do you want to reject the key, trust temporarily, or trust always? [r/t/a/?] (r): a
Retrieving repository 'devel:languages:php (openSUSE_Leap_15.6)' metadata ..........................................................................................................................[done]
Building repository 'devel:languages:php (openSUSE_Leap_15.6)' cache ...............................................................................................................................[done]
Repository 'Non-OSS Repository' is up to date.
Building repository 'Non-OSS Repository' cache .....................................................................................................................................................[done]
Repository 'Open H.264 Codec (openSUSE Leap)' is up to date.
Building repository 'Open H.264 Codec (openSUSE Leap)' cache .......................................................................................................................................[done]
Repository 'Main Repository' is up to date.
Building repository 'Main Repository' cache ........................................................................................................................................................[done]
All repositories have been refreshed.

Install PHP 8.4 on openSUSE 15

Install PHP 8.4 on openSUSE 15 using the command below:

sudo zypper install php8

Agree to the installation prompt:

Loading repository data...
Reading installed packages...
Resolving package dependencies...

The following 8 recommended packages were automatically selected:
  php8-ctype php8-dom php8-iconv php8-openssl php8-sqlite php8-tokenizer php8-xmlreader php8-xmlwriter

The following 4 packages are suggested, but will not be installed:
  php8-gd php8-gettext php8-mbstring php8-mysql

The following 11 NEW packages are going to be installed:
  php8 php8-cli php8-ctype php8-dom php8-iconv php8-openssl php8-pdo php8-sqlite php8-tokenizer php8-xmlreader php8-xmlwriter

11 new packages to install.

Package download size:     3.8 MiB

Package install size change:
              |      16.4 MiB  required by packages that will be installed
    16.4 MiB  |  -      0 B    released by packages that will be removed

Backend:  classic_rpmtrans
Continue? [y/n/v/...? shows all options] (y): y

To install php extension use the command syntax:

sudo zypper install php8-<extension>

Example:

sudo zypper install php8-zip php8-fpm php8-gd php8-gettext php8-mbstring php8-mysql

Accept installation prompt:

Loading repository data...
Reading installed packages...
Resolving package dependencies...

The following package is suggested, but will not be installed:
  systemd-sysvcompat

The following 8 NEW packages are going to be installed:
  libonig4 php8-fpm php8-gd php8-gettext php8-mbstring php8-mysql php8-zip system-user-wwwrun

8 new packages to install.

Package download size:     3.2 MiB

Package install size change:
              |      14.5 MiB  required by packages that will be installed
    14.5 MiB  |  -      0 B    released by packages that will be removed

Backend:  classic_rpmtrans
Continue? [y/n/v/...? shows all options] (y): y

Confirm php version.

$ php --version
PHP 8.4.7 (cli) (built: May  9 2025 12:00:00) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.4.7, Copyright (c) Zend Technologies

To check loaded PHP modules use the following command:

$ php -m
[PHP Modules]
Core
ctype
date
dom
filter
gd
gettext
hash
iconv
json
libxml
mbstring
mysqli
mysqlnd
openssl
pcre
PDO
pdo_mysql
pdo_sqlite
random
Reflection
session
SimpleXML
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
zip

[Zend Modules]

Running PHP 8.4 with Apache

Install apache2-mod_php8 package:

sudo zypper in apache2-mod_php8

Load PHP apache module:

sudo a2enmod php8

Then start and enable apache2 service.

sudo systemctl restart apache2
sudo systemctl enable apache2

Testing:

sudo tee /srv/www/htdocs/index.php<<EOF
<html>
<body>
<div style="width: 100%; font-size: 40px; font-weight: bold; text-align:center;">
<?php
    print "PHP Hello Page";
?>
</div>
</body>
</html>
EOF

Access http://server_ip_or_hostname/index.php

Running PHP 8.4 with Nginx

Stop and disable apache2 service:

sudo systemctl disable --now apache2

Install Nginx:

sudo zypper install nginx
sudo systemctl enable --now nginx

Install php8-fpm package.

sudo zypper install php8-fpm

Edit the configuration:

$ sudo vim /etc/php8/fpm/php-fpm.conf
# Uncomment the line
error_log = log/php-fpm.log

Set user and group.

$ sudo vim /etc/php8/fpm/php-fpm.d/www.conf
user  = nginx
group = nginx

When done start and enable service:

sudo systemctl enable --now php-fpm

Confirm status:

Create test index page.

sudo tee /srv/www/htdocs/index.php<<EOF
<html>
<body>
<div style="width: 100%; font-size: 40px; font-weight: bold; text-align:center;">
<?php
    print "PHP Hello from Nginx";
?>
</div>
</body>
</html>
EOF

Edit Nginx configuration to pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000:

$ sudo vim /etc/nginx/nginx.conf
# Line 78/79
location ~ \.php$ {
            root           /srv/www/htdocs/;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }

On openSUSE, AppArmor is likely enforcing. You can check if it’s blocking PHP from accessing files:

$ sudo aa-status
...
0 profiles are in complain mode.
0 profiles are in kill mode.
0 profiles are in unconfined mode.
5 processes have profiles defined.
5 processes are in enforce mode.
   /usr/sbin/avahi-daemon (773) avahi-daemon
   /usr/sbin/nscd (788) nscd
   /usr/sbin/php-fpm (9201) php-fpm
   /usr/sbin/php-fpm (9203) php-fpm
   /usr/sbin/php-fpm (9204) php-fpm
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.
0 processes are in mixed mode.
0 processes are in kill mode.

If AppArmor is enabled, try placing PHP-FPM into complain mode:

$ sudo aa-complain /etc/apparmor.d/php-fpm
Setting /etc/apparmor.d/php-fpm to complain mode.
$ sudo aa-status
1 profiles are in complain mode.
   php-fpm
0 profiles are in kill mode.
0 profiles are in unconfined mode.
5 processes have profiles defined.
2 processes are in enforce mode.
   /usr/sbin/avahi-daemon (773) avahi-daemon
   /usr/sbin/nscd (788) nscd
3 processes are in complain mode.
   /usr/sbin/php-fpm (9201) php-fpm
   /usr/sbin/php-fpm (9203) php-fpm
   /usr/sbin/php-fpm (9204) php-fpm
0 processes are unconfined but have a profile defined.
0 processes are in mixed mode.
0 processes are in kill mode.

Restart nginx and php-fpm:

sudo systemctl restart php-fpm nginx

Then acess the page via http://server_ip_or_hostname/index.php:

In this article we’ve been able to install PHP 8.4 and configure both Apache and Nginx web servers to serve PHP scripts. You can also check out other guides we have on openSUSE and Web hosting.

Join our Linux and open source community. Subscribe to our newsletter for tips, tricks, and collaboration opportunities!

Recent Post

Unlock the Right Solutions with Confidence

At CloudSpinx, we don’t just offer services - we deliver clarity, direction, and results. Whether you're navigating cloud adoption, scaling infrastructure, or solving DevOps challenges, our seasoned experts help you make smart, strategic decisions with total confidence. Let us turn complexity into opportunity and bring your vision to life.

Leave a Comment

Your email address will not be published. Required fields are marked *

Related Post

In this guide we’ll explore installation of Julia Programming Language on CentOS | RHEL 9 systems. Julia is dynamically typed, […]

Adobe Illustrator is a popular vector illustration application that one can use to capture their creative ideas. Designers use it […]

In today’s guide we will walk you through the steps to install Kotlin Programming Language on Linux Mint | Ubuntu. […]

Let's Connect

Unleash the full potential of your business with CloudSpinx. Our expert solutions specialists are standing by to answer your questions and tailor a plan that perfectly aligns with your unique needs.
You will get a response from our solutions specialist within 12 hours
We understand emergencies can be stressful. For immediate assistance, chat with us now

Contact CloudSpinx today!

Download CloudSpinx Profile

Discover the full spectrum of our expertise and services by downloading our detailed Company Profile. Simply enter your first name, last name, and email address.