PHP 8.0 - What is new in the major update?

PHP 8.0 - What is new in the major update?

PHP (Hypertext Preprocessor) is a general-purpose server scripting language (embedded in HTML) suitable for web development. PHP originally was called Personal Home Page, but now has a recursive initialization Hypertext Preprocessor. PHP powers everything, from simple blogs to popular websites. It is fast and flexible, making it the best match to build interactive and dynamic web pages. It is a FREE, efficient, and widely used alternative to competitors like Microsoft’s ASP.

In 2015, the new PHP 7 version was developed, which had four more sub-upgrades till PHP 7.4. Overcoming the flaws and bringing many long-awaited features recently, PHP has released the eleventh testing release of PHP 8.0, including some great varieties of effective changes and lean language improvements. As PHP 8.0 is here, several changes can be seen in terms of performance, features, etc. The most discussed feature of PHP is PHP JIT (Just In Time Compiler). JIT is set to increase the speed of an application by the technique used to handle the compilation of the scripts.

The RFC (Publication called Request for Comments) proposal stated,

PHP JIT is implemented as an almost independent part of OPcache. It may be enabled/disabled at PHP compile-time and run-time. When enabled, the native code of PHP files is stored in an additional region of the OPcache shared memory and op_array→opcodes[].handler(s) keep pointers to the entry points of JIT-ed code.

The upgrade to PHP 8.0 shouldn't be that hard if you have kept your code up to date with the latest releases as most changes were deprecated before in the PHP 7.* versions. The new PHP 8.0 also brings in some more exciting features such as Named Arguments, Attributes, Constructor property promotion, Union Types, Match expression, Just-In-Time compilation and more.

Challenges faced by older code

As PHP 8.0 is a significant release, compatibility of the old code will no longer be expected. Also, most of the changes that could lead to any complications have already been highlighted in previous versions 7.3 & 7.4.

Migrating to PHP won't be a problem if you have kept your code up to date with all the versions. In their recent announcement, Microsoft stated that they would no longer offer support for PHP 8.0 and later versions.

Improved and new features of PHP 8.0

New features of PHP is a major version update and a milestone in the field of PHP. It is a combined effort of hundreds of people to shape the future of a programming language that is the significant power of internet web sites and applications.

PHP tries to be conservative with changes that can break a majority of the applications, and yet, it brings several new major features to PHP 8.0.

Features such as Just in Time Compiler (JIT), Named Arguments, Attributes, Union Types, Weak Maps, and Constructor properties bringing some major improvements and syntax changes. Some minor changes also include improved error handling, changes & improvements in operators, and engine comparisons that help effectively reduce the chances of overlooked bugs.

Named Arguments

Until the last PHP 7.* versions, PHP used only positional parameters. As per the name, Named argument, which is also called as Named Parameter, allows you to pass input data into a function based on their argument name instead of argument order. The argument of the first position is assigned to the parameter in the first position. Default value is filled in the argument that is missing.

Arguably, Named parameters are a great feature that will have a significant impact on day-to-day programming life. Lastly, Named arguments can be combined with unnamed (ordered arguments). But for that, the ordered arguments must always come first.

Instead of doing this:

htmlspecialchars($string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);

You can now do this:

htmlspecialchars($string, double_encode: false);

Union Types

A union type accepts values of multiple different types, rather than a single one. And the dynamically typed nature of PHP, Union types can be useful in lots of cases. Union types are a collection of two or more types that indicate that either one can be used.

Instead of doing this:

class Number {
  /** @var int|float */
  private $number;

  /**
   * @param float|int $number
   */
  public function __construct($number) {
    $this->number = $number;
  }
}

new Number('NaN'); // Ok

You can now do this:

class Number {
  public function __construct(
    private int|float $number
  ) {}
}

new Number('NaN'); // TypeError

Supporting Union types in the language allows more type information to move phpdoc into function signatures. Usually, Types are enforced, so mistakes can be caught earlier. Union types support all available types except:

  • void type, as void, means that a function does not return any value.
  • null type, its usage as a standalone type is not allowed.
  • The nullable type notation ?T is not allowed to include in union types.

