Instalacja biblioteki z Packagist
🎯 Po tej lekcji zainstalujesz monolog/monolog, skonfigurujesz logger i zrozumiesz rolę composer.lock oraz dlaczego vendor/ trafia do .gitignore.
Największa siła Composera to dostęp do tysięcy gotowych bibliotek. Zamiast pisać od zera logowanie, walidację czy parsowanie plików CSV, możesz skorzystać z rozwiązań przetestowanych przez społeczność PHP. W tej lekcji zainstalujemy Monolog — najpopularniejszą bibliotekę do logowania w PHP, używaną m.in. w Symfony i Laravelu.
Instalacja monolog/monolog
composer require monolog/monolog
Composer pobierze pakiet i wszystkie jego zależności, a następnie zaktualizuje composer.json i composer.lock:
./composer.json has been updated
Running composer update monolog/monolog
...
- Installing psr/log (v3.0.2): Extracting archive
- Installing monolog/monolog (3.8.x): Extracting archive
Generating autoload files
psr/log (interfejsu PSR-3 dla loggerów). Composer pobiera go automatycznie — nie musisz się tym martwić.Zaktualizowany composer.json
{
"name": "twoja-firma/projekt",
"require": {
"php": ">=8.1",
"monolog/monolog": "^3.0"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
Znak ^3.0 oznacza „wersja zgodna z 3.0 — czyli 3.x, ale nie 4.x". To format SemVer (Semantic Versioning).
Plik composer.lock
composer.lock zapisuje dokładne wersje wszystkich pakietów — łącznie z zależnościami zależności:
{
"packages": [
{
"name": "monolog/monolog",
"version": "3.8.1",
...
},
{
"name": "psr/log",
"version": "3.0.2",
...
}
]
}
composer.lock powinien być w repozytorium Git. Gdy inny developer (lub serwer CI/CD) uruchomi composer install, dostanie dokładnie te same wersje, co Ty. Bez composer.lock wersje mogłyby się różnić między środowiskami.Katalog vendor/ w .gitignore
Katalog vendor/ zawiera kod pobrany przez Composera. Może ważyć od kilku MB do setek MB — nie ma sensu go commitować. Wystarczy go wygenerować jedną komendą.
Utwórz (lub uzupełnij) plik .gitignore w katalogu projektu:
vendor/
Żeby odtworzyć środowisko na nowym komputerze lub serwerze:
composer install
Composer odczyta composer.lock i pobierze dokładnie te same wersje.
Użycie Monologa
<?php
declare(strict_types=1);
require 'vendor/autoload.php';
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Level;
// Utwórz logger z nazwą kanału 'app'
$log = new Logger('app');
// Dodaj handler: logi trafią do pliku app.log od poziomu DEBUG w górę
$log->pushHandler(new StreamHandler('app.log', Level::Debug));
// Loguj zdarzenia
$log->debug('Sprawdzam połączenie z bazą danych...');
$log->info('Użytkownik zalogował się', ['user_id' => 42]);
$log->warning('Czas odpowiedzi API przekroczył 1 s');
$log->error('Nie można zapisać pliku', ['path' => '/var/log/app.log']);
Uruchom skrypt:
php index.php
Zawartość app.log:
[2026-01-01T12:00:00.000000+0100] app.DEBUG: Sprawdzam połączenie z bazą danych... [] []
[2026-01-01T12:00:00.001000+0100] app.INFO: Użytkownik zalogował się {"user_id":42} []
[2026-01-01T12:00:00.002000+0100] app.WARNING: Czas odpowiedzi API przekroczył 1 s [] []
[2026-01-01T12:00:00.003000+0100] app.ERROR: Nie można zapisać pliku {"path":"\/var\/log\/app.log"} []
Poziomy logowania (RFC 5424)
Monolog implementuje standard PSR-3, który definiuje 8 poziomów:
| Poziom | Użycie |
|---|---|
| debug | Szczegółowe informacje deweloperskie |
| info | Normalne zdarzenia aplikacji |
| notice | Ważne, ale nie błędne zdarzenia |
| warning | Coś nieoczekiwanego, ale aplikacja działa |
| error | Błąd wykonania — coś poszło nie tak |
| critical | Krytyczny błąd wymagający uwagi |
| alert | Akcja wymagana natychmiast |
| emergency | System nie działa |
Wiele handlerów
Możesz zapisywać logi w kilku miejscach jednocześnie:
<?php
declare(strict_types=1);
require 'vendor/autoload.php';
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Level;
$log = new Logger('app');
// Plik: wszystkie logi od DEBUG
$log->pushHandler(new StreamHandler('app.log', Level::Debug));
// Standardowe wyjście błędów: tylko WARNING i wyżej
$log->pushHandler(new StreamHandler('php://stderr', Level::Warning));
$log->info('Coś się stało'); // trafi tylko do pliku
$log->error('Duży problem!'); // trafi do pliku I na stderr
Podsumowanie: co wylądowało w projekcie
projekt/
├── vendor/
│ ├── autoload.php
│ ├── monolog/
│ │ └── monolog/ ← kod Monologa
│ └── psr/
│ └── log/ ← interfejs PSR-3
├── .gitignore ← vendor/ wpisane tutaj
├── composer.json ← zależności + autoload
├── composer.lock ← zablokowane wersje (commituj!)
└── index.php
W ostatniej lekcji tego modułu zobaczysz, jak zadbać o spójny styl kodu przez PSR-12 i narzędzie PHP-CS-Fixer.
Sprawdź się
Dlaczego katalog vendor/ powinien znaleźć się w pliku .gitignore?
Katalog vendor/ może ważyć wiele megabajtów i zawiera kod generowany automatycznie. Każdy developer odtworzy go jedną komendą: composer install. Commitowanie vendor/ to strata miejsca w repozytorium i źródło konfliktów scalania.
Co gwarantuje plik composer.lock w projekcie zespołowym?
composer.lock zapisuje dokładne wersje (i hasze) wszystkich pakietów — łącznie z zależnościami zależności. Gdy developer lub serwer CI/CD uruchomi composer install, dostanie identyczne środowisko. To kluczowe dla powtarzalności buildu.
Jak skonfigurować kanał i handler w Monologu, żeby logi trafiały do pliku app.log?
Monolog używa architektury kanał → handler. Logger to kanał (np. 'app'), a StreamHandler to jeden z wielu handlerów zapisujący logi do strumienia (pliku lub STDOUT). Możesz dodać wiele handlerów do jednego loggera — np. plik + Slack.
Ćwiczenie
Zainstaluj monolog/monolog przez composer require. Napisz skrypt logs.php, który tworzy logger z kanałem 'kurs', dodaje StreamHandler do pliku kurs.log na poziomie DEBUG i loguje: jedno info ('Aplikacja uruchomiona'), jedno warning ('Niska pamięć') i jeden error ('Baza danych niedostępna'). Uruchom skrypt i sprawdź zawartość kurs.log.
Pokaż rozwiązanie
# W terminalu:
composer require monolog/monolog
<?php
// logs.php
declare(strict_types=1);
require 'vendor/autoload.php';
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Level;
$log = new Logger('kurs');
$log->pushHandler(new StreamHandler('kurs.log', Level::Debug));
$log->info('Aplikacja uruchomiona');
$log->warning('Niska pamięć');
$log->error('Baza danych niedostępna');
// W terminalu:
php logs.php
cat kurs.log