Statyczna analiza kodu cz 1

Jedna z ostatnich prelekcji na jakiej zjawiłem się podczas zeszłorocznego PHPCon była poświęcona statycznej analizie kodu. Bardzo lubię ten temat ponieważ odpowiedni zestaw narzędzi zarówno na komputerze jak i na serwerze CI jest bardzo pomocny w utrzymywaniu kodu aplikacji w dobrej kondycji. Często okazuje się jednak, że nawet doświadczeni programiści nie stosują albo nawet nie wiedzą co to jest statyczna analiza kodu.

W tym poście mam zamiar opisać te najprostsze wg mnie narzędzia do statycznej analizy kodu PHP bezpośrednio wspomagające sam proces programowania. W drugiej części opiszę narzędzie zwane PHP_CodeSniffer, w trzeciej PHP Mess Detector. Ostatnią czwartą części tego postu opiszę narzędzia, które służą do analizy całych projektów lub wspomagają np. migrację projektu na inną wersję PHP. Zanim jednak zajmę się samymi narzędziami warto było by odpowiedzieć sobie na podstawowe pytanie…

… czym w zasadzie jest ta „statyczna analiza kodu”

Najprościej rzecz ujmując jest to analiza kodu bez jego uruchamiania. Statyczna analiza kodu jest przeciwieństwem dynamicznej analizy kodu. Przykładowo jeśli używasz Xdebug lub podobnego narzędzia stosujesz właśnie analizę dynamiczną. Dzięki (dynamicznej analizie kodu) można np zerknąć co znajduje się w konkretnej zmiennej, sprawdzić lub zdiagnozować, w którym miejscu aplikacja zużywa najwiecej pamięci.

Analiza statyczna koncentruje się przede wszystkim na samym kodzie, na stylu kodowania, na utrzymaniu porządku w kodzie etc.

Linter

Jako pierwsze opiszę linter w PHP – czyli narzędzie, które mamy dostępne od razu po instalacji PHP. Jeśli nie wiecie dokładnie, czym zajmuje się linter możecie uzupełnić swoją wiedzę w tym miejscu. W skrócie jest to narzędzie, które oznacza podejrzane lub błędne fragmenty kodu.

W PHP aby uzyskać dostęp do lintera należy w CLI wpisać php -l a zaraz po tym ścieżkę do pliku, który chcemy poddać analizie. Oczywiście wpisywanie za każdym razem polecenia w CLI dla pliku, w którym wykonaliśmy jakąś zmianę byłoby bardzo męczące dlatego też istnieje szereg rozszerzeń różnych edytorów dla programistów takich jak Atom czy Sublime Text 3. Oczywiście nie tylko PHP posiada linter – odpowiednie rozszerzenia istnieją także dla JavaScript i innych języków.

PHP Copy/Paste Detector (phpcpd)

Kolejne narzędzie jest bardzo pomocne przy wykrywaniu powtarzających się fragmentów kodu czyli tzw copy/paste programming. Autorem PHPcpd jest Sebastian Bergmann najbardziej znany chyba z PHP Unit.

Samo narzędzie można zainstalować Composerem lokalnie w projekcie:

lub globalnie w systemie:

Gdy już mamy ten etap za sobą w CLI wpisujemy komendę:

Dla przykładu sprawdzę jak dużo duplikowanego kodu znajduje się w CRMie YetiForce w wersji 3.4. Wycinek efektów działania można zobaczyć poniższym screenie:

phpcpd1

Jak widać panowie z YF musieliby trochę dopieścić swój kod. Znaleziono 350 dokładnych kopi kodu w 314 plikach. Łącznie 21864 linie kodu. Domyślnie phpcpd wyszukuje fragmenty gdzie powtórzono minimum 5 lini kodu. Jeśli chcemy to zmienić możemy użyć parametru –min-lines. Gdy uruchomię phpcpd z tym parametrem ustawionym na 4 wynik działania będzie następujący:

phpcpd2

