PHP 8 - Nowe funkcje, usprawnienia i potencjalne problemy z WordPress

Marten Gülink Ostatnia aktualizacja 11.01.2021
.
. 10 Min.
php 8 główna aktualizacja
Ostatnia aktualizacja 11.01.2021


PHP 8 już jest! Duża aktualizacja została wydana 26 listopada 2020 roku i przynosi nam kilka fundamentalnych zmian, jak również wiele nowych funkcji. Nasz programista Marten wyjaśnia, w którym przypadku PHP 8 naprawdę prowadzi do lepszej wydajności i czy powinieneś już teraz zaktualizować do nowej wersji jako użytkownik WordPress :in.

Wprowadzenie do PHP 8 

PHP 8 zostało po raz pierwszy zaprezentowane testerom w wersji alfa 18 czerwca 2020 roku, a od lipca jest w stanie zamrożenia funkcji. Tak więc żadne nowe dodatki nie mogły być dodawane aż do premiery 26 listopada. Unikalną cechą tego wydania jest to, że pomijamy PHP 7.5 i przechodzimy od razu na PHP 8. A ten skok ma wiele funkcji. 

Jednym z najczęstszych pytań dotyczących PHP 8, jakie zadają sobie użytkownicy WordPress jest zapewne: Czy PHP 8 poprawi wydajność mojej strony?

Odpowiedź na to pytanie brzmi (jak to często bywa): "To zależy...".

Kiedy PHP zostało zaktualizowane z wersji 5 do 7, nastąpił ogromny wzrost wydajności. W PHP 8 nie zaobserwujesz jednak ogólnego wzrostu wydajności, chyba że Twoja aplikacja oblicza wiele funkcji matematycznych (zobacz nasz rozdział o kompilatorze JIT). Wynika to głównie z faktu, że optymalizacja kodu PHP jest już bardzo dobrze rozwinięta.

Ale kto powiedział, że wydajność jest ograniczona do czasu kompilacji? Ja, jako deweloper, mierzyłbym wydajność na wiele sposobów, w tym dostępne mi funkcje do pisania dobrze skonstruowanego kodu. A PHP 8 jest pełne nowych udogodnień. A więc zaczynajmy!

Najważniejsze nowości w PHP 8 

PHP 8 posiada osiem głównych nowych funkcji, które chciałbym Wam pokrótce przedstawić: 

  1. Kompilator JIT 
  2. Atrybuty
  3. Argumenty nazwane
  4. Dopasuj wyrażenia 
  5. Wyrażenia rzutowe
  6. Statyczny typ zwrotu 
  7. Typ Unii 
  8. Rodzaje mieszane 

Kompilator JIT (just-in-time)(rfc)

Kiedy kod PHP jest wykonywany, zazwyczaj odbywa się to poprzez kompilację do wirtualnych instrukcji, które są wykonywane na maszynie wirtualnej. JIT zmieni to poprzez kompilację kodu do postaci kodu maszynowego x86, a następnie wykonanie tego kodu bezpośrednio na procesorze. W przypadku aplikacji, które w dużym stopniu opierają się na funkcjach matematycznych, powinno to skutkować wzrostem wydajności. Nie jest to jednak oczekiwane w przypadku przeciętnych aplikacji internetowych (patrz wykres). 

PHP 8 - Nowe funkcje, usprawnienia i potencjalne problemy z WordPress
Źródło

Aby zobaczyć przykład wzrostu wydajności, który można osiągnąć dzięki JIT, najlepiej obejrzeć poniższy film.

YouTube

Wczytując ten film, akceptujesz politykę prywatności YouTube.
Learn More

Załaduj video

PGlmcmFtZSBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUtbm9jb29raWUuY29tL2VtYmVkL2RXSDY1cG1uc3JJIiBhbGxvdz0iYWNjZWxlcm9tZXRlcjsgYXV0b3BsYXk7IGNsaXBib2FyZC13cml0ZTsgZW5jcnlwdGVkLW1lZGlhOyBneXJvc2NvcGU7IHBpY3R1cmUtaW4tcGljdHVyZSIgYWxsb3dmdWxsc2NyZWVuPSIiIHdpZHRoPSI1NjAiIGhlaWdodD0iMzE1IiBmcmFtZWJvcmRlcj0iMCI+PC9pZnJhbWU+

