Zaczynając od Tracy

Biblioteka Tracy, która została udomowiona pod nazwą Laddy, to przydatny na co dzień pomocnik programisty PHP. To ci pomoże:

  • szybkie wykrywanie i naprawianie błędów
  • błędy w dzienniku
  • wyciągnąć zmienne
  • mierzyć czas wykonywania skryptów i zapytań do bazy danych
  • monitorować wymagania dotyczące pamięci

PHP jest językiem z wyboru do siekania trudnych do wykrycia błędów, ponieważ daje programistom dużą swobodę. Jeszcze cenniejsze jest narzędzie do debugowania Tracy. Wśród narzędzi diagnostycznych PHP to absolutna czołówka.

Jeśli dziś po raz pierwszy spotykasz się z Biedronką, to lepiej uwierz, że Twoje życie zacznie się dzielić na to przed Biedronką i to z Biedronką. Witamy w dobrej części!

Instalacja

Najlepszym sposobem na zainstalowanie Tracy jest pobranie najnowszego pakietu, lub użyty Composer:

composer require tracy/tracy

Możesz również pobrać cały pakiet jako plik tracy.phar.

Zastosowanie

Płyta jest łatwa do aktywacji. Wystarczy dodać poniższe do kodu, najlepiej zaraz po załadowaniu biblioteki (np. require 'vendor/autoload.php') i przed wysłaniem jakiegokolwiek wyjścia:

use Tracy\Debugger;

Debugger::enable();

Pierwszą rzeczą, którą możesz zauważyć na stronie jest Tracy Bar.

(Jeśli nic nie widzisz, oznacza to, że Tracy działa w trybie produkcyjnym. Tracy jest widoczna tylko na localhost ze względów bezpieczeństwa. Możesz zmusić Tracy do uruchomienia w trybie deweloperskim, przekazując Debugger::Development jako pierwszy parametr do metody enable()).

enable() zmienia poziom raportowania błędów na E_ALL.

Tracy Bar

Tracy Bar to pływający pasek, który pojawia się w prawym dolnym rogu strony. Można go przesuwać za pomocą myszy i będzie pamiętał swoją pozycję po ponownym załadowaniu strony.

Do Tracy Bar można dodać inne przydatne panele. Wiele z nich można znaleźć w dodatkach, a nawet napisać własne.

Jeśli nie chcesz wyświetlać paska Tracy Bar, ustaw:

Debugger::$showBar = false;

Wizualizacja błędów i wyjątków

Wiesz, jak PHP zgłasza błędy: drukuje coś takiego w kodzie źródłowym strony:

Parse error:  syntax error, unexpected '}' in HomePresenter.php on line 15

lub gdy wyjątek nie zostanie złapany:

Fatal error:  Uncaught Nette\MemberAccessException: Call to undefined method Nette\Application\UI\Form::addTest()? in /sandbox/vendor/nette/utils/src/Utils/ObjectMixin.php:100
Stack trace:
#0 /sandbox/vendor/nette/utils/src/Utils/Object.php(75): Nette\Utils\ObjectMixin::call(Object(Nette\Application\UI\Form), 'addTest', Array)
#1 /sandbox/app/forms/SignFormFactory.php(32): Nette\Object->__call('addTest', Array)
#2 /sandbox/app/presenters/SignPresenter.php(21): App\Forms\SignFormFactory->create()
#3 /sandbox/vendor/nette/component-model/src/ComponentModel/Container.php(181): App\Presenters\SignPresenter->createComponentSignInForm('signInForm')
#4 /sandbox/vendor/nette/component-model/src/ComponentModel/Container.php(139): Nette\ComponentModel\Container->createComponent('signInForm')
#5 /sandbox/temp/cache/latte/15206b353f351f6bfca2c36cc.php(17): Nette\ComponentModel\Co in /sandbox/vendor/nette/utils/src/Utils/ObjectMixin.php on line 100

Poruszanie się po takim zestawieniu nie jest łatwe. Jeśli włączysz Label, błąd lub wyjątek zostanie wyświetlony w innej formie:

Komunikat o błędzie dosłownie krzyczy. Widzimy fragment kodu źródłowego z podświetloną linią, w której wystąpił błąd, a informacja *Call to undefined method Nette\Security\User::isLoggedIn() jasno wyjaśnia, na czym polega błąd. Co więcej, cała strona jest na żywo, możemy przeklikać się do większej ilości szczegółów. Spróbuj.

I wiesz co? Pozwoli to na wychwycenie i wyświetlenie nawet fatalnych błędów. Bez konieczności instalowania jakichkolwiek rozszerzeń.

Błędy takie jak literówka w nazwie zmiennej lub próba otwarcia nieistniejącego pliku generują komunikat poziomu E_NOTICE lub E_WARNING. Można je łatwo przeoczyć w grafice strony, a może nawet w ogóle nie być widoczne (chyba, że patrząc na kod strony).

Mogą też być wyświetlane tak jak błędy:

Debugger::$strictMode = true; // pokaż wszystkie błędy
Debugger::$strictMode = E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED; // wszystkie błędy z wyjątkiem powiadomień deprecate.

Aby wykryć literówki podczas przypisywania do zmiennej obiektowej, używamy cechy Nette\Object.

