Witajcie, miłośnicy PHP i wszyscy, którzy cenią sobie szybkość, wydajność i nowoczesność w programowaniu!
Dzisiaj o wersji PHP 7.4, czyli najnowsza wersja tego popularnego języka programowania, debiutuje z zestawem nowości dnia 28 listopada 2019 roku. Zapewnia zarówno początkującym, jak i doświadczonym programistom jeszcze większą wydajność oraz elastyczność w tworzeniu aplikacji webowych.
Ta najnowsza iteracja PHP to kolejny kamień milowy dla społeczności PHP, kontynuujący ścieżkę innowacji i rozwoju zapoczątkowaną w poprzednich wersjach. Od czasu wprowadzenia PHP 7, każda kolejna wersja przynosiła znaczące ulepszenia, wzmocnienia bezpieczeństwa oraz nowe funkcje, które nie tylko ułatwiają pracę programistom, ale także poprawiają wydajność i stabilność aplikacji opartych na PHP. Ostatnio w moim artykule, przedstawiłem nowości w php 7.3, które warto przejrzeć, jeżeli jeszcze tego nie zrobiłeś. Dzisiaj, w tym artykule przedstawię tajniki PHP 7.4, przyjrzymy się także nowym funkcjom i ulepszeniom.
Od wprowadzenia typowania zmiennych, przez ulepszenia wydajnościowe, po nowe składnie języka, PHP 7.4 obiecuje być kolejnym krokiem do przodu dla wszystkich, którzy wykorzystują ten potężny język do tworzenia aplikacji internetowych. Gotowi do odkrywania?
Oto, co PHP 7.4 ma do zaoferowania!
Arrow functions rfc
Wartość „Arrow Functions” w PHP 7.4 jest trochę odmienna od koncepcji znanej z języka JavaScript. W PHP 7.4 nie ma konkretnego mechanizmu o nazwie „Arrow Functions” jak w JavaScript. Jednak, w PHP 7.4 wprowadzono składnię „short closures” lub „arrow functions” dla wyrażeń funkcji anonimowych.
Oto jak działają wyrażenia funkcji anonimowych (arrow functions) w PHP 7.4:
- Krótsza składnia: Wyrażenia funkcji anonimowych pozwalają na bardziej zwięzłą składnię w porównaniu do tradycyjnych funkcji anonimowych. Pozwalają one na zdefiniowanie funkcji anonimowej w jednej linii, co jest przydatne w przypadku prostych operacji.
- Brak dostępu do zmiennych zewnętrznych: Wyrażenia funkcji anonimowych nie mają domknięcia zmiennych, co oznacza, że nie mają dostępu do zmiennych spoza swojego zasięgu. Musisz przekazywać potrzebne zmienne jawnie za pomocą słowa kluczowego
use
.
// Tablica liczb $numbers = [1, 2, 3, 4, 5]; // Używając tradycyjnej funkcji anonimowej $double_traditional = array_map(function($x) { return $x * 2; }, $numbers); // Używając skróconej składni (arrow function) $double_arrow = array_map(fn($x) => $x * 2, $numbers); // Wyświetlenie wyników print_r($double_traditional); // Wyświetli: Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 10 ) print_r($double_arrow); // Wyświetli: Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 10 )
W tym przykładzie mamy tablicę liczb od 1 do 5. Chcemy pomnożyć każdą liczbę przez 2. Używając funkcji array_map
, aplikujemy funkcję (anonimową) do każdego elementu tablicy.
- W przypadku tradycyjnej funkcji anonimowej, definiujemy funkcję za pomocą słowa kluczowego
function
i zwracamy wynik mnożenia przez 2. - W przypadku skróconej składni (arrow function), używamy
fn($x) => $x * 2
. Jest to bardziej zwięzła forma, gdzie$x
jest argumentem funkcji, a$x * 2
to wyrażenie zwracające wynik.
Oba podejścia dają ten sam rezultat. Jednakże arrow function jest bardziej zwięzła i czytelna, szczególnie gdy funkcja jest prosta.
Typed properties rfc
Typed properties to nowa funkcja dodana w PHP 7.4, która umożliwia definiowanie typów zmiennych dla właściwości obiektów. Dzięki temu można określić, jakiego typu dane powinny być przechowywane w danej właściwości obiektu.
Oto prosty przykład zastosowania Typed properties:
class Product { public int $id; public string $name; public float $price; public function __construct(int $id, string $name, float $price) { $this->id = $id; $this->name = $name; $this->price = $price; } public function displayInfo() { echo "ID: {$this->id}, Name: {$this->name}, Price: {$this->price} <br>"; } } // Tworzenie nowego obiektu Product $product = new Product(1, "Laptop", 1200.50); // Wyświetlanie informacji o produkcie $product->displayInfo();
W tym przykładzie klasa Product
posiada trzy właściwości: $id
, $name
i $price
. Dzięki Typed properties, określiliśmy typ każdej z tych właściwości:
$id
musi być typuint
(liczba całkowita).$name
musi być typustring
(łańcuch znaków).$price
musi być typufloat
(liczba zmiennoprzecinkowa).
Dzięki temu, gdy tworzymy nowy obiekt Product
, musimy przekazać wartości, które odpowiadają typom zdefiniowanym dla tych właściwości. Jeśli spróbujemy przypisać wartość innego typu, PHP wygeneruje błąd podczas wykonywania skryptu.
Typed properties pozwalają programistom na bardziej jednoznaczne definiowanie struktury danych obiektów oraz pomagają w wykrywaniu błędów typów podczas tworzenia i używania obiektów.
Improved type variance rfc
Improved type variance w PHP 7.4 odnosi się do poprawek w systemie typów, które wprowadzono w celu zapewnienia bardziej precyzyjnego zarządzania typami w programowaniu obiektowym. Konkretnie, wprowadzono poprawki w dziedzinie kowariancji i kontrawariancji w typach argumentów i zwracanych wartości w metodach klas.
Aby zrozumieć Improved type variance, przyjrzyjmy się przykładowi:
Załóżmy, że mamy dwa typy klas: Animal
i Cat
, gdzie Cat
dziedziczy po Animal
.
class Animal {} class Cat extends Animal {} // Klasa Zoo przyjmuje funkcję, która zwraca obiekt klasy Animal class Zoo { public function acceptAnimal(callable $callback) { $animal = $callback(); echo get_class($animal) . " accepted in the zoo<br>"; } } // Funkcja zwracająca obiekt klasy Cat function bringCat(): Cat { return new Cat(); } // Tworzenie obiektu Zoo $zoo = new Zoo(); // Przykład użycia $zoo->acceptAnimal('bringCat');
W poprzednim kodzie, mamy klasę Zoo
, która ma metodę acceptAnimal
, która przyjmuje funkcję zwrotną (callable) zwracającą obiekt klasy Animal
. Funkcja bringCat()
zwraca obiekt klasy Cat
, która jest podklasą Animal
.
W PHP 7.3 i starszych wersjach, taki kod spowoduje błąd, ponieważ funkcja bringCat()
zwraca obiekt klasy Cat
, a nie Animal
, co jest oczekiwane przez metodę acceptAnimal
.
W PHP 7.4 i wyższych wersjach, dzięki Improved type variance, jest to teraz możliwe do zaimplementowania poprawnie, bez generowania błędów. Dzięki poprawkom w systemie typów, można teraz bezpiecznie przekazywać obiekty podklasy tam, gdzie oczekiwany jest typ nadrzędny.
To jest ogólna idea Improved type variance – bardziej precyzyjne zarządzanie typami w języku PHP, szczególnie w kontekście dziedziczenia i polimorfizmu.
Null coalescing assignment operator rfc
Następny jest operator przypisania koalescencji zerowej, skrót dla operacji koalescencji zerowej. Zamiast tego:
$data['date'] = $data['date'] ?? new DateTime();
Możemy użyć tego:
$data['date'] ??= new DateTime();
Zobacz też więcej tricków i skrótów dostępnych w php.
Array spread operator rfc
Array spread operator, umożliwia łatwe kopiowanie elementów z jednej tablicy do drugiej lub dołączanie elementów z jednej tablicy do innej. Działa to podobnie jak w języku JavaScript.
Oto prosty przykład, który pokazuje działanie Array spread operatora:
// Tablica wejściowa $array1 = [1, 2, 3]; // Klonowanie tablicy - kopia wartości $array2 = [...$array1]; // Dodanie nowych elementów do tablicy $array3 = [...$array1, 4, 5]; // Wyświetlenie tablic print_r($array2); // Wyświetli: Array ( [0] => 1 [1] => 2 [2] => 3 ) print_r($array3); // Wyświetli: Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 )
W przykładzie powyżej:
...$array1
to Array spread operator, który rozwija tablicę$array1
na poziomie wartości, kopiuje jej elementy i tworzy nową tablicę$array2
z tymi samymi elementami.$array3
zawiera wszystkie elementy z$array1
, ale dodaje do niej również nowe wartości 4 i 5 za pomocą Array spread operatora.
Array spread operator jest bardzo użyteczny w przypadkach, gdy chcemy kopiować lub łączyć elementy z różnych tablic w prosty i czytelny sposób.
Numeric Literal Separator rfc
Numeric Literal Separator, umożliwia czytelniejsze zapisywanie dużych liczb poprzez dodawanie separatorów cyfr.
Sprawdźmy to na prostym przykładzie:
// Zapis liczby bez użycia Numeric Literal Separator $number1 = 1000000; // Zapis liczby z użyciem Numeric Literal Separator $number2 = 1_000_000; // Wyświetlenie liczb echo $number1 . "\n"; // Wyświetli: 1000000 echo $number2 . "\n"; // Wyświetli: 1000000
W przykładzie powyżej, 1000000
oraz 1_000_000
reprezentują tę samą liczbę, czyli milion. Jednakże używając Numeric Literal Separator, czytanie i zrozumienie liczby staje się łatwiejsze, ponieważ separator _
jest ignorowany przez parser i jest używany jedynie do poprawy czytelności kodu.
Numeric Literal Separator nie zmienia wartości liczby, ale pomaga programistom utrzymywać czytelny i przejrzysty kod, szczególnie przy obsłudze dużych liczb.
Foreign function interface rfc
Foreign Function Interface (FFI) to nowa funkcjonalność, która umożliwia wywoływanie funkcji zewnętrznych oraz dostęp do zmiennych z języków takich jak C, bez konieczności pisania dodatkowego kodu w języku C.
Główne cechy FFI to:
- Bezpośredni dostęp do funkcji C: FFI pozwala na bezpośrednie wywoływanie funkcji zewnętrznych napisanych w języku C, bez konieczności pisania dodatkowego kodu C lub korzystania z rozszerzeń PHP.
- Dostęp do struktur C i zmiennych: Za pomocą FFI możesz również uzyskać dostęp do struktur danych oraz zmiennych zdefiniowanych w języku C.
- Brak potrzeby kompilacji rozszerzeń: W przeciwieństwie do tradycyjnych metod, gdzie konieczne było kompilowanie rozszerzeń PHP, FFI pozwala na bezpośrednie wywoływanie funkcji zewnętrznych bez potrzeby kompilacji.
- Łatwa integracja z istniejącym kodem C: FFI umożliwia integrację z istniejącym kodem napisanym w języku C, co jest szczególnie przydatne w przypadku korzystania z bibliotek systemowych lub zewnętrznych.
Ogólnie rzecz biorąc, FFI otwiera nowe możliwości integracji z kodem napisanym w języku C, bez konieczności korzystania z zewnętrznych rozszerzeń PHP lub pisania kodu w języku C. Dzięki temu programiści mogą korzystać z istniejących bibliotek C bez dodatkowego wysiłku związanego z kompilacją i zarządzaniem rozszerzeniami PHP.
Preloading rfc
Kolejną funkcją niższego poziomu jest preloading. Jest to niesamowity dodatek do rdzenia PHP, który może skutkować znaczną poprawą wydajności.
W skrócie: jeśli korzystasz z frameworka, jego pliki muszą być ładowane i łączone przy każdym żądaniu. Preloading pozwala serwerowi załadować pliki PHP do pamięci podczas uruchamiania i mieć je stale dostępne dla wszystkich kolejnych żądań.
Wzrost wydajności wiąże się oczywiście z kosztami: jeśli źródło wstępnie załadowanych plików zostanie zmienione, serwer musi zostać ponownie uruchomiony.
Custom object serialization rfc
Dodano dwie nowe metody magiczne: __serialize i __unserialize. Różnica między tymi metodami a __sleep i __wakeup została omówiona w RFC.
Reflection for references rfc
Biblioteki takie jak var dumper Symfony polegają w dużej mierze na API refleksji, aby niezawodnie zrzucić zmienną. Wcześniej nie było możliwe prawidłowe odzwierciedlanie referencji, co powodowało, że biblioteki te polegały na hackach w celu ich wykrycia.
PHP 7.4 dodaje klasę ReflectionReference, która rozwiązuje ten problem.
Weak references rfc
Słabe referencje to odniesienia do obiektów, które nie zapobiegają ich zniszczeniu.
mb_str_split
added rfc
Ta funkcja zapewnia taką samą funkcjonalność jak str_split
, ale na wielobajtowych łańcuchach.
Password Hashing Registry rfc
Password Hashing Registry w PHP 7.4 to mechanizm, który ułatwia pracę z algorytmami haszowania haseł poprzez centralizację ich obsługi i zarządzanie nimi w ramach rejestru. Dzięki temu można łatwo zmieniać algorytmy haszowania lub dostosowywać ich konfigurację w jednym miejscu bez konieczności zmiany kodu w wielu miejscach.
Oto przykład wykorzystania Password Hashing Registry:
// Przykładowe hasło do zahashowania $password = 'moje_haslo_tajne'; // Definiowanie algorytmu haszowania $options = [ 'algorithm' => 'argon2i', 'memory_cost' => 1<<17, // 128 MB 'time_cost' => 4, 'threads' => 2, ]; // Hashowanie hasła $hashedPassword = password_hash($password, PASSWORD_DEFAULT, $options); // Weryfikacja hasła if (password_verify($password, $hashedPassword)) { echo 'Hasło zostało zweryfikowane poprawnie.'; } else { echo 'Nieprawidłowe hasło.'; }
W tym przykładzie:
- Używamy funkcji
password_hash()
do zahashowania hasła za pomocą domyślnego algorytmu haszowania (wskazanego przezPASSWORD_DEFAULT
) i opcji konfiguracyjnych zdefiniowanych w tablicy$options
. - Następnie używamy funkcji
password_verify()
do weryfikacji hasła. Jeśli hasło jest poprawne, zostanie wyświetlony komunikat „Hasło zostało zweryfikowane poprawnie”, w przeciwnym razie zostanie wyświetlony komunikat „Nieprawidłowe hasło”.
Password Hashing Registry w PHP 7.4 zapewnia elastyczność i łatwość w zarządzaniu algorytmami haszowania haseł oraz pozwala na użycie silnych i bezpiecznych metod haszowania w aplikacjach webowych.
Zmiany i deprecations w php 7.4
Oprócz nowych funkcji, wprowadzono również wiele zmian w języku. Większość z tych zmian nie jest przełomowa, choć niektóre mogą mieć wpływ na bazy kodu.
Należy pamiętać, że ostrzeżenia o deprecjacji nie są z definicji „łamiące”, a jedynie informują programistę, że funkcjonalność zostanie usunięta lub zmieniona w przyszłości. Dobrze byłoby nie ignorować ostrzeżeń o deprecjacji i naprawiać je od razu, ponieważ ułatwi to ścieżkę aktualizacji do PHP 8.0.
Left-associative ternary operator deprecation rfc
Left-associative ternary operator deprecation w PHP 7.4 oznacza, że zmieniła się asocjacja (kierunek działania) operatora trójargumentowego (ternary operator).
Wcześniej, przed wersją PHP 7.4, operator trójargumentowy (?:
) miał lewostronną asocjację, co oznaczało, że wyrażenie a ? b : c ? d : e
było interpretowane jako (a ? b : c) ? d : e
. Oznaczało to, że pierwsze wyrażenie a ? b : c
było wykonywane jako jeden blok, a następnie wynik tego bloku był porównywany z d
.
Od wersji PHP 7.4 zmieniono to zachowanie. Teraz operator trójargumentowy jest prawostronnie asocjacyjny, co oznacza, że wyrażenie a ? b : c ? d : e
jest interpretowane jako a ? b : (c ? d : e)
. Oznacza to, że drugie wyrażenie c ? d : e
jest traktowane jako jeden blok, a jego wynik jest zwracany, jeśli warunek a
jest fałszywy.
Deprecation tego zachowania oznacza, że starożytna asocjacja lewostronna przestanie być wspierana w przyszłych wersjach PHP i zaleca się dostosowanie kodu do nowego sposobu działania operatora trójargumentowego, aby uniknąć ewentualnych problemów zgodności w przyszłości.
Exceptions allowed in __toString
rfc
Metoda __toString()
jest specjalną metodą, która jest automatycznie wywoływana, gdy obiekt jest używany w kontekście stringa. Jej celem jest konwertowanie obiektu na string. Jednakże, gdy wyjątek zostanie rzucony wewnątrz metody __toString()
, nie ma obsługi, która mogłaby go złapać, co może prowadzić do nieprzewidywalnego zachowania i potencjalnych problemów w aplikacji.
Dlatego też zaleca się unikanie rzucania wyjątków w metodzie __toString()
. Zamiast tego, metoda ta powinna zwracać wartość stringa lub prowadzić do jak najmniejszej ilości operacji, które mogłyby potencjalnie spowodować wystąpienie wyjątku. Jeśli jednak konieczne jest zgłoszenie błędu, lepiej jest to zrobić w inny sposób, a nie w metodzie __toString()
.
Concatenation precedence rfc
Precedencja łączenia (concatenation precedence) w PHP 7.4 dotyczy kolejności wykonywania operacji łączenia ciągów znaków za pomocą operatora kropki (.
).
W PHP, operator kropki (.
) służy do łączenia ciągów znaków, czyli konkatenacji. Precedencja określa, w jakiej kolejności operatory są wykonywane w wyrażeniach.
W przypadku PHP, operator kropki (.
) ma niższą precedencję niż większość innych operatorów, więc jest on wykonywany po innych operacjach w wyrażeniu.
Oto przykład predefiniowanej precedencji operatora kropki (.
):
$a = "Hello"; $b = "World"; $c = "!"; $d = $a . $b . $c; // Operator . jest wykonywany po prawej stronie, łącząc $a, $b, $c echo $d; // Wyświetli: HelloWorld!
W powyższym przykładzie, operator kropki (.
) jest używany do łączenia trzech ciągów znaków: $a
, $b
i $c
. Operator ten jest wykonywany po prawej stronie, łącząc te trzy ciągi znaków w jedno wyrażenie, które jest przypisywane do zmiennej $d
.
Precedencja operatora kropki (.
) jest stała i nie zmienia się w PHP 7.4. Jednak należy być ostrożnym przy łączeniu ciągów znaków, aby uniknąć niejednoznaczności i błędów w kodzie.
Curly brackets for array and string access rfc
Możliwe było uzyskanie dostępu do tablic i przesunięć ciągów znaków za pomocą nawiasów klamrowych:
$array{1}; $string{3};
Ta funkcja została wycofana.
Invalid array access notices rfc
Gdybyś użył składni dostępu do tablicy na, powiedzmy, liczbie całkowitej; PHP wcześniej zwróciłoby null. Począwszy od PHP 7.4, emitowane będzie powiadomienie.
$i = 1; $i[0]; // Notice
strip_tags
also accepts arrays
Kiedyś można było usunąć tylko kilka tagów w ten sposób:
strip_tags($string, '<a><div>')
PHP 7.4 pozwala również na użycie tablicy:
strip_tags($string, ['a', 'div'])
Kilka mniejszych deprecations php 7.4 rfc
Ten dokument RFC zawiera wiele małych przestarzałych rozwiązań, z których każde ma własne głosowanie. Koniecznie przeczytaj bardziej szczegółowe wyjaśnienie na stronie RFC, choć tutaj znajduje się lista przestarzałych rzeczy:
- The
real
type - Magic quotes legacy
array_key_exists()
with objectsFILTER_SANITIZE_MAGIC_QUOTES
filter- Reflection
export()
methods mb_strrpos()
with encoding as 3rd argumentimplode()
parameter order mix- Unbinding
$this
from non-static closures hebrevc()
functionconvert_cyr_string()
functionmoney_format()
functionezmlm_hash()
functionrestore_include_path()
functionallow_url_include
ini directive
Nikt jeszcze nie komentował. Bądź pierwszy!