Dev

How To Install and Use PHP 8.3 on FreeBSD 14

FreeBSD ships PHP 8.3 as binary packages, so PHP with Apache on FreeBSD 14 takes a few pkg install commands and one handler file. The packages you pull today also decide whether the box is exposed to PHP2Shell, the two remote code execution bugs PHP fixed in October 2026, and on FreeBSD the answer depends on which package branch your machine follows, not on what php -v prints.

Original content from computingforgeeks.com - post 62125

This guide installs PHP 8.3 with the common extensions, wires it into Apache 2.4 through mod_php, tests it with a phpinfo page and a sample script, and then shows how to prove your own server runs a fixed build. Every pkg and service command below was run in October 2026 on a FreeBSD 14.0 VM with php83 and mod_php83 8.3.36 from the quarterly packages, using IGNORE_OSVERSION (explained in Step 1) and without running freebsd-update, and the text outputs come from that box.

PHP 8.3 added these language features over 8.2:

  • Typed Class Constants: Support for declaring class, interface, trait, as well as enum constant types (collectively called β€œclass constants” from now on for the sake of simplicity).
  • New #[Override] Attribute: By adding the #[\Override] attribute to a method, PHP will ensure that a method with the same name exists in a parent class or in an implemented interface.
  • Deep-cloning of readonly properties: readonly properties may now be modified once within the magic __clone method to enable deep-cloning of readonly properties.
  • New json_validate() function: json_validate() allows to check if a string is syntactically valid JSON, while being more efficient than json_decode().
  • New Randomizer::getBytesFromString() method: The Random Extension method is extended by a new method to generate random strings consisting of specific bytes only. This method allows the developer to easily generate random identifiers, such as domain names, and numeric strings of arbitrary length.

You need a FreeBSD 14 machine on 14.4 or later with network access and the root password. FreeBSD 15 uses the same package names, but we did not lab-test this guide on 15. For most web applications PHP runs alongside a database such as MariaDB on FreeBSD and a web server such as Nginx or Apache; this guide uses Apache.

Step 1. Update the FreeBSD repository

Every command in this guide runs as root, and the FreeBSD base system has no sudo, so switch to a root shell first.

su -

Bring the package catalogue and the base system up to date before installing anything, so PHP lands on current libraries.

pkg update && pkg upgrade
freebsd-update fetch
freebsd-update install

On a machine that is already current, both pkg commands end with Your packages are up to date. as in this 2024 capture.

how to install and use php8.3 on freebsd14 13 01

On an older 14.x point release, pkg update can stop before it finishes. Our lab VM still ran 14.0 and refused the catalogue with this message:

Newer FreeBSD version for package zxfer:
To ignore this error set IGNORE_OSVERSION=yes
- package: 1404000
- running userland: 1400097
Ignore the mismatch and continue? [y/N]: pkg: repository FreeBSD contains packages for wrong OS version: FreeBSD:14:amd64

The FreeBSD:14 packages are built on 14.4 (1404000), the oldest 14.x release still supported, and 14.0 to 14.3 are past their end of life. FreeBSD 15.0 runs into the same mismatch, because the FreeBSD:15 packages are built on 15.1. Running with IGNORE_OSVERSION=yes lets pkg continue, and that is how we finished the lab, but it’s a stopgap. The real fix is moving to 14.4 or 14.5, which freebsd.org lists as supported until 31 December 2026 and 30 June 2027, or to FreeBSD 15 with the steps in our guide to upgrade FreeBSD 14 to 15 with freebsd-update.

Step 2. Install PHP 8.3 on FreeBSD

PHP 8.3 and its modules are in the FreeBSD binary package repositories, so there is nothing to compile. FreeBSD 13 is a different story: it reached end of life on 30 April 2026 and pkg.FreeBSD.org no longer serves FreeBSD:13 package sets, so this step only works on FreeBSD 14 or 15. Install the PHP package:

pkg install php83

