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 — zależność zależności: Monolog wymaga pakietu 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",
            ...
        }
    ]
}
⚠️ Commituj composer.lock: Plik 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?

Co gwarantuje plik composer.lock w projekcie zespołowym?

Jak skonfigurować kanał i handler w Monologu, żeby logi trafiały do pliku app.log?

Ć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