What is new in PHP 8: All you need to know!

We’ll get in touch with PHP8 on November 26th, 2020, and certainly, there are lots of being written regarding the upcoming features in this appreciated release.


As it’s a major version, there will be breaking changes and new features well as making it important to be aware of what all is changing. It’s gonna make it convenient to think regarding how PHP8 will affect your apps and what actions will be needed to be taken to ensure you can upgrade conveniently without incident.

We went through a few of the most considerable changes to figure out what we’re going to get in the next PHP release and what’s worth criticizing.

let’s begin with the overview!

PHP 8 Overview

As mentioned above, PHP 8 introduces a pack of new features, improvements, functions, and deprecations to the language. Among all these, the most discussed feature is the JIT compiler. However, performance-improving features such as JIT deserve the limelight, but the syntactical improvements are expected to have more of a true smash for PHP practitioners, we’d say, “at least in the short term.”

A history of change

A few PHP changes are proposed, debated, implemented, and further approved in short order. They’re popular, uncontroversial, and have a natural method to implement them.

And after that come the ones that are tried, fail, and return multiple times before we accept them finally. A few times, the implementation consumes a long time to sort out, and sometimes the idea itself is just half-baked, and sometimes the community itself hasn’t warmed up to the idea yet—”it’s not yet time.”

Credits fall squarely into the type category. They were first proposed in the year 2016 for PHP 7.1. However, they met with stubborn resistance and lost the acceptance vote by a heavy margin. Now, fast forward four years, and a pretty similar if slightly reduced-scope proposal floated through with just one dissenter. It’s evidently an idea whose time has certainly come!

What are the issues with the old code?

AS PHP 8 is a huge new release, we should expect old code to no further be compatible. However, the majority of the changes that could propose complications were already conveyed in versions 7.27.3, and 7.4. Let’s talk about the last changes now. They’re:

Magic quotes legacy

  • The real type
  • Unbinding $this from non-static closures
  • array_key_exists() with objects
  • mb_strrpos() with encoding as 3rd argument
  • Reflection export() methods
  • convert_cyr_string() function
  • implode() parameter order mix
  • restore_include_path() function
  • hebrevc() function
  • money_format() function
  • allow_url_include ini directive
  • ezmlm_hash() function

New Functions in PHP 8


If one string contains another, then there are numerous ways to find out.

Generally, you’ll use strpos(). As you know, strpos() takes a haystack beside the needle that you desire to look for. It returns an integer showing the first position at which you see the needle.

Now, as it’s returning the position of a string in another, you simply can’t check for whether or not strpos() discovered it; if it returns “0” (positions are zero-indexed and begin with 0 rather than 1), then the conditional is going to treat it as a false value, and indicating it wasn’t found.

What does that mean?

You’ll have to write conditional –“strpos($haystack, $needle) !== false.” False indicates that it couldn’t find the string’s position. This is a non-transparent and esoteric method to search a string in a string! Well, not that confusing.

To avoid this, PHP 8 brings str_contains().  The job of str_contains() is to return a simple boolean showing whether or not the needle is present in the haystack. That’s much  easier to write, besides that, understand as someone maintaining the code, isn’t it?

