DEV Community

Cover image for PHP 8 Is here! A step in the right direction?
Paul Isaris
Paul Isaris

Posted on • Originally published at paulisaris.com

PHP 8 Is here! A step in the right direction?

post photo by pexels

Introduction

PHP 8 is finally here!

PHP 8.0 is a major update of the PHP language.
It contains many new features and optimizations including named arguments, union types, attributes, constructor property promotion, match expression, nullsafe operator, JIT, and improvements in the type system, error handling, and consistency.

In this article, we will review all the new features and changes, and share some thoughts about each of the changes, as well as on the roadmap that PHP seems to be carving ahead.

You can read all about these in the official release announcement as well.

New features

Named arguments

In PHP 8, when calling a function, you can omit the non-required arguments, and pass only what is desired.

Named Parameters example

function my_awesome_function(string $name, string $value = "", int $expires = 0) {
    ...
}
Enter fullscreen mode Exit fullscreen mode

Let's say now that we want to call this function, but only specify the $name and $expires attributes.

In PHP 7:

// calling the function. but we only want to specify $name and $expires
my_awesome_function('test', '', time() + 60 * 60 * 2)
Enter fullscreen mode Exit fullscreen mode

In PHP 8:

// calling the function. but we only want to specify $name and $expires
my_awesome_function(name: 'test', expires: time() + 60 * 60 * 2)
Enter fullscreen mode Exit fullscreen mode

My thoughts on named parameters

This is a nice and handy touch. Many languages nowadays support this kind of method calling.

However, this design can lead to functions that break the Single-responsibility_principle, by resulting in methods that "do too much" by having many parameters. So, as always, use with caution ;-)

Attributes

Attributes are the new kid in the block. It is essentially a configuration language embedded directly into code.

Attributes is a native PHP syntax that offers the ability to add structured, machine-readable metadata information on declarations in code: Classes, methods, functions, parameters, properties, etc.

Attributes Example

In PHP 7 (With PHPDocs):

class BookController
{
    /**
     * @Route("/api/books/{id}", methods={"GET"})
     */
    public function get($id) { /* ... */ }
}
Enter fullscreen mode Exit fullscreen mode

In PHP 8:

class BookController
{
    #[Route("/api/books/{id}", methods: ["GET"])]
    public function get($id) { /* ... */ }
}
Enter fullscreen mode Exit fullscreen mode

Constructor property promotion

The basic idea is simple: ditch all the class properties and the variable assignments, and prefix the constructor parameters with public, protected, or private. PHP will take that new syntax, and transform it to normal syntax under the hood, before actually executing the code.

Constructor properties example

In PHP 7:

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;
  }
}
Enter fullscreen mode Exit fullscreen mode

In PHP 8:

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

My thoughts on Constructor property promotion

Constructor property promotion reduces the amount of code that is required, leading to smaller and cleaner classes.

If you still want to have class properties that are not part of the constructor parameters, you can declare them in the old way, and instantiate them (or nor), inside the constructor.

Union types

Union types are a way of declaring multiple types for a property/variable.
So if a function parameter can take either string or int values, you can now declare it as string|int.

This is something that you could not do in PHP 7, only using PHPDocs (so it was not part of the PHP core libraries, but existed in the PHPDocs).

Instead of PHPDoc annotations for a combination of types, you can use native union type declarations that are validated at runtime.

Union types example

In PHP 7:

class Book {
  /** @var int|float */
  private $price;

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

new Book('test'); // OK at runtime
Enter fullscreen mode Exit fullscreen mode

In PHP 8, since Union types are part of the PHP runtime library and compiler, this will throw an error:

class Book {
  public function __construct(
    private int|float $price
  ) {}
}

new Book('test'); // TypeError
Enter fullscreen mode Exit fullscreen mode

My thoughts on Union types

As a SOLID Principles advocate, I am not a big fan of this change.

I can understand that it can help speed things up and adds a level of control over my code, but I believe that if your code gets often to the point that you need to use union type for a property, then there is definitely something you need to think about.

Match expression

Match expression syntax is one of the nicest features in PHP 8 that improves the switch syntax in multiple ways.

Let's start by comparing the two. Here's a classic switch example (example from this article):

In PHP 7 (using switch):

switch ($statusCode) {
    case 200:
    case 300:
        $message = null;
        break;
    case 400:
        $message = 'not found';
        break;
    case 500:
        $message = 'server error';
        break;
    default:
        $message = 'unknown status code';
        break;
}
Enter fullscreen mode Exit fullscreen mode

In PHP 8 (using match):

$message = match ($statusCode) {
    200, 300 => null,
    400 => 'not found',
    500 => 'server error',
    default => 'unknown status code',
};
Enter fullscreen mode Exit fullscreen mode

My thoughts on the match expression feature

match will do strict type checks instead of loose ones. It's like using === instead of ==.
In my opinion, this is a good chance, since it makes the code stricter and more expressive.

Also, If you forget to check for a value, and when there's no default arm specified, PHP will throw an UnhandledMatchError exception.

Again more strictness, but it will prevent subtle bugs from going unnoticed.

To fix this, you should wrap the match expression inside a separate method, and deal with the UnhandledMatchError exception there, by returning a default value.

Nullsafe operator

Instead of null check conditions, you can now use a chain of calls with the new nullsafe operator.

When the evaluation of one element in the chain fails, the execution of the entire chain aborts, and the entire chain evaluates to null.

Example of nullsafe operator

In PHP 7:

$country =  null;

if ($book !== null) {
  $author = $book->author;

  if ($author !== null) {
    $address = $author->getAddress();

    if ($address !== null) {
      $country = $address->country;
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

In PHP 8:

$country = $book?->author?->getAddress()?->country;
Enter fullscreen mode Exit fullscreen mode

My thoughts on nullsafe operator

I have mixed feelings about this.

Of course, it is a handy touch since it leads to less and definitely more readable code.

But again, by looking at the big picture, why would our code even need to check so deeply and greedily?

Should our code have Business rules that restrain such behavior?
So, again a handy new feature, but use with caution...

Saner string to number comparisons

When comparing to a numeric string, PHP 8 uses a number comparison. Otherwise, it converts the number to a string and uses a string comparison.

In PHP 7:

0 == 'foobar' // true
Enter fullscreen mode Exit fullscreen mode

In PHP 8:

0 == 'foobar' // false
Enter fullscreen mode Exit fullscreen mode

This is definitely a step in the right direction, but only given that PHP is trying to be a stricter language.

When we say equals, we should mean equals!

My overall thoughts on PHP 8

PHP is undoubtedly trying to become a stricter, more "serious" language.

As a big fan of OOP and SOLID Principles principles, I am totally happy and on board with this direction.

Also, as you will see in the upgrade guide, PHP 8 is generally backwards-friendly, since it does not break a lot of functionality from the previous major releases. Cool!

So let's try to use all the new features of PHP as consciously as possible, and build awesome things!

If you are content with the new PHP version, take a look at the migration guide.

What are your thoughts on PHP 8?

Top comments (7)

Collapse
 
moopet profile image
Ben Sinclair

I think in many ways PHP is a lost cause. It simply has too much baggage that to get it to a point where it's good would mean changing so much it's unrecognisable.
That said, it's the language I'm currently using in my job, and I think that most of these changes are for the better.

I also think they're awkward to look at. I see the same happening in Javascriptland, with new syntaxes which either look completely alien or look too close to a different syntax and mean you need to know multiple ways of doing the same thing in order to read anyone else's code. And there are far too many hacks where PHP developers have tried to standardise things their own way and turned the whole thing into an XKCD-style warning to their fellow humans.

Looking forward to most of those changes, but some things like constructor promotion are definitely going to take extra brainpower to notice when it's being done and when it's not. I can see myself re-reading code because I've forgotten how it works by the time I've reached the end of the class.

Collapse
 
robencom profile image
robencom

PHP was never a lost cause and I do not believe it will ever be.

I never understood the random hatred towards PHP, mostly from developers sitting on high horses, judging on the OOP part or whatever.

PHP is always evolving, which is the key of its success, and the key of its popularity. The same thing is happening with JavaScript.

Just remember, PHP is not general purpose language, it is just for web development, and it does a great job at it.

Collapse
 
celyes profile image
Ilyes Chouia • Edited

I agree but to correct things, PHP is indeed a General-purpose language. It can do more than just web related stuff

Collapse
 
twfahey1 profile image
Tyler Fahey

Great write up! Awesome to see php evolving.

Collapse
 
pavlosisaris profile image
Paul Isaris

Thanks Tyler! Yes, as a PHP developer its really great to see that PHP is adopting robust paradigms from other languages.

Collapse
 
cmuralisree profile image
Chittoji Murali Sree Krishna

Finally I can tell everyone, php isn't going to be outdated or dead

Collapse
 
pavlosisaris profile image
Paul Isaris

On the contrary! PHP is continuing strong ;)