Jak widać wynik tylko nieznacznie różni się od wcześniejszego – znaleziono 351 miejsc gdzie kod jest powtórzony. Oczywiście odczytywanie wyniku działania phpcpd w ten sposób może być trudne dlatego też istnieje możliwość wygenerowania pliku xml z wynikami. Służy do tego parametr –log-pmd=nazwa_pliku.xml.

PHP Coding Standards Fixer

PHP Coding Standards Fixer to owoc współpracy Fabiena Potenciera (założyciela znanej wśród programistów firmy SensioLabs a jego najbardziej znanym projektem jest framework Symfony) i naszego rodaka Dariusza Ruminskiego. Jak sama nazwa wskazuje to narzędzie służy do korygowania kodu tak, aby był zgodny z przyjętymi w projekcie standardami. Instalacja polega na wpisaniu w CLI:

lub dodaniu go lokalnie w projekcie jako plik *.phar.

Teraz aby skorygować jakiś plik należy wydać następujące polecenie:

i w zasadzie to wszystko. Pliki zostaną skorygowane – pytanie tylko wg jakich zasad? W dokumentacji napisane jest „By default, all PSR-2 fixers and some additional ones are run.”. Oczywiście możemy zmienić ten stan rzeczy używając parametru —level:

Inną ciekawą opcją jest możliwość wypisania, jakie elementy w pliku mają zostać poprawione. Można do tego celu użyć parametru —fixers. Przykład poniżej:

W podanym powyżej przypadku w pliku zostaną poprawione tylko „krótkie tagi” rozpoczynające kod PHP. Pełną listę tych elementów można znaleźć w dokumentacji. Istnieje także możliwość sprawdzenia tylko jakie niezgodności są w danym pliku bez jego korygowania – można to osiągnąć za pomocą następującego polecenia:

Warto wspomnieć jeszcze o możliwości utworzenia w projekcie pliku konfiguracyjnego o nazwie .php_cs. Ten plik to tak naprawdę plik PHP. Można w nim zapisywać zasady jakie obowiązują w obrębie projekty aby nie wpisywać cały czas w CLI.

Najbardziej jednak swoją potęgę php-cs-fixer ujawnia w połączaniu z IDE. Przykładowo Atom wraz z paczką atom-beautify pozwala formatować kod aktualnie otwartego pliku, za pomocą wybranego skrótu klawiszowego.

Security Advisories Checker

Ten dodatek jest także autorstwa SensioLabs. Sprawdza on poprzez analizę pliku composer.lock czy zależności, z których korzystamy nie zawierają przypadkiem jakiś znanych luk w bezpieczeństwie. Co ciekawe można to zrobić bez konieczności instalacji jakiegokolwiek dodatku. Wystarczy na stronie security.sensiolabs.org/check załadować swój composer.lock i sprawdzenie nastąpi zdalnie.

Jeśli jednak chcieli byście zweryfikować composer.lock lokalnie na swoim komputerze konieczne będzie pobranie pliku phar z tego miejsca i wywołanie w CLI następującego polecenia:

Poddałem weryfikacji dwa projekty, które rozwijam i w pierwszym wszystko jest ok o czym świadczy screen poniżej:

sec1

Jednak w przypadku drugiego okazało się że Swiftmailer ma lukę. Screen poniżej:

sec2

Na koniec powiem, że ten dodatek informuje tylko o lukach, które zostały zgłoszone do bazy SensioLabs więc może się zdarzyć, że nasze zależności mają jakąś lukę a informacji na jej temat po prostu nie ma w bazie. Po drugie należy regularnie używać tego narzędzia ponieważ baza podatności jest cały czas aktualizowana i może się nagle okazać, że uważany do tej pory za bezpieczny pakiet ma jednak jakieś luki.

… i na zakończenie

Chciałbym przede wszystkim zachęcić do korzystania z tych narzędzi. Mogą one w znacznym stopniu usprawnić waszą pracę i podnieść jakość kodu jaki zostanie przez was napisany. Zachęcam także do komentowania i zaglądania co jakiś czas na bloga, ponieważ już nie długo pojawi się kolejna cześć. Do przeczytania już wkrótce!

Posty które mogą Cię zainteresować:

Dodaj komentarz

Your email address will not be published. Please enter your name, email and a comment.