Attributes

Also known as Annotations, Attributes are used to add metadata to classes, methods, variables, etc., in a structured way. The concept of Attributes isn't new to us; everyone is using docblocks to stimulate their behavior for years now.

Until PHP 7.4, the only way to add metadata to declarations classes, functions, etc., was doc-comments, also known as docblocks. Instead of manually parsing docblocks, attributes are now the first-class citizen in the language to represent this kind of metadata.

Instead of doing this:

class PostsController
{
    /**
     * @Route("/api/posts/{id}", methods={"GET"})
     */
    public function get($id) { /* ... */ }
}

You can now do this:

class PostsController
{
    #[Route("/api/posts/{id}", methods: ["GET"])]
    public function get($id) { /* ... */ }
}

Constructor Property Promotion

It is a syntax that allows class property declaration and constructor assignments right from the constructor. It adds syntactic sweetness to create value objects or data transfer objects. In other words, Property promotion allows us to combine variable assignments, class fields, and constructor definition all into one syntax in the construct parameter list.

Instead of differently specifying class properties and a constructor, PHP can combine them into one. The idea is fundamental and simple, avoid all the variable assignments and class properties, and prefix; public, protected, or private to all the constructor parameters. PHP will take that new syntax and convert it to normal syntax under the hood, just before executing the code.

Instead of doing this:

class Point {
  public float $x;
  public float $y;
  public float $z;

  public function __construct(
    float $x = 0.0,
    float $y = 0.0,
    float $z = 0.0,
  ) {
    $this->x = $x;
    $this->y = $y;
    $this->z = $z;
  }
}

You can now do this:

class Point {
  public function __construct(
    public float $x = 0.0,
    public float $y = 0.0,
    public float $z = 0.0,
  ) {}
}

Weak Maps

Weak Maps were already added in PHP 7.4. Weak maps and WeakRefs can be used to delete objects when only the cache refers to objects' entity classes. Weak maps reference those objects, which doesn’t prevent those objects from being garbage collected. This leads to resource-saving handling of the objects.

In other words, Weak map is a collection of objects in which keys are weakly referenced. Now, the Weak Map introduces a class to create objects to be used as keys, which can be destroyed & removed from the Weak map if there are no further references. In long-run processes, this can prevent memory leaks, which eventually improve performance.

An Example of Weak maps from RFC:

class Foo 
{
    private WeakMap $cache;

    public function getSomethingWithCaching(object $obj): object
    {
        return $this->cache[$obj] ??= $this->computeSomethingExpensive($obj);
    }
}

Non-capturing catches

Whenever you wanted to catch an exception before PHP, you had to store it in a variable, regardless whether you used that variable or not.
With non-capturing catches, you can omit the variable, so instead of this:

try {
    // Something goes wrong
} catch (\Exception $e) {
    Log::error('Something went wrong.');
}

You can now do this:

try {
    // Something goes wrong
} catch (\Exception) {
    Log::error('Something went wrong.');
}

JIT (JUST IN TIME COMPILER)

Everyone probably knows that PHP is an interpreted language. It’s not compiled like C, Java, or another program. Instead of that, it is translated to machine code, things that the CPU understands at run-time.

So, JIT is a technique that will help compile parts of the code at run-time so that the version which is compiled can be used instead. PHP Opcache supports JIT; though it's disabled by default if enabled, JIT compiles and caches native instructions. It provides a massive boost in performance in CPU-heavy web applications. JIT acts very much like a cached version of the code. Which eventually leads to some significant improvements in the performance.

PHP Version Time in Seconds
5.3 0.64574003219604
7.4 0.10253500938416
8 (without JIT) 0.098223924636841
8 (with JIT) 0.053637981414795

As seen in the table, PHP without JIT doesn't make a noticeable difference in the performance. But, when it comes to PHP with JIT, the performance is improved by more than 45%.

