PHP8 (quick note)
Tags: php
Published: 2020-05-13 19:14:58

### Union types

Union types are a collection of two or more types which indicate that either one of those can be used.

void can never be part of a union type, since it indicates "no return value at all". Furthermore, nullable unions can be written using |null, or by using the existing ? notation:

```php
public function foo(Foo|Bar $input): int|float;

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;

```

### JIT

The JIT — just in time — compiler promises significant performance improvements, albeit not always within the context of web requests.

### Attributes

Attributes, commonly known as annotations in other languages, offers a way to add meta data to classes, without having to parse docblocks.

```php
<<Attribute>>
class ExampleAttribute
{
    public $value;
 
    public function __construct($value)
    {
        $this->value = $value;
    }
}

use App\Attributes\ExampleAttribute;

<<ExampleAttribute>>
class Foo
{
    <<ExampleAttribute>>
    public const FOO = 'foo';
 
    <<ExampleAttribute>>
    public $x;
 
    <<ExampleAttribute>>
    public function foo(<<ExampleAttribute>> $bar) { }
}

```

### static return type

```php
class Foo
{
    public function test(): static
    {
        return new static();
    }
}
```

### mixed type 

Note that mixed can also be used as a parameter or property type, not just as a return type.

### Throw expression

throw from being a statement to being an expression, 

```php
$triggerError = fn () => throw new MyError();

$foo = $bar['offset'] ?? throw new OffsetDoesNotExist('offset');
```

### Weak maps
a WeakMap implementation is added in PHP 8. WeakMaps hold references to objects, which don't prevent those objects from being garbage collected.

### ::class on objects
::class on objects, instead of having to use get_class() on them.
```php
$foo = new Foo();

var_dump($foo::class);
```

### Non-capturing catches 
to catch an exception before PHP 8, 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:
```php
try {
    // Something goes wrong
} catch (MySpecialException $exception) {
    Log::error("Something went wrong");
}

try {
    // Something goes wrong
} catch (MySpecialException) {
    Log::error("Something went wrong");
}
```

### Trailing comma in parameter lists

```php
public function(
    string $parameterA,
    int $parameterB,
    Foo $objectfoo,
) {
    // …
}
```

### Stringable interface

The Stringable interface can be used to type hint anything that is a string or implements __toString(). Furthermore, whenever a class implements __toString(), it automatically implements the interface behind the scenes and there's no need to manually implement it.

```php

class Foo
{
    public function __toString(): string
    {
        return 'foo';
    }
}

function bar(Stringable $stringable) { /* … */ }

bar(new Foo());
bar('abc');
```

### str_contains() function

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

### str_starts_with() and str_ends_with() functions
```php
str_starts_with('haystack', 'hay'); // true
str_ends_with('haystack', 'stack'); // true
```