PHP 8.4: „Implicitly marking parameter as nullable is deprecated” – jak to naprawić
PHP 8.4 zgłasza przy wielu starszych funkcjach „Implicitly marking parameter as nullable is deprecated”. Co to znaczy, dlaczego jest tak częste i jak naprawić to w kilka minut.
W skrócie: od PHP 8.4 przestarzałe jest pisanie parametru z typem i wartością domyślną null bez wyraźnego oznaczenia, że typ może przyjmować null. Z string $nazwa = null robi się ?string $nazwa = null. Strona działa dalej, o ile ostrzeżenia nie są wyświetlane w przeglądarce. Poprawka jest mechaniczna i przy dużych projektach można ją zrobić automatycznie narzędziami.
Komunikat wygląda na przykład tak:
Deprecated: Klient::zapisz(): Implicitly marking parameter $notatka as nullable
is deprecated, the explicit nullable type must be used instead
in /var/www/html/src/Klient.php on line 42
O co chodzi
Dawniej PHP po cichu zamieniał taki parametr w parametr, który może przyjmować także null:
function zapisz(string $notatka = null) { … }
Typ mówi „string”, a wartość domyślna to null, czyli nie tekst. PHP dotąd tolerował tę sprzeczność. Od PHP 8.4 pojawia się ostrzeżenie, a w którejś z kolejnych głównych wersji ten zapis ma zniknąć. Ponieważ przez lata był powszechny, jest w bardzo dużej ilości starszego kodu, także w bibliotekach, wtyczkach i frameworkach.
Jak to naprawić
Trzeba wyraźnie oznaczyć typ jako dopuszczający null. Są dwa zapisy:
// od PHP 7.1
function zapisz(?string $notatka = null) { … }
// od PHP 8.0
function zapisz(string|null $notatka = null) { … }
Oba znaczą to samo. Wersja ze znakiem zapytania jest krótsza i działa od PHP 7.1. Kto musi wspierać jeszcze starsze wersje PHP, ma inny problem, patrz PHP 7.4, 8.0, 8.1 – koniec wsparcia.
Przy wielu miejscach: automatycznie
W dużych projektach to szybko setki miejsc. Są narzędzia, które automatycznie przepisują kod:
- Rector ma osobną regułę, która znajduje i zamienia dokładnie te przypadki.
- PHP-CS-Fixer też potrafi zamienić parametry z wartością domyślną
nullna wyraźny zapis.
Takie narzędzia warto uruchamiać na kopii albo w osobnej gałęzi Git i przejrzeć zmiany przed wdrożeniem.
Gdy ostrzeżenie pochodzi z cudzego kodu
Jeśli ścieżka prowadzi do vendor/, do wtyczki WordPressa albo rozszerzenia TYPO3, nie należy zmieniać kodu bezpośrednio, bo przy następnej aktualizacji zmiana zniknie. Trzeba zaktualizować paczkę. Większość rozwijanych bibliotek dawno to poprawiła. Jeśli aktualizacji nie ma, to znak, że paczka nie jest już rozwijana.
Inne zmiany w PHP 8.4
PHP 8.4 przynosi też inne zmiany widoczne w starszym kodzie, np. niektóre rozszerzenia, jak IMAP, nie należą już do rdzenia. Pokrewne komunikaty ze starszych wersji opisuję w artykułach „Passing null to parameter … is deprecated” i „Creation of dynamic property is deprecated”.
Profesjonalna pomoc
Przenoszę aplikacje PHP na PHP 8.4, automatycznie tam, gdzie się da, i ręcznie tam, gdzie trzeba, z testami przed wdrożeniem. Więcej w usługach zmiana PHP na hostingu i naprawa błędów PHP.