The screenshot below was captured in March 2024, when the package was 8.3.1. A current install pulls a newer build, and the PHP2Shell step further down shows which one you need.

how to install and use php8.3 on freebsd14 13 02
Captured March 2024 with php83 8.3.1, which is vulnerable to PHP2Shell.

The base package gives you the PHP CLI and the PHP-FPM daemon. Extensions are separate packages on FreeBSD, so they come next.

Step 3. Install PHP 8.3 Extensions

Install the extensions most applications expect, plus the Apache module and two editors.

pkg install vim nano php83-xml mod_php83 php83-zip php83-mbstring php83-zlib php83-curl php83-mysqli php83-gd

pkg lists everything it will add before asking to proceed, and Apache is in that list because mod_php83 depends on it.

how to install and use php8.3 on freebsd14 13 03

Each extension drops an ext-20-*.ini file into /usr/local/etc/php, which is how PHP loads it. Sessions live in a separate package, php83-session, which isn’t in the list above; add it if your application uses session_start().

Step 4. Install Apache Web Server

Apache serves the PHP pages. On our box mod_php83 had already pulled in apache24 as a dependency in Step 3, so this command only confirms it is there.

pkg install apache24

You can check the installation using the command below:

pkg info apache24

The name, version and origin www/apache24 confirm the package is in place.

how to install and use php8.3 on freebsd14 13 04

Enable Apache at boot, start it and check its status.

sysrc apache24_enable=YES
service apache24 start
service apache24 status

Our first status call, run right after start, printed apache24 is not running. because httpd hadn’t written its PID file yet. Two seconds later the same command reported apache24 is running as pid 90., so wait a moment before you go hunting through /var/log/httpd-error.log. The AH00558 warning about the server’s fully qualified domain name is harmless and goes away once you set ServerName in httpd.conf.

Step 5. Test PHP 8.3 Installation

Apache loads libphp.so as soon as mod_php83 is installed, but it still needs a handler that sends .php files to PHP and a DirectoryIndex that includes index.php. Create the handler file.

vim /usr/local/etc/apache24/Includes/php.conf

Add the following configuration:

<IfModule dir_module>
    DirectoryIndex index.php index.html

    <FilesMatch "\.php$">
        SetHandler application/x-httpd-php
    </FilesMatch>

    <FilesMatch "\.phps$">
        SetHandler application/x-httpd-php-source
    </FilesMatch>
</IfModule>

This capture shows the same handler block open in nano, if you prefer that editor.

how to install and use php8.3 on freebsd14 13 05

Next, create a phpinfo page in Apache’s document root, /usr/local/www/apache24/data (Nginx users would use /usr/local/www/nginx):

vim /usr/local/www/apache24/data/info.php

Put a single phpinfo call in it.

<?php
phpinfo();
?>

Save and close the file then restart Apache service.

service apache24 restart

Before opening a browser, ask Apache for the page from the server itself. This shows the version Apache is actually running, which isn’t always the version the CLI reports:

curl -s http://localhost/info.php | grep -o 'PHP Version [0-9.]*' | head -1

Our server answered with the patched build:

PHP Version 8.3.36

In a web browser, open http://localhost/info.php (or the server’s IP, such as http://10.0.1.50/info.php). You should see the full PHP information page with Apache 2.0 Handler as the Server API. The screenshot is from the March 2024 capture, so it still shows 8.3.1; delete info.php once you’re done, because it tells anyone exactly which build you run.

how to install and use php8.3 on freebsd14 13 06
phpinfo captured March 2024 (PHP 8.3.1). A patched server shows 8.3.36 or later.

PHP is working, so try a small page that mixes HTML and PHP. Create index.php in the document root:

vim /usr/local/www/apache24/data/index.php

Paste this sample page into it.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Simple HTML Page with PHP</title>
</head>
<body>
    <h1>Hello, World!</h1>
    <p>This is a simple HTML page generated using PHP.</p>

    <?php
    // You can include PHP code within the HTML content
    $name = "John";
    echo "<p>Welcome, $name!</p>";
    ?>