if (str_contains('Foo Bar Baz', 'Foo')) {
             // FOUND

PHP 8: Engine Features & Changes

There are some new engine features, and changes noticed in PHP 8. The headlining feature, undoubtedly, is the new JIT compiler.

JIT Compiler

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

For the sake of the core purpose of this blog, we’ll focus on the JIT compiler, resource “classes,” and finally, reflection API changes.

Just-In-Time Compiler (RFC)

Due to speed improvements made before PHP7’s release, the birth of the Just-In-Time (or JIT) compiler took place. It’s being introduced to PHP8 because there are almost no more improvements in speed that can be brought without using a JIT. The idea is that it will improve PHP performance.

PHP code is translated into bytecodes when it is executed, and those bytecodes are further utilized to execute the steps in the program.

PHP will analyze the code you executed, that’s what a JIT means. Further, it can make real-time decisions other than performance improvements on the code as you execute it. It’s going to be highly usable in CPU intensive applications and not just while used in web-based scenarios.

That reflects server-side PHP applications certainly can be more prevalent with the PHP inbuilt JIT system.

You first need to activate JIT if you want to use it. On our test system (Ubuntu 20.04), we already have installed the PHP opcache module, which we installed with the core PHP8 package. We have configured in the file placed at /etc/php/8.0/cli/conf.d/10-opcache.ini.

Now, you’re all set to activate JIT, right? 

  • Enable the opcache

You can assign memory storage to the opcache.jit_buffer_size setting. Your file will appear like this on my system.

  1. zend_extension=opcache.so
  2. opcache.enable_cli=1
  3. ; configuration for php opcache module
  4. opcache.jit_buffer_size=256M

Furthermore use the opcache_get_status() function to ensure whether its active.  Roll your gaze over the ‘jit’ part of this array and get info regarding JIT’s current status.


If JIT has been activated perfectly, this should print out as shown down there.

  1. array(7) {
  2. [“enabled”]=>
  3. bool(true)
  4. [“on”]=>
  5. bool(true)
  6. [“kind”]=>
  7. int(5)
  8. [“opt_level”]=>
  9. int(4)
  10. [“opt_flags”]=>
  11. int(6)
  12. [“buffer_size”]=>
  13. int(268435440)
  14. [“buffer_free”]=>
  15. int(268432880)
  16. }

So was it faster? In a word, we’d exclaim a warm “yes.”

We’ve noticed a few folks doing benchmarks with the help of a mandelbrot set, so we decided to use a library that we created a while ago that draws some different sorts of fractals in PHP. All we did was generate three fractals and tracked how long it took utilizing the microtome() function. We’ve displayed the results for PHP 7.4.8 below.

  • Burningship – 84.20269203186
  • Mandlebrot – 21.552599906921
  • Tricorn – 32.685042858124

When we ran the very same code on PHP8, it was pretty faster. The numbers will speak for themselves..

  • Burningship – 15.272277116776
  • Mandlebrot -3.7528541088104
  • Tricorn -4.4957919120789

This huge speed increase is pretty interesting. The code we used here creates huge-sized fractals, but we remember when creating the code that most of our time was spent waiting for the generation of fractals.

This addition is interesting to us as we have pushed PHP to its boundaries on some occasions (outside of generating fractals). We can notice this being of great benefit to PHP’s future and is going to allow the language to be chosen for situations outside of the regular website language.

We haven’t look at the speed increment for apps like WordPress or Drupal, but from what we had read, there is certainly little difference in those sorts of applications. In the future, we’ll be running benchmarks on these platforms to figure out what sort of a difference the JIT marks there.

Union Types (RFC)

Since PHP7, stipulating what kind of return values and types of arguments and have been possible. This will permit PHP to throw an error in case the type of argument you’re passing is a nonidentical sort to the expected type. It’s crucial to ensure that functions receive as well as produce the perfect types of value in a loosely typed language such as PHP.

In PHP8, it’s now possible to stipulate various sorts for the arguments and return values, split by a pipe character.

We’ve shown below a function that’s capable of accepting either a float or an integer value.

function addNumbers(int|float $number1, int|float $number2) : int|float
return $number1 + $number2;

Formerly, a function identical to this would require to be generated without any type hinting because PHP could silently showcase the type in case the passed argument wasn’t correct. It meant that in case we set the type of argument as an integer, PHP would showcase any float values into an integer. It can certainly lead to a few tricky bugs to catch in case you aren’t unit testing.

We just call it like any other to use the above function

echo addNumbers(1, 1); // prints 2
echo addNumbers(1.1, 1.1); // prints 2.2

In case we try to pass a string to the identical function:

echo addNumbers('one', 'two');

We’ll receive a PHP Fatal error exclaiming that we need to pass either a float or an “int” into the function.

You can’t use the void type as a union type because it stipulates that the function is going to return nothing. In simple words, you can’t exclaim that a function is going to return a void or an integer; you’ll receive a PHP fatal error.

Whilst a normal change we can see was this feature being used a bit as it has earlier only been possible to stipulate various types of value in comments, which resulted in doc block comments becoming more detailed than code.

The Nullsafe Operator (RFC)

Besides the null coalescing operator, the ability to detect null return values is possible directly from methods. If you weren’t aware, the null coalescing operator lets you get a value, and you don’t have to test in case the value is present besides returning a different value in case the first value is null.

So, we can do this to grab a value from – “$_GET superglobal.” and in case that value isn’t present, then “0.”

1. $page = $_GET['page'] ?? 0;

2.   echo $page;

The working of the null safe operator is the same but allows you to create a handy shortcut and test for a null return from a way before trying to use that value.

We noticed  that this is going to be ultimately useful in Drupal, where we tend to write much of checking code to ensure that “returns from methods” or “object properties” have things in them before utilizing them. This is compulsory because of the contextual state of the objects in Drupal because of the content they contain. This change will surely simplify some of the checks.

Named Arguments (RFC)

Named arguments permit you to stipulate a different order of arguments and call functions. Take the following normal function that has two parameters. It fills an array to the given length.

function fillArray(array $arrayToFill, int $number) : array

for ($i = 0 $i < $number; ++$i) {
$arrayToFill[$i] =1;
return $arrayToFill;

We can pass the the arguments in the arrangement they are defined can call this technique in the normal way.

$newArray = fillArray([], 2);

As of PHP8 you can now name the parameters as you pass them to the function. It also allows you to send the parameters in whatever order we want.

$newArray = fillArray(number: 2, arrayToFill: []);

A normal example, but it can make the code more readable as well.

This technique works with all functions in PHP, not just user-defined ones. In PHP language, array and string functions have nonidentical orders of parameters. So, it’s a truly welcome addition.

Attributes V2 (RFC1RFC2RFC3)

Attributes furnish a mechanism to adjoin metadata to PHP classes, functions, class properties, function parameters, and constants. They can’t be directly accessible through code, and you need to pull them out with the help of PHP built in reflection classes.

The ReflectionClass class has been in PHP since PHP5; however, getAttribute() method is new for PHP8. This method returns a range of ReflectionAttribute objects that are going to embrace information about attributes.

This addition faced a few changes (as we can notice from the multiple RFCs above). In case you instantiate the class, you can then use the ReflectionClass and print out the attribute info contained on a class level. There’s quite much to attributes in PHP8, so we’d recommend reading through the RFCs and get familiar with what they actually are and how you can integrate them into your code.

Match expression (RFC)

In PHP 8, we can compare the new match expression to a shorthand switch statement.

It appears a bit like a function declaration that’s going to return a value on the basis of the value passed in.

The switch statement in PHP is amazing when you desire to check condition on the identical expression without including multipleif statements altogether.

Here we bring a basic if-else comparison on an identical expression.


if ($i == 'apple') {

    echo 'i is apple';

} elseif ($i == 'cake') {
    echo 'i is cake';
} else {

    echo 'i is pizza';


And this is how the equivalent switch statement of our previous example would appear like


switch ($i) {

case 'apple':
     echo 'i is apple';

case 'cake':
      echo 'i is cake';


       echo 'i is pizza';

Resource “Classes”

Resource “classes” come in the list of major changes in PHP 8 and serve as non-instantiable replacements for given resource types. See below to know the available replacements include:

  • CurlHandle — curl_init() now returns CurlHandle, relating a curl resource.
  • Socket / AddressInfo — Given by the sockets extension; the quantity of the socket_*() functions return a Socket, while the socket_address_info_lookup() function returns an AddressInfo instance.
  • GdImage — It represents a GD resource, as restored by the numerous imagecreatefrom*() functions.

Also, it’s crucial to note that resources aren’t destroyed by functions such as curl_close(). Rather, you have to unset() the instance to de-reference it as it’s now a class instance.
You gain the ability to specify the classes as typehints in your functions and methods.
Earlier, we had to return values untyped or leave resource arguments and document them through annotations, but now, you can have explicit types, and that not just makes your code more readable but more type-safe as well.
What’s the trade-off here?
You’ll now need to update your code if you want to destroy resources with the help of unset() in place of the previous functions used to demolish resources. This can normally be accomplished through search and replace.

Reflection API Changes

Another little one, but a vital change in PHP 8 is related to Reflection API. While using the attribute system, you can conveniently retrieve those attributes through the Reflection API on whatever reflection classes.
With the addition of mixed and union types, the ReflectionParameter techniques getClass(), isCallable(), and isArray() are now deprecated.
The scenario is so because using getType(), is much better, and you get the complete list of types that a specific parameter satisfies.

PHP 8 Syntax Improvements

As we are noticing, JIT is stealing the headlines; the PHP 8 syntactical improvements provide huge quality of life advantages for PHP developers.
No matter that’s in eliminating common boilerplate among the promoted constructor arguments or the improved exception and error handling, there’s much for developers to feel excited about.

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

For maintaining purposes of this blog, we’re focusing on union types, attributes, and match expressions.

Union Types

Union types show that a value is one among two or more specified sorts. It’s done with a vertical bar placed between every single allowed type. For several developers who are deep into PHP annotations to return values or specify your parameters, you have been doing this already, most probably.
Union types can bring much complexity and difficulty in understanding for those accepting a lot of different types or returning a lot of different types.
Still, this will be very useful on several occasions. For instance, in case you can accept or an object implementing the new Stringable interface (“string|Stringable”), or a string, or if you can accept either an object implementing the Traversable interface (“array|Traversable”) or an array.

Match Expressions

Match expressions cut-off the guesswork related to figure out whether failure to break within a given switch case is intentional or not. It also simplifies the normal pattern of assigning a value on the basis of a match.
When used, the value we pass to match() will be directly compared to whatever the expression is there on the left-hand side. No matter that’s an expression or a value, the value you pass to match() should match it for it to be chosen.
When matched, the expression present on the right is estimated, and its return value returned, while expressions can only be Lambda or callables functions, and no multi-line closures are permitted.


PHP 8 integrates attributes at the language level as well. While attributes are present for more than 15 years via docblock annotations, getting them built into the language offers better performance and certainly, more power and more consistency. We’ll likely see attributes being highly used in the development of tooling and rapid applications.


Certainly, there are some changes going into PHP8. Still, it looks like the majority of the deprecated code being eliminated is for older features that we haven’t seen being used in recent times.
We’re pretty interested to notice what impact the JIT engine is going to have on the codebases we use and also on the wider PHP community—saying that we highly recommend scanning your codebase for incompatibilities with PHP8 and running unit tests to ensure that your PHP applications function perfectly before saying “yes” to the upgrade.

(Visited 734 times, 1 visits today)

Leave a Reply

AlphaOmega Captcha Classica  –  Enter Security Code

This site uses Akismet to reduce spam. Learn how your comment data is processed.