decorative image for blog on php 8
November 12, 2020

PHP 8: New Features and Improvements

State of PHP
PHP Development

PHP 8 released on November 26, 2020, and reached end of life in November, 2023. However, many applications still utilize PHP 8, and it is important for teams to be aware of the available features and performance improvements compared to PHP 7.X and earlier.

In this blog, we look at some of the notable new PHP 8 features and improvements, including the JIT compiler and the syntactical improvements that developers are sure to love.

Note: This blog was updated May, 2024 to include information regarding ongoing PHP 8 features and developments.

Back to top

PHP 8 Overview

PHP 8 Release Date

PHP 8.0 was released on November 26, 2020.

As noted above, PHP 8 introduced a number of new features, functions, improvements, and deprecations to the language. The most talked about feature, of course, is the JIT compiler. While performance-improving features like JIT deserve the limelight, the syntactical improvements may have more of a true impact for PHP practitioners—at least in the short term.

On-Demand Webinar: What's New in PHP 8?

Listen in on this on-demand webinar discussing PHP 8’s new features, functions, and improvements. I take a look at all the features listed in this blog and go in-depth on many of the functions mentioned here today.

Back to top

New Functions in PHP 8

PHP 8 introduces a handful of new functions, including:

  • str_contains
  • str_starts_with and str_ends_with
  • preg_last_error_msg
  • get_debug_type

For the purposes of this article, we’ll be focusing on the str_contains() function.

str_contains

There are a number of ways to find out if one string contains another. Generally, you’ll use strpos(). strpos() takes a haystack and the needle that you want to look for, and returns an integer indicating the first position at which the needle is found. Because it’s returning the position of one string in another, you can’t simply check for whether or not strpos() found it; if it returns zero (positions are zero-indexed and start with 0 instead of 1), then the conditional will treat it as a false value, indicating it wasn’t found.

This means you need to write the conditional as “strpos($haystack, $needle) !== false”, because false indicates that it could not find the position of the string. This is an esoteric, non-transparent way to look for a string in a string!

if (strpos('Foo Bar Baz', 'Foo') !== false) {
	     // FOUND
	}

To avoid this, PHP 8 introduces str_contains().  str_contains() returns a simple boolean indicating whether or not the needle is in the haystack, which is a lot easier to write, and, more importantly, understand as someone maintaining the code.

if (str_contains('Foo Bar Baz', 'Foo')) {
     	     // FOUND
	}
Back to top

Engine Features and Changes in PHP 8

There are quite a few new engine features and changes in PHP 8. The headlining feature, of course, is the new JIT compiler.

  • JIT Compiler
  • Fatal errors on incompatible method signatures
  • LSP Enforcement
  • Resource "Classes“
  • Assertion behavior
  • XML-RPC is now in PECL
  • Reflection changes

For the purposes of this blog, I’ll be focusing on the JIT compiler (stay tuned for a deeper dive on JIT in PHP 8), resource “classes,” and reflection API changes.

JIT Compiler

The JIT compiler in PHP 8 is certainly the most talked about feature. While it is interesting, and does warrant a lot of the spotlight, the actual impact that the JIT compiler will have on PHP as a language is to be determined.

On-Demand Webinar: Exploring JIT in PHP 8

Join me as I discuss the level of benefit (and complexity) developers can expect in real-world PHP applications using JIT compilation, including how the JIT compiler works, how it will impact PHP application performance, and much more.

Resource “Classes”

Resource “classes” are another big change in PHP 8. They serve as non-instantiable replacements for specific resource types. The available replacements include:

  • CurlHandle — curl_init() now returns CurlHandle, describing a curl resource.
  • GdImage — GdImage represents a GD resource, as returned by the various imagecreatefrom*() functions.
  • Socket / AddressInfo — Provided by the sockets extension; a number of the socket_*() functions return a Socket, and the socket_address_info_lookup() function returns an AddressInfo instance.

It’s also important to note that resources are no longer destroyed by functions like curl_close(). Instead, you have to unset() the instance in order to de-reference it because it's now a class instance.

What you gain is the ability to specify these classes as typehints in your methods and functions. Previously, you had to leave resource arguments or return values untyped, and document them via annotations; now you can have explicit types, making your code more readable, and more type-safe.

The trade-off is that you will now need to update your code to destroy resources using unset() instead of the previous functions used to destroy resources. This can generally be accomplished via search and replace.

