Co nowego w PHP v7.3? Opisaliśmy wszystkie 34 zmiany

13 grudnia zostanie udostępniona wersja produkcyjna PHP v7.3. Zmian jest naprawdę dużo, choć nie są rewolucyjne. Większość z nich to drobnostki, ale na pewno każdy znajdzie coś dla siebie. Wszystkie 34 aktualizacje postanowiłem opisać poniżej.

Spis treści

8.  Same site cookie

Jest to póki co proponowany standard sieci web, ale widać chęć jego adopcji w przeglądarkach, językach programowania czy frameworkach. Zapobiega atakom CSRF. Metoda polega na ustawieniu odpowiedniej flagi w ciastku HTTP. Ciastka są ustawiane przez serwer za pomocą nagłówka Set-Cookie, nagłówek ten może mieć kilka flag:

Set-Cookie: foo=bar; path=/; domain=example.com; HttpOnly

Nowa flaga to SameSite która może przyjąć dwie wartości, Strict oraz Lax:

Set-Cookie: foo=bar; path=/; domain=example.com; HttpOnly; SameSite=Lax

Zarówno Lax jak i Strict kompletnie blokują ataki CSRF. Prosto i skuteczne. Czym się różnią oba parametry? Strict jak sama nazwa mówi jest bardziej restrykcyjny. Załóżmy, że jesteś zalogowany do serwisu https://www.allegro.pl. Gdyby ten serwis miał ustawioną flagę na Strict, to po kliknięciu w link, który umieściłem w tym zdaniu zostałbyś przekierowany do strony, lecz byłbyś wylogowany! W trybie Lax jest mniej restrykcyjny. Pozwala on na wczytanie zawartości pliku cookie pod warunkiem, że żądanie jest wykonane przy użyciu bezpiecznej metody, tzn. GET, HEAD, OPTIONS, TRACE. Ataki CSRF są wykonywane zazwyczaj przy użyciu metod POST, PUT, DELETE. Gdyby jednak twoja strona akceptowała żądania niebezpieczne metodą GET, np:

GET http://www.example.com/api/deleteUser?id=1

to zdecydowanie zalecam użycia trybu Strict.

Ekipa PHP zmodyfikowała cztery funkcje:

  • setcookie,
  • setrawcookie,
  • session_set_cookie_params,
  • session_get_cookie_params

Pierwsze trzy funkcje mają bardzo zbliżoną sygnaturę. Sygnatura funkcji setcookie w wersji v7.2 wygląda tak:

Straszny bajzel z tym parametrami! Więc ludzie odpowiedzialni za PHP postanowili, że nie będą wprowadzać kolejnego argumentu. Zaimplementowali alternatywną wersją funkcji:

Opcje jakie możesz teraz przekazać są następujące:

  • name,
  • value,
  • expire,
  • path,
  • domain,
  • secure,
  • httponly,
  • samesite.

Pozostałe sygnatury po zmianach:

Sygnatura funkcji session_get_cookie_params się nie zmieniła. Dodany został nowy klucz w tablicy zwracanej:

Więcej informacji:

9. hrtime() – monotoniczny timer

Czy wiesz, że funkcja microtime() ma pewne ograniczenia? Dość często wylicza się czas wykonania kodu właśnie przy pomocy microtime(). Na początku kodu deklarujesz zmienną, która zawiera czas uruchomienia skryptu, a na końcu deklarujesz kolejną zmienną, tym razem czas zakończenia. Wystarczy, że obliczysz różnicę i otrzymasz czas wykonania. Kod:

Problem polega na tym, że jeśli czas systemowy zmieni się podczas wykonywania skryptu to czas wykonywania skryptu będzie niepoprawny. Dlatego zaimplementowano funkcję hrtime(). Dzięki niej czas wykonywania skryptu będzie super dokładny. Użycie:

Więcej informacji:

10. Nowa metoda – DateTime::createFromImmutable()

Metoda ta jest lustrzana do metody DateTimeImmutable::createFromMutable(). Więcej informacji:

