Autor: Tomasz Jędrzejewski
Data publikacji: 12.12.2003, 13:31 | Ostatnia modyfikacja: 02.11.2006, 16:13
phpDocumentor jest jednym z najbardziej użytecznych skryptów, które powinien mieć każdy programista PHP. Pozwala bowiem na błyskawiczne utworzenie dokumentacji istniejącego kodu źródłowego. Ten artykuł pokazuje, jak go używać.
Zapewne niektórzy pamiętają jeszcze mój wcześniejszy artykuł pt. "Manual - jak wykonać?". Omawiał on sposób napisania "aplikacji" pozwalającej stworzyć nam projekt kodu źródłowego. Dość dobrze nadawała się ona do tworzenia rozmaitych dokumentacji jeszcze przed przystąpieniem do właściwych prac. Ale po zakończeniu głównych robót nad kodem przydałoby się coś znacznie potężniejszego i generującego przyjaźniejsze dokumentacje. Tu z pomocą przychodzi znakomity skrypt phpDocumentor, służący właśnie do tworzenia dokumentacji na bazie istniejącego już kodu PHP.
Zacznijmy od wyjaśnienia, czym phpDocumentor jest, a czym nie jest. Kwestia najważniejsza - nie jest on edytorem, a parserem. Oznacza to, że wpierw musimy coś mieć, aby on mógł to przetworzyć. Kwestia druga - do działania potrzebuje już napisanego kodu źródłowego. Dlaczego? Ano ponieważ jest on taki sprytny, że przegląda i z niego wyciąga informacje o wszystkich funkcjach/klasach/stałych/metodach/polach/Bóg_wie_co należących do projektu. Stamtąd też bierze... opisy do nich. W praktyce wszystko sprowadza się do umieszczenia nad przykładową funkcją odpowiednio napisanego komentarza, a phpDocumentor zamieni nam go ładnie na jej opis :). To jeszcze nie wszystko. Autorzy, wychodząc z założenia, że dokumentacje powinny być jak najbardziej przyjazne czytelnikowi, udostępnili nam wiele gotowych szablonów wyglądu. Możemy więc naszą dokumentację upodobnić do manuala PHP, albo też do DOMopodobnego widoku w ramkach a'la Windows XP. A gdy mamy multum fantazji, mamy możliwość pokuszenia się nawet o wygenerowanie wersji... PDF i CHM (do tego drugiego potrzebny jest jeszcze specjalny program, bowiem phpDocumentor generuje tylko wszystkie niezbędne mu dane)! Osoby znające aplikację XML'ową DocBook też się pewnie ucieszą na wieść o tym, że do dokumentacji można dołączyć rozmaite teksty w tym formacie.
Z tego, co jest powyżej, wynika, że phpDocumentor to cudo nad cudami plus coś jeszcze. Ale niestety nic nie jest tak różowe. Autorzy nie pomyśleli o tym, że są na świecie inne języki i bez bawienia się kodami szablonów raczej nie ujrzymy poza opisami naszego kochanego polskiego. Inna sprawa jest taka, że skrypt na razie nie potrafi rozpoznawać rozmaitych dodatków w OOP z PHP 5 (również nie da się go na nim uruchomić, więc dobrze mieć w zanadrzu "czwórkę"), ale z tym jakoś da się żyć.
Instalacja całości jest stosunkowo prosta. Wchodzimy na http://phpdoc.org, pobieramy stamtąd najnowszą wersję (ja opisuję w tym tekście wersję 1.2.3) i kopiujemy pliki do jakiegoś katalogu na serwerze. I w zasadzie tyle. Instalacji phpDocumentora dla PEAR opisywać nie będę z dwóch powodów: raz, że samemu mi się to nie udało, a dwa - po co, skoro mamy interfejs WWW :).
Aby uruchomić interfejs WWW, należy wpisać w przeglądarkę "http://twojserver.nrd/sciezka/do/phpdocumentor/index.html". Jak widać, ekran jest podzielony na dwie części - górną, z konfiguracją i dolną z oknem informacyjnym. Pokazują się w nim wszystkie dane dotyczące przebiegu kompilacji. Na razie jednak nic kompilować nie będziemy, gdyż nie wiemy, jak pisać kod źródłowy, by coś sensownego otrzymać. Na razie twoim zadaniem jest tylko oswoić się z widokiem, by później wiedzieć, co gdzie jest.
Jak wspomniałem, główna część procesu tworzenia dokumentacji odbywa się na kodzie źródłowym w PHP. Otwórz więc jakiś edytor, po czym załaduj jakikolwiek plik projektu. Najważniejsze, co musisz znać, to budowa komentarza, który ma zostać zinterpretowany jako opis. Wygląda on tak:
/**
* opis opis opis
* opis opis opis
*/
Oczywiście to nie wszystko, bo byłoby to za proste :). Aby został on zinterpretowany jako komentarz z opisem, musi znajdować się nad fragmentem kodu, który phpDocumentor potrafi opisać. Może więc to być deklaracja klasy, pola, stałej, funkcji, czy też początek pliku. Ilustruje to ten przykład:
<?php /** * Ten opis dotyczy pliku, który edytujesz! */ /** * Ten opis dotyczy deklaracji stałej */ define('STAŁA', 3.1415926535897932384626433832795028841951); /** * Ten opis dotyczy deklaracji funkcji */ function meine_function(){ echo 'Jam jest funkcja'; } /** * Ten opis dotyczy klasy */ class meine_klass{ /** * Ten opis dotyczy pola klasy */ var $pole; /** * ten opis dotyczy metody klasy */ function meine_method(){ echo 'Jam jest metoda'; } } ?>
Opisy możemy uzupełniać różnymi informacjami dla parsera, jak poszczególne ich elementy mają być zinterpretowane. Oto przykład pokazujący wykonanie krótkiego i rozbudowanego opisu funkcji (pierwszy pojawi się przy jej nazwie na liście funkcji, jak w manualu PHP, a drugi będzie dokładnym opisem).
/**
* To jest krótki opis
*
* A tu mamy bardzo długi opis wyjaśniający
* jak używać tego całego bajeru.
*/
Opisy możemy także formatować:
/**
* To jest krótki opis
*
* A tu mamy bardzo długi opis wyjaśniający
* jak używać tego całego bajeru. Możemy <b>wyróżnić</b>
* jakiś jego fragment, który jest ważny przy objaśnianiu
* dołączonego <code><?php echo 'kodu źródłowego'; ?></code>
* mogącego służyć za przykład.
*/
Szczegółowy opis wszystkich dostępnych tagów znajduje się pod tym adresem. W ogóle polecam korzystać z dokumentacji phpDocumentora, gdyż nie wszystko jestem w stanie opisać w tym artykule :).
Bardzo ważną rzeczą jest zrozumienie, jak phpDocumentor grupuje pliki, klasy, funkcje itp. Wiadomo, że nie zaindeksuje wszystkiego, jak leci, bo co byłoby, gdyby cały kod podzielony był na parę części, np. jądro, bazy danych, dodatkowe biblioteki i każda z nich powinna być analizowana całkowicie oddzielnie? Owszem - można wygenerować dla każdego elementu osobną dokumentację, ale to nie ma sensu, ponieważ phpDocumentor umożliwia podzielenie kodu na tzw. pakiety, stojące jeszcze wyżej w hierarchii, niż pliki (aczkolwiek jeden plik może zawierać zawartość kilku pakietów). Jak oznaczyć, co należy do jakiego pakietu? Zanim przejdę do tego, przydałoby się wyjaśnić, czym są tagi. Popatrz na poniższy przykład:
/**
* Krótki opis
*
* Tekst tekst tekst
* tekst tekst tekst
*
* @package pakiet
*/
Przyjrzyj się uważnie przedostatniej linijce (tej ze znaczkiem małpy) - to jest właśnie tag. Na początku określona jest nazwa tagu, a następnie jego wartość. W tym przypadku użyłem tagu @package do określenia, że coś, co dokumentuję, należy do pakietu "pakiet". Pamiętaj, że nie musisz ustawiać tego tagu dla wszystkich elementów. Przykładowo: ustawienie, że dana klasa należy do pakietu "jądro" spowoduje, że wszystkie jej metody i pola również zostaną do niego włączone.
Tagów jest o wiele więcej, w dodatku w opisie możemy użyć dowolnej ich ilości. Oto lista niektórych tagów, które mogą ci się bardzo przydać (więcej znajdziesz w dokumentacji skryptu):
/**
* Lista użytecznych tagów
*
* @access public
* @author Tomasz Jędrzejewski <zyxwvu@users.sourceforge.net>
* @license docs/gnu-gpl.txt
* @version 123.45
* @copyright Tomasz Jędrzejewski 2003
* @ignore
* @example examples/przyklad1.php Ten przykład demonstruje jakieś ważne zagadnienie
* @example examples/przyklad2.php Jeszcze jeden przykład
* @param string $nazwa, array $tablica
* @return mixed
* @todo Tu jest jeszcze coś do zrobienia
*/
@access określa dostęp do metody/funkcji/pola. Wiadomo, że część funkcji kodu przeznaczona jest wyłącznie na użytek innych funkcji i nie powinny być one używane przez programistę. Wtedy możemy ustawić ten tag na "private", by poinformować o tym czytelnika. Tag @author pozwala nam określić autora danego elementu, natomiast @license ścieżkę do tekstu licencji, na zasadach której skrypt jest dystrybuowany. @version będzie nam użyteczne przy określaniu numeru wersji danego elementu, a @copyright zaznaczy nasze prawa autorskie. Jeśli w skrypcie pojawiają się dwa elementy o tej samej nazwie, możemy użyć tagu @ignore, by oznaczyć, który z nich ma nie być brany pod uwagę przez parser. Za pomocą tagu @example możesz podać ścieżkę do pliku zawierającego przykładowe użycie funkcji (wraz z dołączonym komentarzem). Nie musisz podawać całej ścieżki, gdyż tę ustawisz w opcjach kompilacji. Wiadomo, że w PHP nie możemy określić typów danych wprowadzanych do funkcji, ani zwracanych danych. Tu pomogą nam tagi @param i @return. Dadzą one kompilatorowi wiadomości o żądanych typach. Tylko uwaga: nazwy zmiennych w tagu @param muszą pokrywać się z tymi w deklaracji funkcji/metody! Ostatnim tagiem jest @todo, który pozwala nam określić, co należy jeszcze dodać do tego elementu, by był w pełni sprawny.
Istnieją także tagi, które mogą być dodawane bezpośrednio do opisu elementu, ale nimi zajmiemy się w dalszej części rozdziału.
Teraz, gdy wiesz, jak dokumentować kod źródłowy, przydałoby się wiedzieć, co należy zrobić, by phpDocumentor przerobił go na dokumentację. Włącz więc interfejs WWW i przejdź do zakładki "Files" (jeśli pojawi się puste okienko, przełącz się na jakąś inną i z powrotem spróbuj wrócić do "Files"). W okienku "Directories to parse" wprowadź dwie ścieżki oddzielone przecinkiem: pierwszą do właściwego kodu źródłowego, a drugą do katalogu z przykładami. Następnie w polu poniżej ("Files to ignore") wpisz ścieżkę do katalogu z przykładami zakończoną na "\*". Dzięki temu phpDocumentor nie zdurnieje i nie włączy nam do kompilacji przykładów jako części kodu źródłowego projektu :). Teraz przjedź do zakładki "Output" i wybierz, jaki wygląd będzie miała dokumentacja. Możesz ustawić generowanie dokumentacji w kilku różnych layoutach za jednym razem. Na końcu pozostaje nam już zakładka "Options" i tam ustawisz już różne pomniejsze szczegóły typu tytuł dokumentacji, czy domyślny pakiet. Zwróć uwagę na zakładkę "Custom tags" - możesz do niej dopisać własne tagi, które zawarłeś w opisach kodu źródłowego. Ja np. u siebie stworzyłem tag "call" określający sposób wywołania danej metody, gdyż jest to dość pokrętne :).
Ustawianie opcji dobiega ku końcowi. Musisz jeszcze ustawić "Working directory" (poniżej, na niebieskim tle), czyli katalog, do którego wygenerujesz dokumentację. Po jego ustawieniu pozostaje ci tylko wcisnąć przycisk "Create" i czekać, aż w okienku diagnostycznym pojawi się komunikat "Operation completed". Jeżeli on się nie pojawi, przeanalizuj cały log kompilacji i popraw to, co jest źle.
Z pewnością zauważyłeś, że każdorazowe ręczne wpisywanie wszystkich tych opcji jest nieco męczące. Na szczęście zauważyli to autorzy phpDocumentora i dali nam możliwość napisania plików z konfiguracją. Składnia poleceń jest dokładnie taka sama, jak w pliku php.ini (nic dziwnego, w końcu są przetwarzane przez ten sam parser :)). Oto, jak powinien wyglądać taki plik:
[Parse Data] ;; Jeśli czegoś nie chcesz ustawiać, poprzedź to średnikiem, by nie było ;; interpretowane przez parser. ;; tytuł dokumentacji title = Moja dokumentacja ;; Czy parsować pliki zaczynające się od kropki, np. .bash_profile, .htaccess ;; wartości: true, false hidden = false ;; Czy pokazywać elementy prywatne (@access private)? ;; Jeśli chcesz stworzyć dokumentację dla końcowych ;; użytkowników, a nie dla developerów projektu, ustaw to na off ;; wartości: on, off parseprivate = on ;; Twoje własne tagi ;; wartości: jakiekolwiek nazwy oddzielone przecinkami (bez małpy) customtags = call ;; Jaki jest główny pakiet projektu? ;; akceptowane wartości: liczby, cyfry, podkreślenie (_) i pauza (-). defaultpackagename = pakiet1 ;; Czy NIE wyświetlać informacje o postępie kompilacji? ;; Wartości: on, off quiet = off ;; Gdzie powinna być zapisana gotowa dokumentacja? target = c:\dokumentacje\moja1 ;; Pakiety, które MUSZĄ być włączone. Jeśli nie ustawisz tego pola, ;; phpDocumentor uwzględni wszystkie pakiety z kodu ;; źródłowego packageoutput = package1,package2 ;; Pliki do włączenia do dokumentacji oddzielone przecinkami. ;filename = /path/to/file1,/path/to/file2,fileincurrentdirectory ;; Katalogi z kodem źródłowym/przykładami/czymkolwiek oddzielone przecinkami directory = c:\usr\www\mojprojekt,c:\dokumentacje\przyklady ;; Katalogi/pliki do ignorowania, oddzielone przecinkami ignore = c:\dokumentacje\przyklady\* ;; lista layoutów dokumentacji, oddzielona przecinkami. ;; wartosci: HTML:frames:default,HTML:frames:l0l33t, ;; HTML:frames:phpdoc.de,HTML:frames:phphtmllib ;; HTML:frames:DOM/default,HTML:frames:DOM/l0l33t, ;; HTML:frames:DOM/phpdoc.de,HTML:Smarty:default ;; HTML:Smarty:PHP,HTML:Smarty:HandS, ;; PDF:default:default,CHM:default:default, ;; XML:DocBook/peardoc2:default output=HTML:frames:phpdoc.de,PDF:default:default
Przed zapisaniem utwórz katalog, gdzie będziesz trzymał dodatkowe informacje dla kompilatora (bowiem potrafi on znacznie więcej, niż tylko przeglądać kod źródłowy) i w nim zapisz ten plik. A jak go załadować? W interfejsie WWW w zakładce "Config" w "Change config directory" wpisujesz nazwę katalogu, w którym zapisałeś plik konfiguracyjny. Po kliknięciu na przycisk "Change", z poniższej listy wybierz twój plik i kliknij na "Go", a proces kompilacji zostanie rozpoczęty.
Zapewne zauważyłeś, że sama lista funkcji i metod jest niezbyt przyjazna użytkownikowi, gdy nie wie on, jak tego wszystkiego używać w praktyce. phpDocumentor ma i na to lekarstwo, bowiem pozwala na dołączanie do niej tutoriali korzystających z aplikacji XML o nazwie DocBook.
Pierwsze, co należy ci o tym wiedzieć to to, że phpDocumentor pozwala na tworzenie tutoriali do trzech typów elementów: pakietów (wtedy pliki tutoriala mają nazwę "nazwapakietu.pkg"), klas (nazwa "nazwaklasy.cls"), oraz plików ("nazwapliku.php.proc"). Ponadto wszystko to musi leżec w specjalnej strukturze katalogów. Na początku dopisz do pliku konfiguracyjnego do dyrektywy "directory" nową ścieżkę, tym razem wskazującą na tutoriale. W niej musisz utworzyć osobne katalogi dla każdego pakietu. Wszystkie pliki *.pkg, *.cls i *.proc muszą znaleźć się w katalogu odpowiadającym pakietowi, do którego zostały przypisane.
Teraz przyszedł czas na sam dokument. DocBook dostarcza różnych zestawów znaczników w zależności od tego, CO chcemy napisać. Mamy więc możliwość napisania pojedynczego rozdziału, artykułu, ale także całej książki :). Oczywiście słowo "książka" jest tutaj przysłowiowe, bo nie sądzę, by komuś chciało się przez 300 stron nawijać o jednym; wszak strukturę do budowy książki można wykorzystać do skonstruowania bardziej złożonego artykułu. Poniżej zamieściłem przykłady każdego z tych elementów wraz z opisem. Na początek artykuł.
<?xml version="1.0" encoding="ISO-8859-2" ?> <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V3.1//EN"> <article> <artheader> <title>Mój artykuł</title> <!-- tak możemy oznaczyć autora --> <author><honorific>Doktor ReHabilitowany</honorific> <firstname>Ferdynand</firstname><surname>Kiepski</surname></author> </artheader> <para>Tutaj treść jakiegoś paragrafu</para> <sect1><title>Tytuł sekcji 1</title> <para>Paragraf pierwszy sekcji 1</para> <sect2><title>Tytuł sekcji 2</title> <para>Paragraf pierwszy sekcji 2</para> <!-- i tak możemy zagłębiać sobie do znacznika "sect5" --> </sect2> <para>Paragraf drugi sekcji 1</para> </sect1> <para>Treść jakiegos paragrafu</para> </article>
Rozdział:
<?xml version="1.0" encoding="ISO-8859-2" ?> <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook V3.1//EN"> <chapter><title>Tytuł rozdziału</title> <para> treść paragrafu </para> <sect1><title>Sekcja 1</title> <para>Z sekcjami jest tu tak samo, jak w przypadku artykułu</para> <example> <title>Tytuł przykładu</title> <programlisting><![CDATA[<?php echo 'Jakiś przykład'; ?>]]></programlisting> </example> </sect1> </chapter>
Książka:
<?xml version="1.0" encoding="ISO-8859-2" ?> <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN"> <book> <bookinfo> <title>Moja pierwsza książka</title> <author> <firstname>Tomasz</firstname> <surname>Jędrzejewski</surname> </author> <copyright> <year>20031998</year> <holder>Tomasz Jędrzejewski</holder> </copyright> </bookinfo> <preface> <title>Tytuł przedmowy</title> <para>Treść przedmowy w paru paragrafach</para> </preface> <!-- tutaj rozdziały, konstruowane tak samo, jak w poprzednim przykładzie --> <chapter> ... </chapter> <chapter> ... </chapter> <chapter> ... </chapter> <!-- a tu są dodatki --> <appendix><title>Dodatek Ą</title> <para>treść dodatku</para> </appendix> <appendix><title>Dodatek Ę</title> <para>treść dodatku</para> </appendix> </book>
Oczywiście to nie wszystko, gdyż DocBook daje nam co najmniej 15 razy więcej przydatnych znaczników. Ich bardzo dobry opis znajdziesz w dokumentacji do niego, którą możesz pobrać ze strony http://docbook.org/.
Teraz omówię taką sytuację. Do pakietu chcesz wrzucić 5 tutoriali, ale jak? Przecież nie da się stworzyć w jednym katalogu pięciu tak samo nazywających się plików (no chyba jak ktoś napisze odpowiedni system plików, to się będzie dało :)). Autorzy phpDocumentora pomyśleli i o tym, dając nam możliwość wprowadzenia informacji o plikach, które też mają być dołączone. Robi się to prosto. W katalogu z pakietem umieszczasz plik "nazwapakietu.pkg.ini" z treścią:
[Linked tutorials] tutorial1 tutorial2 tutorial3 tutorial4 tutorial5
Wszystkie te "tutorialx" są oczywiście nazwami plików tutoriali, tyle że bez rozszerzeń. Zostana one włączone do dokumentacji w takiej kolejności, w jakiej je podałeś.
I tak oto szczęśliwie dobrnęliśmy do końca tego artykułu. Mam nadzieję, że zainteresowałem Cię tematem dokumentowania kodu przy pomocy phpDocumentora i DocBooka i że będziesz dalej poszerzał o nich swą wiedzę. Przypomnę tylko tradycyjnie przydatne adresy:
Autor: Tomasz "Zyx" Jędrzejewski, www.zyxist.com
Waszym zdaniem:
Nikt jeszcze nie dodał swojego komentarza. Możesz być pierwszy!