Zasadniczo, jeśli używasz PHP do wykonywania pracochłonnych zadań matematycznych, Twoja aplikacja będzie działać płynniej z nową wersją. Jeśli jednak używasz PHP jak większość użytkowników WordPress , nie zauważysz zbyt wielu zmian. Poniżej wyjaśniam, co PHP 8 oznacza dla właścicieli stron WordPress . 

Przechodząc do nowych funkcji:

Atrybuty v2(rfc, rfc)

Jedną z nowych funkcji w PHP 8 (która wywołała wiele dyskusji w społeczności PHP) są atrybuty - znane jako "adnotacje" w wielu innych językach. Atrybuty zastępują w PHP 8 konieczność przechowywania metadanych za pomocą docblocków. To jest to, do czego kiedyś trzeba było się uciekać, aby zadeklarować metadane dla klas, metod, funkcji i argumentów w uporządkowany sposób. 

Jak możesz sobie wyobrazić, używanie komentarzy do kodu w celu zastosowania metadanych nie było idealne, ale działało. Na szczęście teraz nie będziemy mieli tego problemu. 

Atrybuty mogą być definiowane za pomocą Syntax #[...] zadeklarowany.

Oto kilka przykładów z RFC, jak atrybuty mogą być stosowane do różnych typów danych.

#[ExampleAttribute]
class Foo
{
    #[ExampleAttribute]
    public const FOO = 'foo';
 
    #[ExampleAttribute]
    public $x;
 
