Skip to main content

Miscellaneous New PHP8 Features

·351 words·2 mins·
Table of Contents

In this final post about PHP81 I’m going to cover random new features that aren’t covered by previous posts.

Match expression2
#

match is similar to switch but with safer semantics and the ability to return values.

Syntax
#

// Before
switch ($this->lexer->lookahead['type']) {
    case Lexer::T_SELECT:
        $statement = $this->SelectStatement();
        break;

    case Lexer::T_UPDATE:
        $statement = $this->UpdateStatement();
        break;

    case Lexer::T_DELETE:
        $statement = $this->DeleteStatement();
        break;

    default:
        $this->syntaxError('SELECT, UPDATE or DELETE');
        break;
}

// After
$statement = match ($this->lexer->lookahead['type']) {
    Lexer::T_SELECT => $this->SelectStatement(),
    Lexer::T_UPDATE => $this->UpdateStatement(),
    Lexer::T_DELETE => $this->DeleteStatement(),
    default => $this->syntaxError('SELECT, UPDATE or DELETE'),
};

Differences to switch
#

Return value
#

switch (1) {
    case 0:
        $result = 'Foo';
        break;
    case 1:
        $result = 'Bar';
        break;
    case 2:
        $result = 'Baz';
        break;
}

echo $result;
//> Bar

echo match (1) {
    0 => 'Foo',
    1 => 'Bar',
    2 => 'Baz',
};
//> Bar

No type coercion
#

switch ('foo') {
    case 0:
      $result = "Oh no!\n";
      break;
    case 'foo':
      $result = "This is what I expected\n";
      break;
}
echo $result;
//> Oh no!

echo match ('foo') {
    0 => "Oh no!\n",
    'foo' => "This is what I expected\n",
};
//> This is what I expected

No fallthrough
#

switch ($pressedKey) {
    case Key::RETURN_:
        save();
        // Oops, forgot the break
    case Key::DELETE:
        delete();
        break;
}

match ($pressedKey) {
    Key::RETURN_ => save(),
    Key::DELETE => delete(),
};

echo match ($x) {
    1, 2 => 'Same for 1 and 2',
    3, 4 => 'Same for 3 and 4',
};

Exhaustiveness
#

switch ($operator) {
    case BinaryOperator::ADD:
        $result = $lhs + $rhs;
        break;
}

// Forgot to handle BinaryOperator::SUBTRACT

$result = match ($operator) {
    BinaryOperator::ADD => $lhs + $rhs,
};

// Throws when $operator is BinaryOperator::SUBTRACT

Mixed Type3
#

This appears to be the PHP equivalent to JavaScript’s any type. I want nothing to do with it and will not bother explaining it further.

Create DateTime objects from interface
#

It’s already possible to create a DateTime object from a DateTimeImmutable

DateTime::createFromImmutable(new DateTimeImmutable())

The other way round isn’t possible. Now with PHP8 we can do the sane thing and use interfaces:

DateTime::createFromInterface(DateTimeInterface $other);
DateTimeImmutable::createFromInterface(DateTimeInterface $other);