Installing packaged PHP on SUSE gives cron jobs, Composer runs, deployment hooks, and one-off maintenance scripts a supported interpreter without forcing Apache or PHP-FPM into the first install. That keeps the initial runtime small and leaves updates, security fixes, and later module changes on the normal zypper path.

On current openSUSE and SUSE Linux Enterprise branches, the current PHP 8 packages used here are published through the official openSUSE Build Service devel:languages:php project. The shared php8 package underpins the runtime, php8-cli adds the shell interpreter, and web-facing SAPIs and extensions stay split into separate RPMs such as php8-fpm, apache2-mod_php8, php8-mysql, and php8-zip.

The repository label is branch-specific, so the add-repo step must use the exact string published for the host. Current official repo files include labels such as openSUSE_Leap_15.6, 15.7, openSUSE_Tumbleweed, and SLE_15_SP6, and current Leap 15.6 package checks on aarch64 can return only srcpackage rows instead of installable binaries. Confirm the branch label and architecture before relying on the same package set across every SUSE system.

Steps to install PHP on SUSE:

  1. Check the installed SUSE release and CPU architecture before selecting the PHP repository label.
    $ grep -E '^(PRETTY_NAME|VERSION_ID)=' /etc/os-release
    PRETTY_NAME="openSUSE Leap 15.6"
    VERSION_ID="15.6"
    
    $ uname -m
    x86_64

    Leap 15.6 uses openSUSE_Leap_15.6, Leap 15.7 uses 15.7, Tumbleweed uses openSUSE_Tumbleweed, and SLE 15 SP6 uses SLE_15_SP6.

  2. Set a shell variable to the exact repository label published for the host.
    $ repo_label='openSUSE_Leap_15.6'

    Use the package's Expert Download page when the host runs another supported branch because the label format is not identical across every SUSE release.

  3. Add the official PHP repository definition for that label.
    $ sudo zypper addrepo "https://download.opensuse.org/repositories/devel:/languages:/php/${repo_label}/devel:languages:php.repo"

    Importing the published .repo file creates the devel_languages_php alias automatically, which is used in the later search step.

  4. Refresh the new repository metadata and import its signing key.
    $ sudo zypper --gpg-auto-import-keys refresh devel_languages_php

    The first refresh imports the current OBS signing key and builds the local metadata cache for the selected branch.

  5. Confirm that the selected branch publishes binary PHP packages for the current architecture.
    $ zypper search -s -r devel_languages_php --match-exact php8 php8-cli php8-fpm apache2-mod_php8 php8-curl php8-dom php8-mbstring php8-mysql php8-xmlreader php8-xmlwriter php8-zip
    Loading repository data...
    Reading installed packages...
    
    S  | Name             | Type    | Version            | Arch   | Repository
    ---+------------------+---------+--------------------+--------+-----------------------------------------
       | apache2-mod_php8 | package | 8.4.19-lp156.253.1 | x86_64 | devel:languages:php (openSUSE_Leap_15.6)
       | php8             | package | 8.4.19-lp156.253.1 | x86_64 | devel:languages:php (openSUSE_Leap_15.6)
       | php8-cli         | package | 8.4.19-lp156.253.1 | x86_64 | devel:languages:php (openSUSE_Leap_15.6)
    ##### snipped #####
       | php8-xmlwriter   | package | 8.4.19-lp156.253.1 | x86_64 | devel:languages:php (openSUSE_Leap_15.6)
       | php8-zip         | package | 8.4.19-lp156.253.1 | x86_64 | devel:languages:php (openSUSE_Leap_15.6)

    If the search shows only srcpackage rows, the selected branch does not currently publish installable binaries for that architecture.

  6. Install the packaged PHP CLI runtime.
    $ sudo zypper install php8-cli

    Installing php8-cli also pulls in the shared php8 package. When another enabled repository also offers PHP, add --from devel_languages_php to pin the install to the selected OBS branch.

  7. Verify that the interpreter is installed and reporting the expected CLI runtime.
    $ rpm -q php8 php8-cli
    php8-8.4.19-lp156.253.1.x86_64
    php8-cli-8.4.19-lp156.253.1.x86_64
    
    $ php -r 'printf("PHP_VERSION=%s\nPHP_SAPI=%s\n", PHP_VERSION, PHP_SAPI);'
    PHP_VERSION=8.4.19
    PHP_SAPI=cli

    The package release string varies by branch, but the installed php8 and php8-cli packages should resolve to the same build.

  8. Search the repository for the SAPI and extension packages required by the workload.
    $ zypper search -s -r devel_languages_php --match-exact php8-fpm apache2-mod_php8 php8-curl php8-dom php8-mbstring php8-mysql php8-xmlreader php8-xmlwriter php8-zip
    Loading repository data...
    Reading installed packages...
    
    S  | Name             | Type    | Version            | Arch   | Repository
    ---+------------------+---------+--------------------+--------+-----------------------------------------
       | apache2-mod_php8 | package | 8.4.19-lp156.253.1 | x86_64 | devel:languages:php (openSUSE_Leap_15.6)
       | php8-curl        | package | 8.4.19-lp156.253.1 | x86_64 | devel:languages:php (openSUSE_Leap_15.6)
       | php8-dom         | package | 8.4.19-lp156.253.1 | x86_64 | devel:languages:php (openSUSE_Leap_15.6)
    ##### snipped #####
       | php8-zip         | package | 8.4.19-lp156.253.1 | x86_64 | devel:languages:php (openSUSE_Leap_15.6)

    Use php8-fpm for FastCGI workloads or apache2-mod_php8 when Apache should load PHP directly. XML support is split across packages such as php8-dom, php8-xmlreader, and php8-xmlwriter instead of one generic php8-xml RPM.

  9. Install only the extra modules required by the application.
    $ sudo zypper install php8-curl php8-dom php8-mbstring php8-mysql php8-xmlreader php8-xmlwriter php8-zip

    Add php8-fpm or apache2-mod_php8 only when the host also needs a web-facing PHP SAPI.

  10. Confirm that the requested modules are loaded by the active CLI interpreter.
    $ php -m | grep -E '^(curl|dom|mbstring|mysqli|mysqlnd|xmlreader|xmlwriter|zip)$'
    curl
    dom
    mbstring
    mysqli
    mysqlnd
    xmlreader
    xmlwriter
    zip

    The php8-mysql package also loads mysqlnd, so seeing both mysqli and mysqlnd confirms the database driver stack is active.