</body>
</html>

The same file open in nano looks like this before you save it.

how to install and use php8.3 on freebsd14 13 07

Now open http://localhost/index.php in your browser and you should see the Hello World heading with the welcome line under it. Use the full /index.php path, because on our box a bare http://localhost/ still returned Apache’s stock “It works!” index.html. Apache 2.4 appends a second DirectoryIndex to the one in httpd.conf instead of replacing it, so index.html stays first; delete that file if you want index.php served at the root.

how to install and use php8.3 on freebsd14 13 08

With the sample page rendering, the install itself is finished. The next step checks it against the October 2026 PHP security release.

Step 6. Check FreeBSD PHP for PHP2Shell (CVE-2026-109618, CVE-2026-109619)

PHP2Shell is a pair of critical bugs in PHP itself, CVE-2026-109618 and CVE-2026-109619, that allow remote code execution over HTTP. PHP’s 20 October pre-announcement rated both CVSS v4.0 9.2, and the PHP security advisory of 21 October 2026 shipped the fixes in 8.5.12, 8.4.27, 8.3.36 and 8.2.35. On FreeBSD the fix reached the package branches unevenly. The catalogues we pulled from pkg.FreeBSD.org at 20:18 UTC on 22 October 2026 showed:

  • FreeBSD 14 quarterly (the default): php83 8.3.36, fixed
  • FreeBSD 14 latest: php83 8.3.35, not fixed
  • FreeBSD 15 latest: php83 8.3.36, fixed
  • FreeBSD 15 quarterly: php83 8.3.35, not fixed

So a fresh FreeBSD 14 install from this guide on the default branch is already patched, and you can stop after the audit check below. An existing server needs the upgrade and the restarts that follow it. Start with the vulnerability database, which -F refreshes before checking:

pkg audit -F | grep -A4 '^php8'

A patched server prints nothing. On a box still running 8.3.35, the VuXML entry for PHP2Shell shows up like this:

php83-8.3.35 is vulnerable:
  PHP -- Multiple vulnerabilities
  CVE: CVE-2026-109618
  CVE: CVE-2026-109619
  WWW: https://vuxml.FreeBSD.org/freebsd/d8e16d08-cd2f-11f1-8135-8447094a420f.html

The audit only covers the php83 package. pkg audit mod_php83-8.3.35 reported zero problems in our test, yet mod_php83 is the library Apache actually loads, so check both versions yourself. Each must read 8.3.36 or later:

pkg query '%n %v' php83 mod_php83

Before upgrading, ask the repository what it would install. If pkg rquery still prints 8.3.35, your branch hasn’t caught up and pkg upgrade will report nothing to do:

pkg update -f && pkg rquery '%n %v' php83 mod_php83

Switch branch only if pkg rquery on your current branch shows 8.3.35 or older, and move to whichever branch offers 8.3.36 or later. Branches catch up at different times, so the snapshot list above can be out of date by the time you read this; the rquery output is what counts. The override is a file under /usr/local/etc/pkg/repos.

mkdir -p /usr/local/etc/pkg/repos
vim /usr/local/etc/pkg/repos/FreeBSD.conf

On FreeBSD 14 the default repository is named FreeBSD, so this switches it to the latest branch.

FreeBSD: {
  url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest"
}

We ran that form on our FreeBSD 14 box, and pkg -vv then listed pkg+https://pkg.FreeBSD.org/FreeBSD:14:amd64/latest with SRV mirrors and fingerprint signatures, and pkg update -f completed. FreeBSD 15 renamed the default repository to FreeBSD-ports, and an override still named FreeBSD there creates a second, unsigned repository instead of changing the default. The 15 form below follows the FreeBSD.conf that the 15.0 release ships, and we did not run it.

FreeBSD-ports: {
  url: "pkg+https://pkg.FreeBSD.org/${ABI}/latest"
}

