Composer w PHP
Zarządzanie bibliotekami, ich zależnościami i wersjami to problem, na który napotkało w swej historii wiele technologii i języków programowania. Świat PHP w przeszłości również cierpiał z powodu trudności w zarządzaniu i rozpowszechnianiu bibliotek. Sprawdź, jak obecnie radzić sobie z zarządzaniem pakietami w aplikacji PHP przy użyciu menadżera zależności Composer.
Do czasu kiedy w PHP brakowało menadżera zależności programiści często zajmowali się tzw. wymyślaniem koła na nowo. Zamiast użycia istniejących już rozwiązań, decydowali się na własne implementacje pewnych funkcjonalności. W innych przypadkach używane oprogramowanie często nie było aktualizowane (pakiety stawały się mało bezpieczne) lub po prostu zebranie wszystkich zależnych bioblotek generowało wiele trudności i kosztowało sporo czasu.
Po latach marazmu na tym polu - idąc w ślady takich rozwiązań jak bundler dla języka ruby, czy npm dla node.js, czy wiele innych - także w PHP zdecydowano się na rozwój aplikacji, która pozwala swobodnie nimi zarządzać.
Odpowiedzią na te problemy był Composer - manager pakietów, dobrze znany wśród społeczności programistów PHP, a który zamierzam przybliżyć w niniejszym artykule szczególnie dla tych, którzy nie mieli jeszcze okazji z nim pracować.
Co to jest Composer
W najprostszych słowach Composer to nic innego jak aplikacja uruchamiana z wiersza poleceń (tzw. CLI - Command Line Interface), napisana w języku PHP. Przeznaczona jest do zarządzania bibliotekami i skryptami dla tegoż języka. Pierwsze prace nad jego powstaniem zaczęto w 2011 i po niecałym roku udało się je sfinalizować, wypuszczając pierwsze oficjalne wydanie w wersji alpha1 (03.2012). Obecna wersja stabilna to 2.0.7, wydana w listopadzie 2020.
Kiedy z niego skorzystać
Biorąc pod uwagę moje doświadczenie we współpracy z programistami Drupala w Droptica oraz developerami PHP, wiem, że istnieje tylko jeden przypadek, kiedy tak naprawdę nie istnieje potrzeba, żeby korzystać z Composera - wtedy, kiedy nie mamy ani jednej zależności do żadnej biblioteki.
Oczywiście w dzisiejszych czasach ciężko wyobrazić sobie taki projekt, który w żadnym stopniu nie skorzystałby z osiągnięć innych programistów i implementował poszczególną funkcjonalność od zera. W związku z powyższym, a także ze względu na łatwość używania i instalacji, z Composera warto korzystać w każdej sytuacji. Daje on w łatwy sposób możliwość pobrania, zaktualizowania, czy rozwiązania zależności dla potrzebnej do naszego projektu biblioteki.
Jak zainstalować
Instalacja Composera jest względnie prosta pod warunkiem, że posiadamy w swoim systemie (lub w odpowiednim kontenerze, jeśli korzystamy np. z rozwiązań typu Docker) zainstalowany PHP w wersji minimum 5.3.2. Oczywiście sam proces jest zróżnicowany w zależności od używanego systemu operacyjnego. Szczegółowa instalacja znajduje się na oficjalnej stronie.
Dla systemu Windows najprostszym rozwiązaniem jest pobrać i uruchomić plik Composer-Setup.exe, a następnie przejść cały proceś instalacyjny. Z kolei dla systemów Linux / Unix / macOS instalacja odbywa się w kilku krokach. Najpierw pobieramy i weryfikujemy plik .phar (PHP Archive):
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
Należy pamiętać, że porównywany hash zmienia się z każdą wydaną wersją, dlatego zawsze należy go porównać z wartością publikowaną na oficjlanej stronie zawierającej sumy kontrolne.
Następnie uruchamiamy instalację, w wersji podstawowej - lokalnie
php composer-setup.php
lub do globalnego użytku.
php composer-setup.php --install-dir=/usr/local/bin --filename=composer
W ostatnim kroku usuwamy niepotrzebny plik instalacyjny.
php -r "unlink('composer-setup.php');"
Świetnie, teraz możemy w pełni cieszyć się możliwościami Composer'a w naszym systemie.
Jak używać
Composer, jak wiele tego typu aplikacji, oferuje szereg funkcjonalności, których przytaczanie w ramach tego artykuły nie miałoby sensu (więcej szczegółowych informacji można znaleźć w oficjalnej dokumentacji). Chciałbym natomiast przedstawić tu kilka komend najbardziej przydatnych w codziennej pracy dewelopera.
Inicjalizacja projektu
composer init
Z pomocą tej komendy inicjalizujemy nowy projekt korzystający z Composera. Po jej wykonaniu tworzy nam się plik composer.json, w którym przechowywane są wszystkie nasze dane dotyczące projektu, takie jak nazwa projektu, dane o autorze i co najważniejsze wszystkie biblioteki przez niego używane.
Instalacja istniejącego projektu
Jeżeli posiadamy już jakiś istniejący projekt (np. sklonowaliśmy jakieś istniejące repozytorium), to zazwyczaj wystarcza nam jedna komenda do zainstalowania wszystkich tych samych pakietów, które ktoś opublikował dla swojej aplikacji (lista zainstalowanych wersji pakietów zapisywana jest w pliku composer.lock)
composer install
Dodawanie, usuwanie i aktualizacja biblioteki
Schemat wszystkich tych komend pozostaje ten sam. Zmienia się w zasadzie słowo kluczowe dla danej operacji:
- require - do dodania,
- remove - do usunięcia,
- update - do aktualizacji pakietu.
Aby np. dodać nową bibliotekę jako zależność do naszego projektu (w tle rozwiązywane są także zależności dla pobieranej przez nas biblioteki), wystarczy użyć komendy require:
composer require <vendor name>/<project name>
przykładowa komenda do aktualizacji rdzenia Drupala wyglądałaby więc następująco:
composer update drupal/core
Dla przykładu: załóżmy scenariusz, w którym tworzymy aplikację do generowania faktur w postaci plików .pdf, które potem wysyłane są na maila. Oczywiście nie chcemy pisać wszystkiego od zera, tylko łatwo dołączyć potrzebne nam biblioteki, a zatem użyjemy Composera. Jako pierwszą skompletujemy sobie bibliotekę do PDF np. dompdf:
composer require dompdf/dompdf
Gotowe! Powyższa komenda zainstaluje do naszego projektu najnowszą wersję tej biblioteki, bez żadnej dodatkowej interakcji z naszej strony. Czas teraz na obsługę wysyłki wiadomości e-mail. Tu również skorzystamy z gotowego rozwiązania - PHPMailer. Zanim tego dokonamy, przyjmijmy, że z jakiegoś powodu mamy złe doświadczenie w pracy z tą biblioteką w najnowszej wersji 6, ale za to pracowaliśmy bardzo dużo z wersją 5. Z Composer nie ma żadnego problemu - dołączamy to czego potrzebujemy, definiując konkretną wersję główną:
composer require phpmailer/phpmailer:"^5"
Składania Composera pozwala na różnorodne oznaczenie potrzebnych wersji. Mogą to być zarówno wersje minimalne, można wskazać na konkretny branch np. dev-develop, na branch develop w danej bibliotece. Można też określić konkretną wersję np. 5.2.28 w celu pobrania konkretnie tej np. dobrze przetestowanej i działającej wersji.
Po wykonaniu powyższych komend utworzony zostanie katalog vendor zawierający pobrane biblioteki wraz z ich zależnościami:
Odpowiednio zaktualizowany zostanie także plik composer.json oraz wygenerowany zostanie plik composer.lock. Finalna struktura w katalogu projektu prezentuje się następująco:
Jak sami widzicie, dysponując zestawem kilku komend, możemy w zasadzie z powodzeniem rozpocząć pracę nad dowolnym projektem i w większości wypadków nie będzie nam nic więcej potrzebne, a cała magia wykonana jest za nas w tle.
Co zyskujemy
Composer to przede wszystkim kompleksowe narzędzie używane powszechnie w projektach PHP, przy czym sam napisany jest również w PHP. To ogromny atut, gdyż każdy potencjalny programista dołączający do twojego zespołu lub firma, z którą zamierzasz współpracować z pewnością się z nim zetknęli i z niego korzystają. Prosty instalator i samo uruchomienie podstawowych komend zachęca wręcz do użycia go od samego początku przy pracy nad dowolnym projektem.
Dodatkowo łatwość z jaką możemy zainstalować dowolną bibliotekę PHP, mając jednocześnie wpływ na jej wersję, czy możliwości aktualizacji, pozwala na znaczne oszczędności czasu programistów i dostępnych zasobów. Z pomocą pakietów takich jak sensiolabs/security-checker możemy także samodzielnie sprawdzić dostępne aktualizacje bezpieczeństwa, podnosząc bezpieczeństwo własnej aplikacji. W naszej pracy to codzienność, zwłaszcza w przypadku gdy np. zapewniamy ciągły monitoring stron opartych na Drupalu możliwość szybkiej aktualizacji z użyciem Composera jest niezastąpione, a sam proces jest szybki i efektywny.
Podsumowanie
Jako doświadczony developer nie wyobrażam sobie codziennej pracy bez użycia Composera. Narzędzia typu manadżer zależności czy pakietów są powszechnością w wielu technologiach, w tym w PHP. Mnogość zalet, takich jak oszczędność czasu, łatwość użycia, czy prosta kontrola nad zależnościami sprawia, że mogę w swojej pracy być bardziej efektywny. Jeśli Ty także chcesz skupić się wyłącznie na rozwoju kodu własnej aplikacji, a jednocześnie nadążać za powszechnie stosowanymi standardami, to nie zwlekaj i użyj Composer'a. Przecież to banalnie proste.