    #[ExampleAttribute]
    public function foo(#[ExampleAttribute] $bar) { }
}
 
$object = new #[ExampleAttribute] class () { };
 
#[ExampleAttribute]
function f1() { }
 
$f2 = #[ExampleAttribute] function () { };
 
$f3 = #[ExampleAttribute] fn () => 1;

W tym miejscu warto zauważyć, że RFC dla Atrybutów przeszło kilka zmian od czasu jego pierwotnej koncepcji, co pokazuje wysiłek i przemyślenia, które zostały włożone w tę aktualizację. 

Argumenty nazwane(rfc)

Argumenty nazwane dają większą elastyczność przy wywoływaniu funkcji. Do tej pory trzeba było wywołać funkcję i przekazać każdy argument w kolejności określonej przez funkcję. 

// Using positional arguments:
array_fill(0, 100, 50);

Argumenty nazwane pozwala na określenie nazwy dla każdego parametru. A teraz można je wywołać poza kolejnością, jak opisano poniżej: 

// Using named arguments:
array_fill(start_index: 0, num: 100, value: 50);

Dostęp do nich można również uzyskać w następujący sposób:

array_fill(value: 50, num: 100, start_index: 0);

Możliwa jest również hybryda tych dwóch rozwiązań, pozwalająca na łączenie parametrów nazwanych i argumentów pozycyjnych, co poprawia czytelność kodu: 

htmlspecialchars($string, double_encode: false);

Wyrażenia dopasowujące(rfc)

Match Expressions ma na celu rozwiązanie niektórych długotrwałych problemów w funkcjonalności swojego poprzednika, Switch. 

operator porównania

Switch używa operatora relacyjnego konwertującego typy (==), co może powodować problemy. W przeciwieństwie do tego, Match używa ścisłego operatora porównania (==), niezależnego od strict_types.

wartość zwrotna

Instrukcje switch często tworzą wartość, która jest potrzebna w dalszej części przepływu programu. Może się zdarzyć, że wartość ta nie zostanie ustawiona w instrukcji switch, co w konsekwencji może prowadzić do problemów w skrypcie PHP. Dodatkowo, składnia instrukcji switch utrudnia czytanie zagnieżdżonych instrukcji switch.

switch (1) {
    case 0:
        $y = 'Foo';
        break;
    case 1:
        $y = 'Bar';
        break;
    case 2:
        $y = 'Baz';
        break;
}
 
echo $y;
//> Bar

Nowe wyrażenie dopasowujące eliminuje ten problem poprzez przypisanie wartości zwracanej bezpośrednio dla każdej gałęzi dopasowania(=>), co jest bardziej intuicyjne. 

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

Przejście

Jeśli instrukcja switch nie ma przerwania po każdym przypadku, będzie kontynuować do następnego przypadku, nawet jeśli kod zostanie przerwany. Zostało to zaprojektowane, aby umożliwić funkcjom przełączającym wykonywanie wielu bloków kodu w sekwencji. Jest to jednak częste źródło błędów. 

Match zaimplementował niejawną przerwę po każdej gałęzi (=>). Wiele warunków może być teraz wykonywanych poprzez umieszczenie przecinków pomiędzy każdym z nich: 

match ($x) {
    1, 2 => {
        // Same for 1 and 2
    },
    3, 4 => {
        if ($x === 3) {
            // Only 3
        }
        // Same for 3 and 4
    },
}

Wyrażenia rzutowe(rfc)

W PHP 8 instrukcja throw stała się wyrażeniem. Oznacza to, że throw może teraz technicznie zwracać wartość. Jest to pomocne w tym sensie, że rzut może być teraz używany w wielu innych miejscach, takich jak funkcje strzałek lub operatory Coalesce. 

Funkcje strzałek: 

$callable = fn() => throw new Exception();

Operatory koalescencyjne: 

// $value is non-nullable.
$value = $nullableValue ?? throw new InvalidArgumentException();
 
// $value is truthy.
$value = $falsableValue ?: throw new InvalidArgumentException();

Operatory ternarne:

// $value is only set if the array is not empty.
$value = !empty($array)
    ? reset($array)
    : throw new InvalidArgumentException();

Statyczny typ zwrotu(rfc)

Jak mówi RFC, Statyczny Typ Zwrotny pozwala na zwrócenie specjalnej nazwy klasy "static" z metody: "Statyczna nazwa klasy specjalnej w PHP odnosi się do klasy, na której metoda została wywołana, nawet jeśli metoda jest dziedziczona. Jest to znane jako "późne wiązanie statyczne" (LSB). Ten RFC proponuje, aby static był również użyteczny jako typ zwracany (obok już użytecznych typów self i parent)."

Static nie może być jednak w tym przypadku użyty jako część parametru. Statyczny powrót będzie odnosił się do klasy, która została wywołana. 

Typy unii(rfc)

Rodzaje Unii pozwalają na zadeklarowanie typu wartości, jakiej oczekujesz od wejścia. W niektórych językach nazywa się to schematem. Dokonuje się tego składniowo poprzez użycie  | (np. string|array|int) określone. Ale magia nie kończy się na tym, ponieważ można również użyć zdefiniowanych klas, takich jak:

class MyClass {

}
function myFunction(string|array|int|MyClass){

}

Typy unii są już używane w PHP. Są one jednak zaimplementowane za pomocą metody adnotacji phpdoc, jak pokazano poniżej. 

class Number {
    /**
     * @var int|float $number
     */
    private $number;
 
    /**
     * @param int|float $number
     */
    public function setNumber($number) {
        $this->number = $number;
    }
 
    /**
     * @return int|float
     */
    public function getNumber() {
        return $this->number;
    }
}

Aby uzyskać nieco więcej kontekstu na temat użycia, sprawdź ten przykład z RFC:

class Number {
    private int|float $number;
 
    public function setNumber(int|float $number): void {
        $this->number = $number;
    }
 