Run the pkg update -f and rquery line again to confirm the new branch offers 8.3.36. Deleting the file puts the machine back on quarterly. Once a fixed build is on offer, upgrade and restart everything that has PHP loaded:

pkg upgrade
service apache24 restart
service php_fpm restart

Skip the php_fpm line if you never set php_fpm_enable=YES, and restart long-running PHP CLI workers too. The restart isn’t optional: pkg didn’t restart anything in our test, and right after the upgrade php -v already printed 8.3.36 while Apache kept serving 8.3.35 from the old library. Confirm that both masters were started after the upgrade:

ps -o pid,etime,command -p $(cat /var/run/httpd.pid) $(cat /var/run/php-fpm.pid)

If you don’t run php_fpm, drop the $(cat /var/run/php-fpm.pid) part. Both elapsed times should be shorter than the time since the upgrade, and http://localhost/info.php should report 8.3.36:

PID ELAPSED COMMAND
566   00:03 /usr/local/sbin/httpd -DNOHTTPACCEPT
592   00:03 php-fpm: master process (/usr/local/etc/php-fpm.conf) (php-fpm)

If neither branch has a fixed package for your release, building lang/php83 and www/mod_php83 from a ports tree that already carries 8.3.36 is the other route. We didn’t run a ports build for this update. FreeBSD 13 has no package set at all any more, so a 13 server gets no fixed binary and needs to move to 14 or 15.

Until a fixed build is installed, PHP’s advisory lists mitigations that only reduce exposure, among them limits on field, part and header counts and nesting, so read it before relying on any of them. We tested three settings through real web requests. For mod_php, they go in a new Apache include file.

vim /usr/local/etc/apache24/Includes/php2shell.conf

Add the overrides, which apply to every request Apache hands to PHP:

<IfModule php_module>
    php_admin_flag session.upload_progress.enabled off
    php_admin_value memory_limit -1
    php_admin_value post_max_size 8M
</IfModule>

Restart Apache with service apache24 restart so every child picks them up. If PHP-FPM serves your sites instead, the same settings go at the end of the pool file.

vim /usr/local/etc/php-fpm.d/www.conf

Append the pool form of the same settings, then run service php_fpm restart:

php_admin_flag[session.upload_progress.enabled] = off
php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 8M

A probe page served by Apache went from upload_progress='1' memory_limit=128M to upload_progress='0' memory_limit=-1 post_max_size=8M under both mod_php and FPM, while php -r on the CLI still showed 1, so check through the web server. The upload progress setting only exists once php83-session is installed, and memory_limit -1 lets one request eat all the RAM, so watch memory and restore the limit after patching. Raise post_max_size to 32M if the site takes uploads, and keep upload_max_filesize below it. PHP is clear that these settings only reduce exposure: the upgrade is the fix.

Conclusion

You now have PHP 8.3 running under Apache on FreeBSD 14.4 or later, on a build you have checked against PHP2Shell. Keep pkg audit -F in your routine, because it catches the next PHP advisory the same way, and see how to manage packages and services on FreeBSD for the pkg and service commands this guide leaned on.

Keep reading

Install GitHub CLI (gh) on Linux, macOS, and Windows Programming Install GitHub CLI (gh) on Linux, macOS, and Windows Claude Sonnet 5.5 Released: Benchmarks, Pricing, vs Opus 5.5 AI Claude Sonnet 5.5 Released: Benchmarks, Pricing, vs Opus 5.5 Best Linux Laptops for Programming and Developers (2026) Programming Best Linux Laptops for Programming and Developers (2026) Best Monitor Arms for a Multi-Monitor Developer Desk Programming Best Monitor Arms for a Multi-Monitor Developer Desk Best Mouse and Keyboard for Programming Programming Best Mouse and Keyboard for Programming Is it Worth Outsourcing a Software Development Team? Here are the Pros and Cons Programming Is it Worth Outsourcing a Software Development Team? Here are the Pros and Cons

Leave a Comment

Press ESC to close