Rector to narzędzie open source, które automatycznie przepisuje kod PHP na nowszą wersję języka — usuwa wycofane funkcje, aktualizuje składnię i modernizuje konstrukcje do aktualnych standardów. W praktyce eliminuje 80–90% mechanicznej pracy przy migracji PHP, skracając ją z tygodni do dni. Ten przewodnik pokazuje, jak skonfigurować Rector do migracji, jak prowadzić zmiany wersja po wersji i jakich pułapek unikać.
Najważniejsze: Rector nie zastępuje testów ani decyzji architektonicznych — to maszyna do mechanicznej refaktoryzacji. Bezpieczny workflow: ruleset dla jednego kroku wersji → uruchomienie z
--dry-run→ przegląd diffa → commit → testy → następny krok. Nigdy nie uruchamiaj Rectora na produkcji bez przejścia przez staging.
Czym jest Rector i co potrafi
Rector analizuje kod przez AST (drzewo składniowe) i przepisuje go według zestawów reguł. Ma trzy zastosowania, które nakładają się na siebie w migracji PHP.
- Aktualizacje wersji PHP — rulesety
PHP_80,PHP_81,PHP_82,PHP_83,PHP_84(i kumulatywnewithPhpSets) podmieniają usunięte funkcje, aktualizują składnię i wprowadzają nowe konstrukcje. - Aktualizacje frameworków — gotowe zestawy dla Symfony, Laravel, PHPUnit, Doctrine i kilkudziesięciu innych projektów.
- Refaktoryzacja jakościowa — typowanie, martwy kod, wczesne zwroty, uproszczenia warunków.
Rector wspiera przejścia od PHP 5.3 aż do najnowszych wersji — to jedyne narzędzie tego typu z tak szerokim pokryciem historycznych wersji. Oficjalna dokumentacja z listą wszystkich reguł jest w repozytorium rectorphp/rector na GitHubie.
Instalacja i minimalna konfiguracja
Rector instalujesz jako zależność deweloperską. Do projektu z Composerem
composer require --dev rector/rector
Konfiguracja to plik rector.php w katalogu głównym projektu. Minimalna wersja dla migracji na PHP 8.4 wygląda tak
<?php
// rector.php
declare(strict_types=1);
use Rector\Config\RectorConfig;
return RectorConfig::configure()
->withPaths([
__DIR__ . '/app',
__DIR__ . '/src',
__DIR__ . '/tests',
])
->withPhpSets(php84: true); // kumulatywnie: 5.6 → 7.x → 8.0–8.4
Kluczowe decyzje konfiguracyjne.
withPhpSets(php84: true)— zestaw kumulatywny: Rector zastosuje reguły wszystkich przejść prowadzących do 8.4. To najszybsza droga, gdy migrujesz z 5.6/7.x bezpośrednio.withPaths— katalogi, które Rector ma przepisywać. Zawsze wskaż też katalog testów — inaczej rozjedzie się spójność.withSkip— wyjątki dla reguł, które w Twoim projekcie robią więcej szkody niż pożytku (np. agresywne uproszczenia warunków w kodzie generowanym).
Wersję krokową stosujesz, gdy chcesz iść wersja po wersji — co jest zalecane w dużych projektach
// Etap 1: tylko przejście 7.4 → 8.0
return RectorConfig::configure()
->withPaths([__DIR__ . '/src'])
->withPhpSets(php80: true);
Po zakończeniu etapu podmieniasz konfigurację na kolejny krok (php81: true, potem php82: true itd.) i powtarzasz cykl.
- ## Workflow: jak prowadzić migrację z Rector krok po kroku
Bezpieczny proces składa się z sześciu kroków, które powtarzasz dla każdego etapu wersji.
- Upewnij się, że testy przechodzą — zielony stan wyjściowy to warunek. Rector przepisuje kod masowo; bez testów nie odróżnisz poprawnej zmiany od regresji.
- Uruchom Rector w trybie podglądu — zobaczysz dokładnie, co się zmieni, bez zapisu plików.
- Przejrzyj diff — zmiany mogą liczyć tysiące linii, ale wzorce się powtarzają. Wyłap nietypowe przypadki.
- Zastosuj zmiany — usuń flagę podglądu, żeby Rector zapisał pliki.
- Uruchom testy i PHPStan — zielone testy + brak nowych błędów statycznych = commit.
- Commituj jako osobny krok — historia git pokaże dokładnie, co zmienił który ruleset, co ułatwia ewentualny cof.
Odpowiednie komendy wyglądają tak
# Podgląd zmian (nic nie zapisuje)
vendor/bin/rector process --dry-run
# Zapis zmian
vendor/bin/rector process
# Tylko wybrany katalog
vendor/bin/rector process src/Legacy
Wskazówka: W dużych projektach uruchamiaj Rector katalogami albo modułami, commitując po każdym. Łatwiej wtedy zlokalizować błąd, jeśli testy się wysypią — i można oddać zmiany do review w częściach.
Rector w CI — żeby kod nie „cofał się" w czasie
Jednorazowa migracja to początek. Drugą wartością Rectora jest pilnowanie, żeby nowy kod nie używał konstrukcji z poprzednich wersji. Dodaj do pipeline'u krok sprawdzający:
# .github/workflows/ci.yml (fragment)
- name: Rector (dry-run — blokuje wycofywanie się w czasie)
run: vendor/bin/rector process --dry-run
Jeśli deweloper napisze kod w starym stylu, CI to wychwyci. To szczególnie ważne w projektach, gdzie migracja szła etapami — bez takiej bramki stare wzorce wracają przy każdym nowym zadaniu.
Co Rector naprawi, a czego nie
Warto znać granicę automatyzacji, żeby nie przecenić narzędzia.
Rector naprawi automatycznie: usunięte funkcje (each(), create_function()), zmianę API funkcji (preg_replace z /e, mysql_* → mysqli/PDO w ograniczonym zakresie), niejawne parametry nullowalne, get_class() bez argumentu, typy i składnię (strzałkowe funkcje, konstruktor promotion, match), częściowo typowanie właściwości.
Rector nie naprawi: logiki opartej na zachowaniach, które zmieniły się między wersjami (rzutowanie typów, sortowanie, porównania stringów numerycznych), porzuconych bibliotek wymagających wymiany, problemów architektonicznych, kodu generowanego przez inne narzędzia (trzeba go wykluczyć przez withSkip).
Dlatego audyt zgodności (PHPCompatibility, PHPStan) i testy zostają w planie — Rector działa między nimi: po audycie, przed testami regresji na stagingu.
Pułapki, które warto znać przed pierwszym uruchomieniem
- Diff nie do przejrzenia w całości — w projekcie z 100 tys. linii pierwszy przebieg może zmienić 20 tys. linii. Nie próbuj czytać wszystkiego: przejrzyj próbkę, zaufaj testom, commituj krokami.
- Konflikty z formatowaniem — Rector zmienia składnię, ale nie formatuje kodu. Uruchom po nim
php-cs-fixeralbopint, żeby diff był czytelny. - Kod generowany — szablony kompilowane, cache, migracje generowane przez ORM: wyklucz przez
withSkipalbowithPaths, bo Rector może „naprawić" coś, co i tak zostanie nadpisane. - Reguły agresywne — część zestawów (np.
LevelSetList::UP_TO_PHP_84z regułami jakościowymi) zmienia więcej niż wymaga migracja. Do migracji używajwithPhpSets, nie pełnych level setów. - Brak testów = brak siatki bezpieczeństwa — w projektach bez testów najpierw napisz testy charakterystyczne na ścieżki krytyczne, dopiero potem uruchom Rector. Inaczej nie masz jak zweryfikować masowych zmian.
Rector a inne narzędzia migracji
Rector nie działa sam — w procesie migracji PHP towarzyszą mu trzy narzędzia, każde z inną rolą.
| Narzędzie | Rola | Kiedy uruchamiasz |
|---|---|---|
| PHPCompatibility | wykrywa konstrukcje niezgodne z docelową wersją | przed migracją (audyt) |
| Rector | automatycznie przepisuje kod na docelową wersję | po audycie, przed testami |
| PHPStan | wykrywa błędy typów i wywołań po przepisaniu | po Rectorze, w CI |
| PHP-CS-Fixer / Pint | formatowanie po masowych zmianach | po Rectorze |
Ten układ — wykryj, przepisz, zweryfikuj, sformatuj — to standardowy pipeline migracji PHP. Cały proces, wraz z krokami audytu i wdrożenia, opisuję w przewodniku o migracji PHP na 8.x. Jeśli migrujesz z konkretnej wersji, kolejność rulesetów i najważniejsze breaking changes znajdziesz w artykule o migracji PHP 7.4 na 8.x.
Kiedy Rector to dobry wybór — a kiedy nie
Rector ma największy sens w projektach, które mają testy albo przynajmniej działające ścieżki krytyczne do zweryfikowania ręcznie. W projektach z frameworkiem (Symfony, Laravel) dochodzi bonus: gotowe rulesety frameworkowe pozwalają połączyć migrację PHP z aktualizacją frameworka.
Odradzam Rector w dwóch sytuacjach. Pierwsza: projekt bez żadnych testów i bez środowiska staging — masowe zmiany bez siatki bezpieczeństwa to hazard. Druga: kod, który i tak planujesz przepisać od zera — automatyzacja refaktoryzacji kodu, który zniknie, to strata czasu. W obu przypadkach najpierw zabezpieczenie (testy, decyzja o kierunku), potem narzędzia.
Jeśli chcesz ocenić, ile pracy czeka Twój projekt, zanim uruchomisz Rector — zamów audyt kodu albo audyt techniczny. Raport z audytu zawiera listę blokad i plan migracji, a Rector jest jednym z pierwszych kroków wykonawczych.
Najczęściej zadawane pytania
Czy Rector jest bezpieczny dla kodu produkcyjnego?
Sam Rector nie dotyka produkcji — działa na plikach w repozytorium. Ryzyko polega na tym, że przepisze kod niepoprawnie w miejscach, których nie rozumie. Dlatego standardowy workflow to: gałąź, podgląd (--dry-run), testy, staging, dopiero potem produkcja. Z testami i stagingiem ryzyko jest niskie.
Ile czasu oszczędza Rector przy migracji PHP?
W typowym projekcie eliminuje 80–90% mechanicznej pracy — zamiana usuniętych funkcji, aktualizacja składni, poprawki deprecation. Migracja, która ręcznie zajęłaby tygodnie, z Rectorem zajmuje dni. Pozostałe 10–20% (logika zależna od zmienionego zachowania języka, wymiana bibliotek) nadal wymaga człowieka.
Czy Rector działa z Laravel i Symfony?
Tak — Rector ma oficjalne rulesety dla Laravel, Symfony, PHPUnit, Doctrine i innych. Dla Laravel dostępny jest osobny zestaw aktualizacji frameworka, który można łączyć z rulesetami wersji PHP. Uwaga: aktualizację frameworka prowadź jako osobny krok (osobny commit, osobne testy), nie razem z migracją PHP.
Czy potrzebuję testów, żeby użyć Rectora?
Formalnie nie — Rector uruchomi się bez nich. Praktycznie tak: przy zmianach liczonych w tysiącach linii testy to jedyny sposób weryfikacji. Jeśli projekt nie ma testów, napisz najpierw testy charakterystyczne na ścieżki krytyczne (logowanie, zamówienie, płatność). To inwestycja, która zwraca się przy każdej kolejnej zmianie.
Co zrobić, gdy Rector zmieni coś niepoprawnie?
Wycofaj konkretny commit (zmiany commituj krokami, więc cofnięcie jest precyzyjne), dodaj regułę do withSkip albo wyklucz plik, a przypadek popraw ręcznie. Zgłoś też problem w repozytorium Rectora — to projekt aktywnie rozwijany i takie zgłoszenia są zwykle szybko naprawiane.
Czy Rector obsługuje przejście z PHP 5.6 od razu na 8.4?
- **Tak —
withPhpSets(php84:** true)stosuje kumulatywnie reguły wszystkich przejść od 5.6 do 8.4. W dużych projektach lepiej jednak iść krokami (7.4 → 8.0 → 8.1 → …), bo łatwiej przypisać błędy do konkretnej zmiany i bezpieczniej wdrażać na staging.