ix
ix

informatix

EN version Porozmawiajmy o projekcie
Strona główna / Blog / Migracja PHP 7.4 na 8.x — breaking changes wersja po wersji ...
• 8 min czytania •

Migracja PHP 7.4 na 8.x — breaking changes wersja po wersji [2026]

Cztery generacje zmian między 7.4 a 8.4, każda z własną listą pułapek: wyjątki zamiast warningów, deprecation nulli, dynamiczne właściwości, typowane stałe. Rozkład zmian wersja po wersji, tabela ryzyk i plan przejścia krok po kroku.

Migracja PHP 7.4 na 8.x — breaking changes wersja po wersji [2026]
DevOps i utrzymanie

Migracja PHP 7.4 na 8.x to najczęstsza migracja w polskich projektach — na 7.4 stoi większość aplikacji pisanych w latach 2019–2022. Dobra wiadomość: to również migracja najlepiej udokumentowana i najbardziej zautomatyzowana. Zła: między 7.4 a 8.4 narosły cztery generacje zmian, a każda ma własną listę pułapek. Ten artykuł rozkłada przejście wersja po wersji — co dokładnie się psuje, jak to naprawić i w jakiej kolejności iść.

Najważniejsze: Kolejność jest sztywna: 7.4 → 8.0 → 8.1 → 8.2 → 8.3 → 8.4. Nie musisz wdrażać każdego kroku na produkcję, ale musisz przejść przez każdy na poziomie kodu i testów. Rector prowadzi przez wszystkie przejścia automatycznie (withPhpSets(php84: true)), a ręczne poprawki skupiają się na zmianach zachowania, nie składni.

Dlaczego warto iść krokami, a nie skokiem

Technicznie da się przepisać kod z 7.4 od razu na 8.4 — Rector ma zestaw kumulatywny. Praktycznie skok przez cztery wersje naraz ma dwie wady.

  • Pierwsza: diagnoza błędów. Gdy testy sypią się po masowej zmianie, nie wiesz, które zachowanie za to odpowiada. Przy krokach wersja po wersji każdy commit odpowiada jednemu przejściu — błąd znajdujesz w minutach, nie w dniach.

  • Druga: zależności. Frameworki i biblioteki mają własne wymagania wersyjne. Laravel 8 wspiera PHP 8.0, Laravel 9 — 8.0/8.1, Laravel 10 — 8.1/8.2, Laravel 11 — 8.2/8.3. Idąc krokami, aktualizujesz framework równolegle z PHP, wersja po wersji — jak po schodach. Skok naraz oznacza aktualizację frameworka przez cztery wersje w jednym kroku, co jest osobnym, dużym projektem.

W małych projektach (kilkanaście tysięcy linii, framework w wersji wspierającej 8.4) skok bezpośredni jest sensowny — Rector i testy wystarczą. W średnich i dużych — kroki.

7.4 → 8.0 — największa porcja zmian

  • To przejście generacyjne: PHP 8.0 zmieniło model błędów, system typów i usunęło konstrukcje z 5.x/7.0. Najważniejsze zmiany z punktu widzenia typowego projektu.

Wyjątki zamiast warningów. Wiele funkcji, które w 7.4 zwracały false i logowały warning, w 8.0 rzuca wyjątki (ValueError, TypeError). Dotyczy m.in. strpos() z niepoprawnymi argumentami, funkcji arytmetycznych, json_decode() z głębokością. Kod, który „działał mimo warningów", przestaje działać.

// 7.4: zwraca false + warning
$pos = strpos('abc', '');

// 8.0: rzuca ValueError — trzeba walidować argumenty
if ($needle === '') {
    // obsłuż przypadek brzegowy
}

Surowsze porównania stringów z liczbami. 0 == "abc" w 7.4 dawało true, w 8.0 — false. To zmiana, która cicho psuje logikę warunków w starym kodzie — testy na ścieżkach decyzyjnych (uprawnienia, koszyki, rabaty) są tu obowiązkowe.

Usunięte funkcje i konstrukcje. each() (od lat deprecjonowane), create_function(), money_format(), rozszerzenie mysql_* (usunięte już w 7.0), stare API preg_replace z modifierem /e. Rector podmienia większość automatycznie.

Zmiany w sortowaniu i funkcjach tablicowych. usort() i rodzina stabilnych sortowań — w 8.0 sortowania są stabilne, co zmienia kolejność równych elementów. Jeśli kod polegał na niestabilności (a część starego kodu polegała), wyniki się zmienią.

Konstruktor promotion, atrybuty, named arguments — nowe możliwości, które Rector częściowo wprowadza automatycznie (np. promotion), ale nie musisz ich używać. Migracja to nie refaktoryzacja do nowego stylu.

8.0 → 8.1 — deprecation nulli i nowe typy

Łagodniejsze przejście, ale z jedną zmianą, która dotyka niemal każdego projektu.

Deprecation null w parametrach nie-nullowalnych. Przekazywanie null do funkcji wewnętrznych oczekujących stringa/int (np. strlen(null), htmlspecialchars(null)) daje od 8.1 deprecation. Kod działa dalej, ale zaśmieca logi — a w przyszłych wersjach to będzie błąd.

// 7.4/8.0: działa bez ostrzeżenia
htmlspecialchars($value); // $value może być null

// 8.1+: deprecation — napraw jawnie
htmlspecialchars($value ?? '');

Nowości, które warto wykorzystać przy okazji migracji: enums (enum Status: string), readonly properties, never jako typ zwracany, fibers (dla bibliotek asynchronicznych), array_is_list().

Zmiany w zachowaniu: $GLOBALS działa inaczej (pełny dostęp do zapisu), część ostrzeżeń o parametrach opcjonalnych przed wymaganymi stała się deprecation. Rector ma reguły dla większości przypadków.

8.1 → 8.2 — dynamiczne właściwości i readonly klasy

Kolejne przejście „deprecation-focused" — kod działa, ale logi się zapełniają.

Deprecation dynamicznych właściwości. Tworzenie właściwości „w locie" ($obj->newField = 1 na obiekcie, który nie zadeklarował pola) jest od 8.2 deprecjonowane. Dotyczy to szczególnie starych ORM-ów, obiektów DTO i kodu, który „doklejał" pola do modeli. Rozwiązania: deklaracja pól, #[AllowDynamicProperties] jako bufor, albo refaktoryzacja na tablice/typy.

class UserDto
{
    // 8.2+ wymaga jawnej deklaracji albo atrybutu
    public string $name;
    public ?string $email = null;
}

Deprecation części interpolacji stringów. Konstrukcje typu "${var}" (poza {$var}) są deprecjonowane — prosta zamiana składni, Rector robi to automatycznie.

Nowości: readonly klasy, typy DNF ((A&B)|C), usunięcie części dynamicznych właściwości z biblioteki standardowej. Pełne wsparcie dla 8.2 mają Laravel 10/11, Symfony 6.2+.

8.2 → 8.3 i 8.3 → 8.4 — kosmetyka i domknięcie

Dwa ostatnie kroki są najlżejsze — dla większości projektów to dni pracy, nie tygodnie.

8.3: typowane stałe klas (kod nadpisujący stałe ze zmienionym typem dostaje błąd — dotyczy głównie bibliotek), deprecation get_class() bez argumentu (zamiana na static::class), losowe zmiany w Random\Randomizer, nowa funkcja json_validate().

8.4: deprecation niejawnych parametrów nullowalnych (string $x = null → ?string $x = null), property hooks (gettery/settery na właściwościach), asymetryczna widoczność, nowe funkcje tablicowe (array_find, array_any, array_all).

Po przejściu na 8.4 projekt jest na wersji z pełnym wsparciem do końca 2028 roku — i gotowy na 8.5 (kolejne kosmetyczne przejście, gdy będzie potrzebne).

Tabela zbiorcza — co sprawdzić w każdym kroku

Przejście Najważniejsze ryzyko Typowa naprawa Czas dla średniego projektu
7.4 → 8.0 wyjątki zamiast warningów, porównania stringów walidacja argumentów, poprawki warunków 1–3 tygodnie
8.0 → 8.1 deprecation nulli ?? '' i jawne typy nullowalne 2–5 dni
8.1 → 8.2 dynamiczne właściwości deklaracje pól / atrybut 3–7 dni
8.2 → 8.3 typowane stałe (biblioteki) aktualizacja zależności 1–3 dni
8.3 → 8.4 niejawne nullowalne parametry Rector + przegląd sygnatur 1–2 dni

Praktyczny plan przejścia 7.4 → 8.4

Kolejność pracy, która sprawdza się w projektach.

  1. Audyt na 8.4 — PHPCompatibility z testVersion 8.4- i PHPStan od razu pokażą pełną listę blokad wszystkich przejść. Listę porządkujesz potem według kroków.
  2. Testy ścieżek krytycznych — bez nich nie zaczynaj. 15–20 testów end-to-end wystarczy na start.
  3. Rector krokami — najpierw withPhpSets(php80: true), commit, testy. Potem php81, php82, php83, php84. Każdy krok to osobny commit i osobne uruchomienie testów.
  4. Framework równolegle — aktualizuj Laravel/Symfony o jedną wersję na krok PHP (mapę wersji frameworka do PHP znajdziesz w dokumentacji frameworka).
  5. Staging po każdych dwóch krokach — wdrażaj na staging i przechodź testy manualne; produkcję aktualizuj, gdy cały łańcuch jest zielony.
  6. Deprecation do zera — po każdym kroku uruchom aplikację i wyczyść logi z ostrzeżeń. Zaległe deprecation z 8.1/8.2 to najczęstszy powód niespodzianek przy kolejnych krokach.