Reflection API Changes

Another small, but important new PHP 8 feature is the change to the Relection API. When you’re using the attribute system (more on this later), you can now retrieve those attributes via the Reflection API on any other reflection classes. With the addition of union and mixed types, the ReflectionParameter methods getClass(), isArray() and isCallable() are now deprecated. This is because it’s much better to use getType(), which will give you the complete list of types that particular parameter satisfies.

Back to top

PHP 8 Syntax Improvements

While JIT may be stealing the headlines, the syntactical improvements in PHP 8 offer big quality of life benefits for PHP developers. Whether that is in eliminating common boilerplate between the promoted constructor arguments, or the improved error and exception handling, there’s a lot for developers to be excited about.

  • Union Types
  • "mixed" pseudo type
  • Class Constructor property promotion
  • ::class ubiquity
  • Attributes
  • Match Expressions
  • Catch by type only
  • Throwing exceptions from expressions

For the purposes of this blog, we’ll be focusing on union types, match expressions, and attributes.

Union Types

Union types indicate that a value is one of two or more specified types. This is done with a vertical bar between each allowed type. For many developers who have been doing PHP annotations to specify your parameters or return values, you have probably been doing this already.

For those returning a lot of different types, or if you’re accepting a lot of different types, union types can make the code more complex and harder to understand. Still, there are a number of times where this will be very useful. For example, if you can accept a string, or an object implementing the new Stringable interface (“string|Stringable”), or if you can accept either an array, or an object implementing the Traversable interface (“array|Traversable”).

Match Expressions

Match expressions eliminate the guesswork associated with determining whether failure to break within a switch case is intentional or not, and simplify the common pattern of assigning a value based on a match.

When used, the value you pass to match() is going to be compared directly to whatever the expression is on the left-hand side. Whether that’s a value or an expression, the value you pass to match() must match it for it to be selected. When matched, the expression on the right is evaluated, and its return value returned; expressions can only be callables or a lambda functions, and no multi-line closures are allowed. 

Attributes

PHP 8 also integrates attributes at the language level. While attributes have been around for over 15 years via docblock annotations, having them built into the language provides better performance and more power, as well as more consistency (as annotation libraries have often supported different syntax varieties). We’ll likely see attributes being used widely in the development of rapid application development tooling.

Back to top

Ongoing Improvements in PHP 8 Versions

PHP has been improving and adapting since its initial conception in 1994. Each iteration works to improve performance, security, and usability for developers and end-users. While PHP 8 built a strong foundation, subsequent 8.X versions—including the upcoming PHP 8.4, slated to release in November 2024—have continued to evolve. Take a look below for a timeline of PHP 8 iterations and improved features.

Explore All PHP Versions

PHP 8.1

PHP 8.1 was released on November 25, 2021. This update improved upon PHP 8.0’s already impressive offerings, adding key features and functions such as:

  • Enumerations
  • Fibers functionality
  • Readonly properties
  • Additional intersection types
  • Never return types

Learn More About PHP 8.1 >>

PHP 8.2

PHP 8.2 was released on December 8, 2022. It introduced several new features and improvements for PHP applications, with notable changes including:

  • Improved readonly classes
  • New random number generator
  • DNF types
  • Sensitive parameter value redaction

Learn More About PHP 8.2 >>

PHP 8.3

PHP 8.3 was released on November 23, 2023. While it did bring several notable updates to previous versions, it contains relatively fewer new features compared to the releases of PHP 8.1 or PHP 8.2. PHP 8.3 offers:

  • Typed class constants
  • Dynamic class constant and Enum member fetch support
  • json_validate () function
  • mb_str_pad () addition
  • #[\Override] attribute
  • And other random extension additions

Learn More About PHP 8.3 >>

Back to top

Final Thoughts

On the whole, the new PHP 8 features and functions offer some big improvements. The syntactical improvements simplify a lot of common boilerplate, and the expansions to the type systems are wonderful.

JIT is an intriguing addition to the language, but we likely won’t start seeing the benefits until developers start writing libraries and applications that can truly take advantage of it.

Get Guidance and Support for Your Next Migration

If you’re considering migrating a large-scale application to PHP 8, our team can help answer questions you have and even provide support and assistance as you complete your migration. Click the button below to learn more.

See Migration Services

Additional Resources

Back to top