what's new in PHP 8.4
Austin Drupal Meetup April 2025
Ian Littman
Released November 21, 2024
- Thanks to release managers Eric Mann, Calvin Buckley, and Saki Takamachi
- Current version: 8.4.6 (as of April 10)
- Bugfixes until Dec 31, 2026
- Security fixes until Dec 31, 2028
- Security fixes after that if provided by your distro (or Zend)
What we'll cover
- Where to get it
- What's new
- What's deprecated/removed/BC-broken
Blue-highlighted items are links if you want more info (ian.im/php84adm)
Info drawn from the release page + php.watch + UPGRADING and NEWS files
How do I get it?
- macOS
-
brew tap shivammathur/php
-
brew install php@8.4
-
- Red Hat-based: use Remi's repo
- Debian-based: use ondrej's PPA
- Inside Docker: e.g. php:8.4.6-fpm-alpine3.20
- Source code to build yourself is on php.net
New Features + Improvements
class User
{
private bool $isModified = false;
public function __construct(private string $first, private string $last){}
public string $fullName {
// Override the "read" action with arbitrary logic.
get => $this->first . " " . $this->last;
// Override the "write" action with arbitrary logic.
set (string $value) {
[$this->first, $this->last] = explode(' ', $value, 2);
$this->isModified = true;
}
}
}
class User { public private(set) string $firstName; public private(set) string $lastName; public function setName(string $first, string $last) { $this->firstName = $first; $this->lastName = $last; } } $u = new User(); $u->setName('John', 'Smith'); echo $u->firstName . ' ' . $u->lastName . "\n"; // succeeds $u->firstName = 'Jane'; // fails
Ghosts 👻💤 'n' proxies 'n' stuff
- array_find - first value in array for which callback returns true
- array_find_key - first key in array for which callback returns true
- array_all - whether callback returns true for all items
- array_any - whether callback returns true for at least one item
- Polyfill via polyfills/array-find
Date improvements
- ->getMicrosecond()/setMicrosecond()
- ::createFromTimestamp()
- Available on DateTime/DateTimeImmutable
- NOT in DateTimeInterface
Security
- Sodium supports AEGIS-128L/AEGIS256
- tempnam() filenames are now 13 bytes longer
- bcrypt default cost is now 12, up from 10
- OpenSSL Curve25519/Curve448 support (including ed25519)
NumberS!
- Rounding
- bcceil, bcfloor, bcround
- New rounding modes in round() and Intl NumberFormatter::round()
- Slightly better max precision (by one digit)
- BCMath is now faster, and has an OO interface
- fpow() method for IEEE 754 compliant raising-to-a-power
String manipulation
Other additions
- new Foo->bar() now works (previously needed to be (new Foo)->bar())
- #[\Deprecated] attribute + ReflectionClassConstant::isDeprecated()
- http_(get|clear)_last_response_headers (for e.g. file_get_contents via HTTP)
- feature_list array key in curl_version() response
- request_parse_body() (returns [$looks_like_POST, $looks_like_FILES])
- PHP integer size in phpinfo
- More info in Closure::__debugInfo() (and names tweaked for better visibility)
- PDO driver-specific SQL parsers and driver-specific subclasses
- Various Postgres client improvements (in the PGSQL extension)
- ReflectionGenerator::isClosed() and ReflectionProperty::isDynamic()
- SplObjectStorage::seek(): SeekableIterator
- XMLReader/Writer operation on streams
- Various performance improvements
Exceptions/input validation
- dom
- Intl
- mb_*
- pcntl
- SimpleXML
- SplFixedArray out of bounds
- XMLReader/XMLWriter
- XSL
- round() on invalid mode
- xml_set_*_handler()
Resources -> Types
- BCMath numbers (mentioned earlier)
- ODBC connections and results
- SoapClient Url, Sdl (and typemap is now an array)
- Bonus: Clark Notation support
- StreamBucket
- More typed constants
- Date
- Intl
- PDO
- Spl
- Sqlite
- XMLReader
- PHP_DEBUG, PHP_ZTS (now bools)
- New JIT that compiles to an intermediate representation
- JIT is enabled based on a flag rather than buffer size
- PHP will now exit if JIT is enabled and fails to init
- Opcache interned string buffer default is 8x larger
JIT/Opcache
- Core -> PECL
- PHP built-in web server recursively falls back to index.php more aggressively
- PCRE is now updated (changes behavior)
- SimpleXML now doesn't reset the iterator in a few cases
- strcspn() now doesn't bug out when it sees a null byte
- Newer openssl, curl requirements
- GMP class is now final
- A bunch of MYSQLI_* constants have been removed
- exit() and die() behave more like functions now
Other BC Breaks
- Implicitly nullable parameter declarations aka (string $foo = null)
- session_set_save_handler() with callables rather than SessionHandlerInterface
- CURLOPT_BINARYTRANSFER (was a no-op anyway)
- Passing PHP session ID via URL parameter rather than cookie (and URL rewriting to include session IDs)
- DatePeriod::__construct() (use DatePeriod::createFromISO8601String())
- ldap_connect() with more than 2 arguments, ldap_exop() with more than 4
- Escaped question marks in PDO_PGSQL inside dollar-quoted strings
- Various PgSQL methods with omitted row arg (pass null instaed)
- ReflectionMethod::__construct() with one argument
- stream_context_set_option() with two arguments
- _ as a class name
- Raising 0 to a negative power
- Various mysqli methods
- E_STRICT (no longer used in the engine)
Deprecations
Thanks! Questions?
- This talk: ian.im/php84adm
- GitHub: github.com/iansltx
- Fediverse: phpc.social/@ian
- Bluesky: @ian.im
- Twitter: @iansltx
What's New in PHP 8.4 - Austin Drupal Meetup April 2025
By Ian Littman
What's New in PHP 8.4 - Austin Drupal Meetup April 2025
- 27