Szczegóły techniczne workflow z Rectorem — konfiguracja, tryby, CI — są w artykule o automatycznej migracji z Rector. Pełny proces z audytem, stagingiem i wdrożeniem opisuje przewodnik o migracji PHP na 8.x. Jeśli zaczynasz od jeszcze starszej wersji (5.6), dochodzi krok przez 7.x — opisany w tym samym przewodniku.

Najczęściej zadawane pytania

Czy z PHP 7.4 mogę przejść od razu na 8.4?

Technicznie tak — Rector ma zestaw kumulatywny (withPhpSets(php84: true)), który stosuje reguły wszystkich przejść. W praktyce dla średnich i dużych projektów lepiej iść krokami: łatwiej przypisać regresje do konkretnej zmiany, a framework aktualizujesz w rytmie zgodnym z jego wymaganiami wersyjnymi.

Co się najczęściej psuje przy przejściu z 7.4 na 8.0?

  • Trzy rzeczy: wyjątki tam, gdzie wcześniej były warningi (funkcje stringowe i arytmetyczne), zmienione porównania stringów z liczbami (0 == "abc" przestało być prawdziwe) oraz usunięte funkcje (each(), create_function(), preg_replace z /e). Dwie pierwsze wymagają przeglądu logiki, trzecia jest w większości automatyczna.

Ile trwa migracja z PHP 7.4 na 8.4?

  • Mały projekt: 1–2 tygodnie. Średni system z frameworkiem: 4–10 tygodni (łącznie z aktualizacją frameworka i bibliotek). Duży system bez testów: 2–4 miesiące etapami. Samą refaktoryzację kodu Rector wykonuje w godziny — reszta czasu to testy, poprawki ręczne i wdrożenia.

Czy po migracji PHP muszę od razu aktualizować framework?

Nie „od razu", ale w tej samej podróży. Frameworki mają własne przedziały wsparcia PHP — np. Laravel 8 działa na PHP 8.0, ale nie na 8.2+. Jeśli zostaniesz na starym frameworku na nowym PHP, stracisz wsparcie frameworka. Najlepszy rytm: przy każdym kroku PHP podnieś framework o wersję, którą obsługuje.

Czy dynamiczne właściwości to blokada migracji na 8.2?

Nie — to deprecation, kod działa dalej. Ale zaśmieca logi i stanie się błędem w przyszłej wersji. Najczęstsze źródła to stare ORM-y i kod „doklejający" pola do obiektów. Naprawa: jawne deklaracje pól albo #[AllowDynamicProperties] jako świadomy bufor z datą przeglądu.

Czy migracja z 7.4 wpłynie na wydajność aplikacji?

  • Zwykle pozytywnie: PHP 8.x jest szybsze od 7.4 o kilkanaście–kilkadziesiąt procent w zależności od profilu (JIT, optymalizacje silnika, szybsze funkcje). Największy zysk widzą aplikacje obciążone CPU; aplikacje ograniczone bazą danych zyskają mniej. Pełny efekt daje też aktualizacja frameworka i bibliotek.

Źródła

KS

Krzysztof Słonina

Full stack developer i właściciel Inoventis Solutions (informatix). Od 2009 roku buduje aplikacje webowe w Laravel/PHP, integracje e-commerce i automatyzacje procesów — m.in. OneCRMApp i FamilyTimelineApp, działające na Laravel, React i Inertia.js.

O autorze
Darmowy PDF

Checklista wymagań do wyceny aplikacji

12 pytań kontrolnych, które warto przygotować przed rozmową z wykonawcą — szybsza wycena, mniej ukrytych kosztów.

Powiązane wpisy

20.10.2026

Migracja i aktualizacja PHP — przewodnik 5.6/7.x → 8.x [2026]

Migracja PHP na 8.x usuwa ryzyka bezpieczeństwa i przyspiesza aplikację bez zmian w kodzie biznesowym. Ścieżka krok po kroku — od audytu zgodności i testów, przez Rector, po wdrożenie z monitoringiem. Z tabelą dat wsparcia, kosztami i checklistą.

Czytaj dalej

23.10.2026

Checklista migracji PHP — 30 punktów przed wdrożeniem [2026]

30 punktów w pięciu fazach — od inwentaryzacji zależności po monitoring po wdrożeniu — z kryterium odbioru dla każdej fazy i listą błędów, które taka kontrola eliminuje. Szablon planu migracji i narzędzie weryfikacji wykonawcy.

Czytaj dalej