profileRyan KesPGP keyI build stuffEmailGithubTwitterLast.fmMastodonMatrix

Miscellaneous New PHP8 Features

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);