11. Nowa funkcja – fpm_get_status()

Zwraca ona aktualny status menadżera procesów fastcgi. Więcej informacji: https://github.com/php/php-src/commit/140def4ac712acac6e2561f65e1b72f8efad8717

12. Nowe funkcje w GMP

gmp_binomial()

Wylicza Symbol Newtona. Więcej informacji: https://pl.wikipedia.org/wiki/Symbol_Newtona. Commit: https://github.com/php/php-src/commit/7fea79675cfb064726f3fc7845e2c2bb1f247ea5.

gmp_lcm()

Wylicza najmniejsza wspólną wielokrotność. Więcej informacji: https://pl.wikipedia.org/wiki/Najmniejsza_wspólna_wielokrotność. Commit: https://github.com/php/php-src/commit/a1d36a1157bd88afd64119be059812dd46c4fb2d.

gpm_perfect_power()

Sprawdza czy dana liczba jest perfect power. Więcej info: https://en.wikipedia.org/wiki/Perfect_power. Commit: https://github.com/php/php-src/commit/10a336d3d062fdfa0133b22fb4f79852ec939ea5.

gmp_kronecker()

Wylicza Symbol Kroneckera. Więcej informacji: https://pl.wikipedia.org/wiki/Symbol_Kroneckera. Commit: https://github.com/php/php-src/commit/fc80114a481e1e7fc8c7be775a2cce683db9c107.

13. CompileError – nowy typ błędu

Ekipa PHP dodała nowy błąd do aktualnie dostępnych. Dziedziczy po nim ParseError. Póki co bardzo niewielka ilość błędów kompilacji rzuci CompileError zamiast generować błąd fatal. Dotyczy to tylko funkcji token_get_all() w trybie TOKEN_PARSE oraz eval(). W przyszłości więcej błędów będzie rzucać CompileError.

Więcej informacji https://github.com/php/php-src/commit/d04917c7b361fd07e098fe29ae931fb6fac1d9e0.

14. Aktualizacja PCRE do PCRE2

PHP aktualnie bazuje na PCRE w wersji pierwszej, które jest dość stare. Dlatego postanowiono o aktualizacji do najnowszej wersji PCRE2, która została wydana w 2015. Całość zmian jest „pod maską”, ale kilka rzeczy się zmieni:

  • modyfikator S nie ma wpływu na zachowanie, wszystkie wyrażenia regularne są teraz dokładniej analizowane, więc ta flaga jest zawsze włączona,
  • modyfikator X również nie ma wpływu na zachowanie, PCRE2 domyślnie korzysta z tej flagi więc zespół PHP ustawił ją zawsze włączoną,
  • PCRE2 korzysta z nowszego Unicode (v10 w PCRE2 vs v7 w PCRE) więc niektóre wyrażenia mogą się inaczej zachowywać,
  • PCRE2 jest bardziej dokładne, więc niektóra wyrażenie które były zgodne z poprzednią implementacją, teraz mogą nie działać jak należy.

Więcej informacji:

https://wiki.php.net/rfc/pcre2-migration
https://github.com/php/php-src/pull/2857

15. MBString – wsparcie pełnego case-mapping i case-folding

W stosunku do do prostego case-mapping, jego pełna odmiana może zmienić długość łańcucha znaków. Przykład:

Różne typy case-mapping oraz case-folding są dostępne przez mb_convert_case():

  • MB_CASE_LOWER (używane domyślnie przez mb_strtolower),
  • MB_CASE_UPPER (używane domyślnie przez mb_strtoupper),
  • MB_CASE_TITLE,
  • MB_CASE_FOLD,
  • MB_CASE_LOWER_SIMPLE,
  • MB_CASE_UPPER_SIMPLE,
  • MB_CASE_TITLE_SIMPLE,
  • MB_CASE_FOLD_SIMPLE (używane domyślnie przez operacje case-insensitive).
ZOBACZ TEŻ:  Konferencja „IT w Produkcji” o technologiach wykorzystywanych w nowoczesnych firmach produkcyjnych

