Testing the PHP 8.5.4 release candidate: what’s fixed and how to try it safely
The PHP 8.5.4 release candidate landed this week, bringing a handful of hard‑to‑ignore bug fixes across the core engine and popular extensions. This article walks through the most noticeable changes, shows a quick way to spin up the RC on a development box, and flags the quirks that can still bite you.
Why bother with an RC at all
Even though the final 8.5 release is still weeks away, many projects run nightly builds or depend on edge‑case behavior that only surfaces in a release candidate. The recent core patches address memory‑heap corruption on Aarch64 LTO builds, a segfault when preloading constant AST closures, and a crash triggered by an (unset) cast in a constant expression. Those aren’t just theoretical – a colleague who runs CI on ARM servers reported intermittent test failures that vanished after the RC was applied.
Core fixes you’ll actually notice
The most visible change is the elimination of “insufficient shared memory” errors when JIT is enabled on Solaris; this used to abort scripts that allocated even modest opcode caches. The engine also stopped throwing deprecation warnings when accessing a null array key under JIT, which cleans up noisy logs in production‑like environments. Another subtle improvement fixes an assertion failure deep inside the lazy object handling path – if you’ve been debugging strange isset() behavior on Reflection LazyProxy objects, the RC should stop those mysterious crashes.
Extension updates that matter
Curl now respects the full length of transferred data instead of silently truncating it, a bug that showed up when streaming large JSON payloads. The Date extension finally handles null start values in DatePeriod::__set_state(), preventing fatal errors in unserialized period objects. DOM node properties such as baseURI no longer throw TypeError exceptions on edge cases, which smooths out HTML parsing scripts that walk the tree without checking each property first. LDAP’s ldap_modify() validation has been relaxed, allowing attributes to be unset – a change many legacy authentication scripts have been waiting for. MBString’s mb_guess_encoding() no longer explodes when fed an enormous list of candidate encodings; this saves memory on batch‑processing pipelines that dynamically generate those lists.
Getting the RC onto your machine
The simplest route is to pull the tarball from php.net’s “release candidates” page, extract it into a dedicated folder, and configure it with a prefix that points to a sandbox directory. After extraction, run the ./configure script with the same flags you use for your stable build – for example, include --enable-jit --with-openssl if those features are part of your workflow. The configure step checks for missing headers; on Windows the recent fix adds the required intrin.h include when compiling with clang, so you won’t hit that compile‑time error anymore. Once configured, invoke make -j$(nproc) to compile in parallel, then run make install. Because the RC lives outside your system PHP path, you can point your IDE or test runner at the new binary without overwriting the production interpreter.
Pitfalls and things to keep an eye on
Even with all these patches, the RC is still a work‑in‑progress. The fuzzing harness uncovered a leak in the OpenSSL integration that only appears under heavy TLS traffic; if your test suite includes long‑running HTTPS connections, watch memory usage closely. Also note that the build system now installs libtool wrappers when using slibtool – a regression that can clutter your PATH if you rely on custom wrapper scripts. Finally, because the RC’s JIT implementation is still being fine‑tuned, some edge‑case optimizations may produce different floating‑point results compared to the stable branch; a quick numeric sanity check after enabling JIT is advisable.
Give the PHP 8.5.4 release candidate a spin on a non‑critical environment, and you’ll see why these fixes matter before they make it into the final release.
Release php-8.5.4RC1
Tag for php-8.5.4RC1