New PHP Functions

str_contains

Finally, we don't have to rely on strops() anymore to know if a string contains another string.

Instead of this:

if (strpos('string with lots of words', 'words') !== false) { /* … */ }

Now you can do this:

if (str_contains('string with lots of words', 'words')) { /* … */ }

str_starts_with() and str_ends_with()

These two functions are now added into the core. They check if a given string starts or ends with another string.

str_starts_with('haystack', 'hay'); // true
str_ends_with('haystack', 'stack'); // true

get_debug_type()

This function get_debug_type() returns the mixed type of the variable. It returns more useful results for arrays, anonymous classes, objects, and strings. It works similarly to the gettype() function. But get_debug_type() returns native class name. This is one significant improvement for the language as gettype() is not useful for type system checking.

Consistent Type Errors

Fatal Error will be thrown for user-defined functions in PHP, but internal function won't; they would rather emit warnings and returned null.
But in PHP, the behavior of the internal function has been made consistent.

Removed each() Method

This method retrieves the next key and item from next from an array and advances the pointer on by one. To move the pointer to the next item in the array, it was a convenient way at the same time as getting a value out of the array. This has been removed now, and ArrayIterator or foreach should be used instead.

Reclassified Engine Warnings

The triggered warnings or notices of the errors have now been converted to proper errors. These are some warnings that were changed:

  • Undefined array index: warning instead of a notice.
  • Undefined variable: Error exception instead of a notice.
  • Division by Zero: Error exception instead of a warning.
  • Attempt to decrement or increment property '%s' of non-object: Error exception instead of a warning.
  • If the next element is already occupied, the element cannot be added to the array: Error exception instead of a warning.
  • Illegal offset type: Error instead of a warning.
  • Illegal offset type in unset: Error exception instead of a warning.
  • Converting an Array to string: warning instead of notice.

Benchmarks

Benchmarks are done on PHP and Symfony 5.2; here are some of the benchmarks done on the latest version of PHP.

A total of five configs are tested using a PHP-FPM and NGINX setup:

  • PHP 7.4 without OPCache Preloading
  • PHP 7.4 with OPCache Preloading
  • PHP 8.0 without OPCache Preloading
  • PHP 8.0 with OPCache Preloading
  • PHP 8.0 with OPCache Preloading and JIT enabled

PHP 8.0 - Performance Throughput Benchmarks

Both PHP 7.4 and PHP 8.0 benefit significantly with Throughput from enabling Opcache Preloading.

Further improvements

Here is the list of some additional approved but still in draft improvements of PHP:

  • Stringable interface: It is automatically added to classes implementing _to_string() method. The actual goal here is to use the string|stringable union type.
  • Static return type: It is the usage of static as return type next to self and parent type.
  • New living standard APIs in ext/dom: It proposes to implement the current DOM living standard to the PHP DOM extension by introducing public properties and interfaces.
  • Variable Syntax tweaks: It resolves some residual inconsistencies in PHP’s variable syntax.

Breaking Changes

This is one of the major updates in PHP 8.0. Most of these breaking changes have been deprecated in the previous versions of PHP 7.*. The best thing to do is take a look at the full list of breaking changes over at the UPGRADING document.

Conclusion

PHP indeed is a step towards tidying up the language and boosting the performance significantly.
Most importantly, bringing the long-awaited features have definitely put PHP into the top place. It'll be exciting to see what and how the JIT engine will have on codebases and the broader PHP community.

Introducing features that include Opcache extension, constructor property promotion, Union types, and more support for attributes have made it easy and efficient for people to code. It promises to improve the language's usability and performance.

Dhaval D.
Dhaval D.
Technical Writer

Dhaval has over 6 years of experience as a Content Writer in the Professional Industry. He is also a Certified Digital Marketing Executive with Google & Facebook Certifications. As a passionate writer, he loves to write challenging content and go out of the box to make the article worth it.


Deploy CloudPanel For Free! Get Started For Free!