Tryb produkcyjny i rejestrowanie błędów

Jak widać, Laden jest dość lakoniczny, co można docenić w środowisku programistycznym, natomiast na serwerze produkcyjnym spowodowałoby to prawdziwą katastrofę. Tam nie można zrzucić żadnych informacji o debugowaniu. Biedronka ma więc środowisko autodetekcji i jeśli uruchomimy przykład na żywym serwerze, błąd jest rejestrowany zamiast wyświetlany, a odwiedzający widzi tylko zrozumiały dla użytkownika komunikat:

Tryb produkcyjny wyłącza wyświetlanie wszystkich informacji o debugowaniu, które wysyłamy za pomocą dump(), oraz oczywiście wszystkich komunikatów o błędach generowanych przez PHP. Więc jeśli zapomniałeś o jakiejś dump($obj) w swoim kodzie, nie martw się, nic nie zostanie wydrukowane na serwerze produkcyjnym.

Pierwszy parametr metody Debugger::enable() służy do ustawienia trybu. Tryb może być ustalony za pomocą stałej Debugger::Production lub Debugger::Development. Inną opcją jest to, że tryb deweloperski będzie włączony przy dostępie z danego adresu IP o danej wartości tracy-debug cookie. Stosowana składnia to hodnota-cookie@ip-adresa.

Jeśli go nie określisz, domyślnie jest to Debugger::Detect, w takim przypadku tryb jest wykrywany przez adres IP serwera – jeśli jest on dostępny przez publiczny adres IP, działa w trybie produkcyjnym, jeśli jest na lokalnym adresie IP, działa w trybie deweloperskim. Dzięki temu w zdecydowanej większości przypadków nie ma potrzeby ustawiania trybu i będzie on prawidłowo wykrywany przez to, czy aplikacja działa na swoim lokalnym serwerze, czy w ruchu na żywo.

W trybie produkcyjnym Ladenka automatycznie rejestruje wszystkie błędy i złapane wyjątki do dziennika tekstowego. Jeśli nie określimy inaczej, będzie to plik log/error.log. Rejestrowanie błędów jest niezwykle przydatne. Wyobraź sobie, że wszyscy użytkownicy Twojej aplikacji to tak naprawdę beta testerzy, którzy za darmo wykonują najwyższej klasy pracę polegającą na znajdowaniu błędów, a Ty byłbyś głupi, gdybyś wyrzucił ich cenne raporty do kosza niezauważone.

Jeśli musimy zarejestrować niestandardowy raport lub wyjątek złapany przez użytkownika, używamy do tego metody log():

Debugger::log('Wystąpił nieoczekiwany błąd'); // komunikat tekstowy

try {
	kritickaOperace();
} catch (Exception $e) {
	Debugger::log($e); // można również rejestrować wyjątek
	// lub
	Debugger::log($e, Debugger::ERROR); wysyła również powiadomienie e-mail
}

Inny katalog do rejestrowania błędów można ustawić za pomocą drugiego parametru metody enable():

Debugger::enable(Debugger::Detect, __DIR__ . '/mylog');

Jeśli chcesz, aby Tracy rejestrował błędy PHP jako E_NOTICE lub E_WARNING ze szczegółowymi informacjami (raport HTML), ustaw Debugger::$logSeverity:

Debugger::$logSeverity = E_NOTICE | E_WARNING;

Dla prawdziwego zawodowca dziennik błędów jest kluczowym źródłem informacji i chce on być natychmiast informowany o każdym nowym błędzie. Ladenka jest w tym względzie bardzo pomocna, gdyż może go informować o nowych wpisach w dzienniku za pomocą poczty elektronicznej. Określamy gdzie mają być wysyłane maile za pomocą zmiennej $email:

Debugger::$email = 'admin@example.com';

Jeśli używasz całego Nette Framework, to to i więcej można ustawić w pliku konfiguracyjnym.

Jednak aby nie zalać skrzynki mailowej, zawsze wysyła tylko jedną wiadomość i tworzy plik email-sent. Po otrzymaniu powiadomienia mailowego, deweloper sprawdza log, naprawia aplikację i usuwa plik monitorujący, tym samym ponownie aktywując wysyłanie maili.

Otwieranie w edytorze

Po wyświetleniu strony błędu możesz kliknąć na nazwy plików i otworzą się one w Twoim edytorze z kursorem w odpowiedniej linii. Możesz również tworzyć pliki (akcja create file) lub poprawiać w nich błędy (akcja fix it). Aby to zadziałało, wystarczy skonfigurować przeglądarkę i system.

Obsługiwane wersje PHP

Tracy kompatybilny z PHP
Tracy 2.10 – 3.0 PHP 8.0 – 8.2
Tracy 2.9 PHP 7.2 – 8.2
Tracy 2.8 PHP 7.2 – 8.1
Tracy 2.6 – 2.7 PHP 7.1 – 8.0
Tracy 2.5 PHP 5.4 – 7.4
Tracy 2.4 PHP 5.4 – 7.2

Ważne dla najnowszych wersji poprawek.

Porty

Jest to lista nieoficjalnych portów dla innych frameworków i CMS-ów: