BreadcrumbHomeResourcesBlog Exploring PHP 8: New Features and Improvements November 12, 2020 Exploring PHP 8: New Features and ImprovementsState of PHPPHP DevelopmentBy Matthew Weier O’PhinneyWith PHP 8 coming out in the next few weeks, it’s important for teams to be aware of the new features and performance improvements.In this blog, we look at some of these notable features and improvements in PHP 8, including the JIT compiler and the syntactical improvements that developers are sure to love.PHP 8 OverviewAs noted above, PHP 8 introduces 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.Release DateWhile initially planned for release on November 26th, 2020, PHP 8 will now reach general availability in late Q4, 2020.New Functions in PHP 8PHP 8 introduces a handful of new functions, including:str_containsstr_starts_with and str_ends_withpreg_last_error_msgget_debug_typeFor the purposes of this article, we’ll be focusing on the str_contains() function.str_containsThere 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 }Engine Features and Changes in PHP 8There are quite a few new engine features and changes in PHP 8. The headlining feature, of course, is the new JIT compiler.JIT CompilerFatal errors on incompatible method signaturesLSP EnforcementResource "Classes“Assertion behaviorXML-RPC is now in PECLReflection changesFor 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 CompilerThe 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.New Webinar: Exploring JIT in PHP 8If you want more information on the JIT compiler, be sure to check out my upcoming webinar on JIT compilation in PHP 8. I’ll be talking about the nuts and bolts of the compiler, as well as what it may mean for PHP development going forwardSee Webinar DetailsResource “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 ChangesAnother small, but important change in PHP 8 is the change to the Reflection 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.PHP 8 Syntax ImprovementsWhile 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 typeClass Constructor property promotion::class ubiquityAttributesMatch ExpressionsCatch by type onlyThrowing exceptions from expressionsFor the purposes of this blog, we’ll be focusing on union types, match expressions, and attributes.Union TypesUnion 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 ExpressionsMatch 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. AttributesPHP 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.Final ThoughtsOn the whole, PHP 8 offers 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 MigrationIf 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 ServicesAdditional ResourcesMuch of the content for this blog was pulled from my preparation for a recent webinar I did on PHP 8. The webinar looks at all of the features listed in this blog, and offers a closer look at some of the features I covered here today.Want to learn more about how PHP has evolved from version to version? Be sure to view the resources below.Blog – New Features in PHP 7.4Resource Collection – PHP Versions: Performance, Security, and Feature ComparisonsWhite Paper – Hidden Costs of PHP UpgradesCustomer Success Story - Sensational Brain
Matthew Weier O’Phinney Zend Product Manager, Zend by Perforce Matthew began developing on Zend Framework (ZF) before its first public release, and led the project for Zend from 2009 through 2019. He is a founding member of the PHP Framework Interop Group (PHP-FIG), which creates and promotes standards for the PHP ecosystem — and is serving his second elected term on the PHP-FIG Core Committee.