Przy tej zmianie radzę zweryfikować czy stary kod działa poprawnie. Polecam Unit Testy do tego.

Więcej informacji:

16. compact() rzuci Notice gdy napotka niezdefiniowaną zmienną

Przed v7.3 funkcja compact() w żaden sposób nie informowała o fakcie przekazania nazwy niezadeklarowanej zmiennej. W przypadku literówki jest to bardzo przydatna rzecz. Spójrz na ten przykład, który wyrzuci Notice w v7.3:

Przy tej zmianie radzę zweryfikować czy stary kod działa poprawnie. Polecam Unit Testy do tego.

Więcej informacji:

17. instanceof – brak Fatal error w przypadku literału

Załóżmy, że masz tablicę z nieznaną Ci zawartością i chcesz z wyciągnąć tylko obiekty danej instancji. Teoretycznie wystarczy przefiltrować tablicę za pomocą instanceof:

Jedna w v7.2 spowoduje tp Fatal error:

Do wersji v7.2 operator instanceof działał tylko z obiektami, w v7.3 naprawili to i teraz możesz wykonać instanceof na dowolnym typie zmiennej, w przypadku gdy nie będzie ona obiektem, zwróci false:

Więcej informacji:

https://github.com/php/php-src/commit/b6131364f95af68159b1c17ab48f9523e439cb65
https://github.com/php/php-src/blob/PHP-7.3/UPGRADING#L173

18. Przeprojektowane narzędzie ext_skel

Narzędzie to z pewnością przyda Ci się, jeśli planujesz stworzyć własne rozszerzenie do PHP. Każde rozszerzenie składa się z mnóstwa plików, wiele z nich wygląda bardzo podobnie i mają zbliżoną treść, wręcz duplikacje w niektórych miejscach. By ułatwić pracę przy tych plikach powstało narzędzie ext_skel. We wcześniejszych wersjach PHP narzędzie to było napisane w bash z kilkoma zależnościami. W v7.3 całość została przepisane w PHP + zero zależności. By tworzyło się rozszerzenia łatwiej. Więcej info:

19. Wyjątki nie wypełnią stanu error_get_last()

Wyjątki wyrzucane przez automatyczną konwersję Warning w trybie EH_THROW już nie wypełniają stanu error_get_last(). Teraz działają w ten sam sposób co wyjątki rzucane manualnie.

Więcej:

20. TypeError zgłosi błędne typy jako int oraz bool

Gdy w pliku PHP masz zadeklarowane strict_types to musisz sam zadbać o typy zmiennych. Załóżmy że masz metodę która przyjmuję argument typu int. Gdy przekażesz argument type string, język wyrzuci TypeError. W v7.2 w przypadku gdy twój kod oczekuje int albo bool, wyjątek zgłosi że oczekuje integer lub boolean:

W v7.3 poprawiono to i teraz zgłasza int lub bool:

Więcej:

21. Instrukcja continue rzuci Warning wewnątrz switch

Jeśli w kodzie masz pętlę np. while, w której jest struktura switch, a do tego wewnątrz switch użyjesz continue, by przejść do kolejnej iteracji w pętli, to twój kod był poprawny w v7.2, ale działał nie prawidłowo. continue wewnątrz switch działa tak samo break, przerywa dalsze przetwarzanie switch i nie przechodzi do kolejnej iteracji w pętli zawierającej switch. Wynika to z faktu iż switch jest uważany przez język za pętlę. Więc by przejść do kolejnej iteracji należy użyć continue 2. Zespół PHP wyszedł temu na przeciw i wyrzuci Warning w tym przypadku:

Przy tej zmianie radzę zweryfikować czy stary kod działa poprawnie. Polecam Unit Testy do tego.

Więcej:

https://github.com/php/php-src/commit/04e3523b7d095341f65ed5e71a3cac82fca690e4
http://php.net/manual/en/control-structures.continue.php

Zapraszamy do dyskusji

Patronujemy

 
 
More Stories
Programowanie “bez gadania”, czyli jak ułatwić pracę sobie i innym