PHP 8 – co ciekawego?

Mimo, że od premiery najnowszej wersji PHP 8 za chwilę minie rok to ja dopiero teraz zdecydowałem się napisać co ciekawego ta wersja przynosi. Powód? Bardzo prosty, musiałem na własnej skórze sprawdzić, które ulepszenia są naprawdę przydatne w mojej codziennej pracy. Przyjrzyjmy się tej liście.

Na pierwszy ogień idą argumenty nazwane (named arguments), pozwalają one zmieniać kolejność przekazywania argumentów do funkcji/metody, a tym samym unikać konieczności podania wartości z zdefiniowaną domyślną wartością. Dla przykładu:

<?php

function rysuj(int $x, int $y = 25, string $figura = 'kwadrat') {
    printf ('Rysuje w punkcie x: %d, y: %d figure: %s', $x, $y, $figura);
}

rysuj(
 figura : 'trojkat', // tym samym unikamy podania parametru y - zostanie użyta wartość domyślna
  x: 12
);

Długo wyczekiwanym przez mnie usprawnieniem PHP są adnotacje (lub też inaczej atrybuty) wbudowane w język. Nie musimy już posiłkować się bibliotekami jak Doctrine\ORM. Pomimo, że wybór właściwej notacji był niezwykle burzliwy to osiągnięto kompromis definiując adnotacje przy użyciu Syntax #[…]. Należy też nadmienić, że twórcy w sposób staranny i przemyślany projektowali ten feature. Z tego też powodu będę chciał bardziej szczegółowo opisać adnotacje w osobnym wpisie.

Zdecydowanie najczęściej używaną przeze mnie nowością jaką zaoferowało PHP 8 to bezpieczny operator zerowy (nullsafe operator). Pozwala uniknąć całej ifozy sprawdzeń przy wypakowywaniu konkretnej wartości. Sprawdźmy to na przykładzie z trzema klasami, użytkownik posiada adres, adres posiada obiekt kraj.

<?php
class Country {
    private $code = null;
    
    public function getCode(): ?string
    {
        return $this->code;
    }
}

class Address {
    private ?Country $country;
    
    public function getCountry(): ?Country
    {
        return $this->country;
    }
}

class User {
    private ?Address $address = null;
    
    public function getAddress(): ?Address
    {
        return $this->address;
    }
}

$user = new User();

echo $user?->getAddress()?->getCountry()?->getCode();

W przypadku wystąpienia wartości null nie otrzymamy błędu, kod dalej będzie się wykonywać.

Jednakże nie wszystkie feature PHP 8 przypadły mi do gustu. Unie są dobrym przykładem tezy, że nie zawsze rozwój jest postępem. W tym przypadku mówimy o cofnięciu się w rozwoju języka do czasów z przed PHP 7 ponieważ unie to konstrukcja pozwalająca na definiowania kilku typów dla danej zmiennej (co praktycznie oznacza brak typu).

<?php

class samochod {
    private int|float|string $cena;
    
    public function ustawCena(int|float|string $cena)
    {
        $this->cena = $cena;
    }
    
    public function pobierzCena(): int|float|string
    {
        return $this->cena;
    }
}

$fiat = new samochod();
$fiat->ustawCena(99.99);

echo $fiat->pobierzCena();

Nie dostrzegam również korzyści z wyrażenia dopasowania (match expressions). Jak dla mnie to tylko nakładka na switch case z kilkoma wyjątkami.

<?php
$name = match(2) {
    1 => 'One',
    2 => 'Two',
};

echo $name; // "Two"

choć może to jednak kwestia przyzwyczajenia się do tego całego PHP 8?