    public function getNumber(): int|float {
        return $this->number;
    }
}

Wszystko to sprowadza się do tego, że możesz używać wielu typów wejściowych dla tej samej funkcji zamiast tylko jednego, co pozwala na większy stopień wielokrotnego użycia kodu.

Typy mieszane(rfc)

W ostatnich wersjach PHP możliwe było zadeklarowanie oczekiwanego typu danych wejściowych i zwrotnych. Jednak PHP nie zawsze obsługiwało typy, i to jest problem. W niektórych przypadkach typ został pominięty lub po prostu zapomniany. MixedTypes próbuje teraz rozwiązać ten problem.

An mixed typ byłby odpowiednikiem array|bool|callable|int|float|null|object|resource|string

Oto przykład z dokumentacji RFC, jak to jest używane:

// Valid example
 
class A
{
    public function foo(int $value) {}
}
 
class B extends A
{
    // Parameter type was widened from int to mixed, this is allowed
    public function foo(mixed $value) {}
}

Dodatkowe funkcje PHP 8

Uczyń sortowanie stabilnym(rfc)

Stabilność jest dodawana do wszystkich funkcji, które podlegają pod Sort (na przykład.

sort, rsort, usort, asort, arsort, uasort, ksort, krsort, uksort, array_multisort).

Zalecałbym przeczytanie tego w dokumentach RFC i porównanie z twoją aplikacją, ponieważ zmiana tej funkcjonalności z sortowania niestabilnego na stabilne może negatywnie wpłynąć na twój kod.

Promowanie właściwości konstruktora(rfc)

Ta funkcja powinna pomóc w przyspieszeniu przepływu pracy i zredukowaniu liczby błędów. Obecnie zdefiniowanie obiektu wartości wymaga zestawu boilerplates, jak pokazano poniżej w dokumentacji RFC:

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

W tej metodzie właściwości muszą być powtórzone trzy razy. Ulepszeniem tego jest poniższa krótka formuła: 

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

Bezpieczny operator zerowy(rfc)

W tym bloku pojawił się nowy operator! 

Zamiast klasycznego <code>!== null</code>, mamy teraz to: <code>?-></code>. Na początku wydaje się to dziwne, ale jeśli spojrzysz na to z punktu widzenia łańcuchowania "if-statements", zastosowanie staje się całkiem jasne: 

$country =  null;
 
if ($session !== null) {
    $user = $session->user;
 
    if ($user !== null) {
        $address = $user->getAddress();
 
        if ($address !== null) {
            $country = $address->country;
        }
    }
}
 
// do something with $country
$country = $session?->user?->getAddress()?->country;
 
// do something with $country

str_contains(rfc)

Ta raczej ładna nowa funkcja zwraca wartość boolean (prawda/fałsz), jeśli ciąg znaków znajduje się w innym ciągu znaków. Pobiera dwa argumenty, łańcuch do wyszukania i łańcuch do wyszukania.

str_contains('php8', '8'); // true
str_contains('php8', 'wordpress'); // false

Aby uzyskać jeszcze więcej przydatnych filtrów łańcuchowych, sprawdź te nowe funkcje:

str_starts_with('haystack', 'hay'); // true
str_ends_with('haystack', 'stack'); // true

Te dwa elementy zwrócą wynik typu boolean i działają tak samo jak str_contains().

Słabe mapy(rfc)

W PHP, kiedy ustawiasz zmienną na wartość jakiegoś obiektu, zazwyczaj tworzy ona referencję do tego obiektu, ale nie nowy obiekt. 

Tak więc w tym przypadku możesz skończyć mając wiele odniesień do obiektu, ale tylko jeden obiekt. Problem z tym jest taki, że gdy przyjdzie czas na usunięcie tego obiektu, PHP policzy ilość referencji, które ten obiekt posiada. A jeśli jest ich więcej niż jeden, PHP odmówi usunięcia tego obiektu. 

Weak Maps rozwiązuje ten problem poprzez utworzenie "słabej" referencji do odpowiedniego obiektu. Po usunięciu obiektu, wszystkie zmienne z referencją Weak Maps do tego obiektu są ustawiane na zero. 

Połowy bez przechwytywania(rfc)

Blok try-catch jest już dość niesamowity, jeśli chodzi o raportowanie błędów, a teraz jest jeszcze szybszy sposób, aby to zaimplementować. I nie, to naprawdę nie wpłynie na czytelność. 

W "starej szkole" oznaczało to, że musiałeś przekazać wyjątek catch do zmiennej w ten sposób:

function catchMeWhenIFall(){
	try {
        throw new Exception('NOPE - GRAVITY');
    } catch (Exception $e) {
        return $e->getMessage();
    }

}

Ale teraz nie musisz już definiować zmiennej, którą chcesz przekazać do bloku catch.

try {
	throw new Exception('FOO!');
 catch  (){
	//Do some code here
 }

}

Dodatkowe materiały do czytania o PHP 8

Jeśli chcesz dowiedzieć się więcej o wydaniu PHP 8 lub sprawdzić próbki kodu RFC, zajrzyj do oficjalnego komunikatu o wydaniu. 

Czy jesteś gotowy na PHP 8? 

Żaden programista nie przepada za aktualizacjami z dużymi zmianami (pamiętamy WordPress 5.0 i Gutenberg), gdzie istnieje ryzyko, że Twój kod się zepsuje i czekają Cię godziny pracy lub całkowita przebudowa. Jednakże, jeśli Twój kod działał poprawnie w PHP 7.4, nie powinieneś mieć problemów z PHP 8 (więcej o PHP i WordPress w następnym rozdziale). 

Jednakże, jeśli używasz starszej wersji PHP, powinieneś sprawdzić listę przestarzałych funkcji przed aktualizacją. Zobacz dokumentację PHP "Dodatki", aby uzyskać pełną listę poprzednich funkcji, zmian i problemów przy aktualizacji z jednej wersji PHP do następnej. 

Czy powinieneś zaktualizować swoją stronę WordPress do PHP 8? 

W przypadku dobrze przygotowanych baz kodu lub baz, które są na bieżąco z najnowszymi wersjami PHP, nie ma większego problemu [z migracją do PHP 8]. W rzeczywistości jednak WordPress nie jest taką bazą kodową.

Omar Reiss, yoast

Ten cytat z Yoast "WordPress and PHP 8 Compatibility Report" już sugeruje, że jako użytkownik WordPress nie powinieneś traktować aktualizacji do PHP 8 lekko. Konkluzja raportu wzmacnia to założenie, jak pisze Omar Reiss: "Badając jedynie podzbiór zmian w PHP 8 mogliśmy już potwierdzić, że mogą one powodować poważne uszkodzenia na stronach, których pochodzenie jest niejasne. Często błąd występuje w jednym miejscu, ale jest spowodowany przez plugin lub theme w innym miejscu, co czyni te problemy trudnymi do usunięcia."

Te problemy z kompatybilnością są również powodem, dla którego PHP 8 nie jest od razu dostępne w panelu administracyjnym RAIDBOXES dla naszych klientów. Szczególnie po dużych aktualizacjach, zawsze warto dać programistom Plugin wystarczająco dużo czasu na wprowadzenie niezbędnych poprawek i poczekać. Jak tylko upewnimy się, że nie ma problemów z instalacją WordPress , a PHP 8 działa stabilnie i wydajnie na naszym systemie, oczywiście udostępnimy PHP 8.

Jeśli masz już dostęp do PHP 8 i chcesz przetestować nową wersję na swojej stronie WordPress , powinieneś - jak przed każdą aktualizacją - najpierw stworzyć kopię zapasową. Jak poprawnie przetestować nową wersję PHP na RAIDBOXES można przeczytać w tym artykule w Helpcenter (tutaj na przykładzie PHP 7.2).

Nasz wniosek

PHP 8 jest dużym krokiem naprzód w stosunku do swoich poprzedników. Chociaż możesz nie zauważyć radykalnej poprawy wydajności od razu (w zależności od tego, jak używasz PHP 8), powinieneś rozważyć aktualizację - przynajmniej po tym, jak ją przetestujesz, jest stabilna i dostępna na Twoim serwerze WordPress . Nowa wersja jest naturalnym krokiem naprzód, a wdrażając ją raczej wcześniej niż później, stworzysz solidne podstawy dla przyszłych ulepszeń, rozwoju i przyszłej poprawy wydajności.

Masz więcej pytań na temat PHP 8?

Mam nadzieję, że tym artykułem udało mi się przybliżyć Ci nowe, ekscytujące funkcje PHP 8. Masz więcej pytań na ten temat? Zapraszamy do skorzystania z funkcji komentarza. Chcesz więcej wskazówek na temat WordPress , projektowania stron internetowych i nie tylko? Następnie śledź nas na Twitterze, Facebooku lub poprzez nasz newsletter.

Jako web developer w RAIDBOXES , Marten zawsze pracuje nad nowymi funkcjami dla naszych klientów. Na "wp unboxed" punktuje również swoją wiedzą na temat tworzenia stron internetowych, WordPress i naszego dashboardu. W wolnym czasie lubi też zajmować się self-hostingiem i najnowszymi trendami w internecie.

Powiązane artykuły

Komentarze do tego artykułu

Napisz komentarz

Twój adres e-mail nie zostanie opublikowany. Pola wymagane oznaczone są *.