2006.04_Programowanie obiektowe w PHP na przykładzie IRCBota_[Programy].pdf

(841 KB) Pobierz
440355768 UNPDF
Początki
Programowanie obiektowe
w PHP na przykładzie IRCBota
Marcin Staniszczak
Stopień trudności: l ll
Pewnie słyszałeś już termin programowanie
obiektowe i ktoś przedstawiał Ci jego zalety.
Dobrze, ale jak je zastosować w PHP? Wraz
z wersją PHP5 pojawiło się wiele nowych
funkcjonalności, które możesz wykorzystać
w swoich aplikacjach: pokażemy Ci, jak to
zrobić, tworząc prostą, ale użyteczną aplikację
sieciową...
maliśmy w końcu możliwość
pisania programów obiekto-
wych z prawdziwego zdarzenia. Co wię-
cej, ta wersja PHP jest oferowana przez
coraz większą liczbę providerów, co za-
chęca coraz większą liczbę programistów
do korzystania z niej w swoich projektach.
Warto jednak pamiętać, że progra-
mowanie obiektowe wiąże się ze zmia-
ną sposobu myślenia o aplikacji. Teraz
w mniejszym stopniu myślimy o funkcjach
(zwanych w klasach metodami ), czyli ze-
stawie instrukcji do wykonania konkret-
nych zadań, a w coraz większym o obiek-
tach modelujących tworzony system.
którzy ich nie czytali, przybliżamy w skró-
cie ideę obiektowości. Jej podstawą jest
obiekt – odrębny, zamknięty fragment ko-
du, zawierający metody (czyli funkcje) mo-
gące przeprowadzić określone czynności
oraz pola (czyli zmienne) zwane też atry-
butami lub cechami, które przechowują
dane (np. łańcuchowe, liczbowe czy in-
ne obiekty). To, że obiekt jest zamknięty,
uniemożliwia przypadkowe interakcje je-
go metod i pól z innymi elementami pro-
gramu (np. innymi obiektami), pozwalając
jednocześnie wykorzystać obiekt w dowol-
nym miejscu aplikacji (dając tym samym
W SIECI
l http://www.faqs.org/rfcs/
rfc2812.html – RFC 2812
opisujące IRC
l http://www.cybernexus.biz/
irc/default.htm – informacje o
IRC w przystępnej formie
l http://www.phppatterns.com
– strona o programowaniu
obiektowym i wzorcach pro-
jektowych w PHP
l http://www.php.net/manual/
en/language.oop5.php – oi-
cjalny manual PHP, rozdział
nt. obiektowości w PHP5
l http://en.wikipedia.org/wiki/
Anti-pattern – antywzorce,
czyli jak NIE należy progra-
mować
Co należy wiedzieć...
Należy znać podstawy programowania
w PHP. Przydatna będzie również znajo-
mość protokołu i usług IRC.
Czym jest programowanie
obiektowe?
O programowaniu obiektowym już pisali-
śmy na naszych łamach, choćby w arty-
kułach Erika Zoltana „Po co nam PHP5”,
„Medoty magiczne w PHP5”, zamiesz-
czonych w numerze 5/2005. Tym z Was,
Co obiecujemy...
Pokażemy, jak stworzyć bota IRC-owe-
go, kładąc szczególny nacisk na demon-
strację możliwości obiektowych PHP5.
14
www.phpsolmag.org
PHP Solutions Nr 4/2006
W raz z nadejściem PHP5 otrzy-
440355768.012.png
 
440355768.013.png 440355768.014.png 440355768.001.png 440355768.002.png
 
IRCBot – programowanie obiektowe
Początki
dużą elastyczność) i nazywa się enkapsu-
lacja , którą omówimy później.
Każdy obiekt należy do jakiejś klasy
i jest jej instancją (czyli egzemplarzem),
przykładowo obiekt lampkaPrzyMoimŁóżku
może należeć do klasy lampkaNocna . Sko-
jarzenia ze światem materialnym nasuwa-
ją się same: dzięki obiektom łatwo zasy-
mulujemy przedmioty i zjawiska występu-
jące w naszej rzeczywistości. Modelowa-
nie rzeczywistości zaczynamy od wdraża-
nia głównych cech, a następnie przecho-
dzimy do kolejnych detali.
Kontynuujmy nasz przykład z lampką
nocną. Możemy utworzyć klasę o nazwie
lampkaNocna , która będzie zawierała me-
tody zgaś() i zapal() . Pominiemy mniej
istotne szczegóły, takie jak np. kolor czy
kształt obudowy lampki. Następnie, chcąc
umieścić lampkę nocną w naszym progra-
mie, po prostu utworzymy instancję klasy
lampkaNocna .
Co jednak będzie, jeżeli zechcemy za-
symulować również lampę biurową, lam-
pę wiszącą czy latarnię uliczną? Czy bę-
dziemy za każdym razem tworzyć no-
wą klasę od podstaw (np. lampaWisząca
i latarniaUliczna )? Mijałoby się to z sen-
sem, gdyż:
Rysunek 1. Klasa lampka i jej klasy pochodne
wystąpią we wszystkich klasach pochod-
nych. W przypadku lampy będą to metody
zapal() oraz zgaś() . Moglibyśmy dodać
do niej również pole żarówka , ale co zrobić
z lampami, które zawierają np. świetlów-
kę? Rozsądnym wyjściem byłoby utworze-
nie drugiej klasy, np. źródłoŚwiatła , z któ-
rej będzie korzystać klasa lampka i która
również będzie posiadała klasy pochodne.
Dodane właśnie metody zapal()
i zgaś() istnieją wewnątrz klasy lampka .
Inna, całkowicie odrębna klasa, np.
znicz , mogłaby mieć metody o takich
samych nazwach i nie kolidowałyby one
w żaden sposób z metodami lampki. To
samo dotyczy pól. Dostęp do nich jest
możliwy jedynie przy podaniu nazwy kla-
sy (lub jej obiektu), w której zostały zde-
iniowane. To jest właśnie enkapsulacja
(lub hermetyzacja ): zamknięcie metod
i pól wewnątrz klasy. Bardzo ułatwia ona
tworzenie oprogramowania, szczegól-
nie dużych projektów (wystarczy sobie
wyobrazić jakikolwiek interfejs graicz-
ny, w którym najmniejszy przycisk ma kil-
kadziesiąt własnych cech i funkcji) i jest
jedną z najmocniejszych zalet programo-
wania obiektowego.
Teraz bazując na klasie lampka mo-
żemy utworzyć klasy pochodne (dziedzi-
czące): lampkaNocna oraz lampkaBiurowa .
Zwróćmy uwagę, jak bardzo jest to wy-
godne. Możemy teraz zasymulować jed-
nego człowieka (klasa człowiek ) potra-
iącego obsługiwać wszystkie utworzone
przez nas lampki. Co więcej, podczas pi-
sania klasy człowiek nie musimy nawet
wiedzieć, jakie lampki będzie on obsługi-
wał, ani ile ich będzie. Istotne jest tylko,
aby dziedziczyły one po klasie lampka .
Niestety, nie jest powiedziane, że
nasz człowiek będzie potraił w pełni wy-
korzystać każdą nową lampkę: klasa po-
chodna może bowiem rozszerzać li-
stę metod i pól o własne, o których nasz
człowiek nie będzie nic wiedział (pamię-
tajmy, że zna on jedynie klasę lampka ).
Zobacz Rysunek 1. Prezentujemy tam
klasy wszystkich lampek włącznie z no-
wą, którą jest klasa LampkaPrzyciemniana ,
symulująca lampkę z regulacją jasno-
ści (sciemniaczem). Obok standardo-
wych metod zapal() oraz zgaś() posia-
da ona także metody rozjaśnij() oraz
sciemnij() . Nasz człowiek potraiący ob-
służyć obiekty klasy lampka , po której
dziedziczy nasza lampkaPrzyciemniana ,
będzie potraił ją zapalić oraz zgasić, ale
nie będzie umiał jej przyciemnić czy rozja-
śnić. Niestety, nie można mieć wszytego.
Istnieją co prawda sposoby obejścia tego
problemu, nie są one jednak tak elastycz-
ne i nie są w pełni zgodne z podejściem
obiektowym.
• część elementów tych klas (jak meto-
dy zgaś() i zapal()) będzie się pokry-
wała,
• jeśli wymodelujesz sobie człowieka
(lub robota) obsługującego lampkę,
będziesz musiał implementować mu
obsługę każdej lampki z osobna.
Lepiej więc byłoby zacząć od utworzenia
bardziej ogólnej klasy lampka , będącej ba-
zą dla wszelkiego rodzaju dziedziczących
po niej lamp, lampek, relektorów, latarń
czy latarek kieszonkowych. Ta podstawo-
wa lampa powinna zawierać wyłącznie
najbardziej ogólne pola i metody: te, które
Programowanie obiektowe – historia i teraźniejszość
Programowanie obiektowe jest już dojrzałą metodologią projektowania oprogramowa-
nia komputerowego. Stworzona już w 1967 roku Simula posiadała pewne cechy języka
obiektowego, zaś w latach 70. ubiegłego wieku Xerox pracował nad językiem Smalltalk
– do dziś niedoścignionego wzorca w dziedzinie obiektowości. Z bardziej znanych, często
stosowanych języków wystarczy wymienić C++ czy Javę. Przed pojawieniem się PHP5,
w PHP było znacznie gorzej: teoretycznie już w PHP4 można było korzystać z pewnych
technik obiektowych, ale było to niewydajne i zawodne. Prawdziwy, rewolucyjny przełom
nastąpił wraz z nadejściem PHP5, która oferuje nowy, solidny silnik obiektowy oraz wie-
le użytecznych cech, których poprzednio brakowało, a które czynią z PHP język obiektowy
z prawdziwego zdarzenia.
PHP Solutions Nr 4/2006
www.phpsolmag.org
15
440355768.003.png
 
440355768.004.png 440355768.005.png 440355768.006.png
Początki
IRCBot – programowanie obiektowe
Podsumowując, najistotniejsze cechy
programowania obiektowego to:
klasy (tego, czy będzie to klasa ba-
zowa, czy określona klasa pochod-
na – można to sprawdzić) czy od ilo-
ści lub typu parametrów (przeciąże-
nie parametrów). Przykładowo, meto-
da zapal() może działać zupełnie ina-
czej w przypadku lampki nocnej z ża-
rówką, niż w przypadku lampy suito-
wej ze świetlówką.
Dziedziczenie – możliwość tworzenia
klas pochodnych opartych o klasę ba-
zową.
Szybki start IRCBota
Jeśli chcesz sprawdzić, jak działa nasz
bot, pobierz jego źródła z naszej strony
WWW. Możesz go uruchomić z linii pole-
ceń lub w przeglądarce internetowej.
Przed uruchomieniem bota musisz
go skonigurować. Ustawienia znajdują
się w pliku Coniguration.class.php . Po-
nadto musisz zmodyikować wpis w pli-
ku admins – zmień tam nicka oraz host,
spod którego będziesz się łączył z ser-
werem IRC (nie dodawaj ręcznie nowych
użytkowników – po zalogowaniu się mo-
żesz nimi zarządzać za pomocą komend
add_admin : oraz remove_admin : – pa-
miętaj o dwukropku).
Aby uruchomić bota z linii poleceń,
przejdź do jego katalogu i wydaj pole-
cenie: php ConsoleBOT.class.php . Pa-
miętaj, że aby to polecenie zadziała-
ło, potrzebujesz odpowiednio ustawio-
nej ścieżki PATH : musi ona wskazywać
na katalog z PHP. Alternatywnie, możesz
podać pełną ścieżkę dostępu do progra-
mu php (lub php.exe pod Windows).
Aby uruchomić bota w przeglądar-
ce internetowej, skopiuj jego pliki do ka-
talogu, do którego ma dostęp twój ser-
wer HTTP (np. Apache lub IIS), a następ-
nie wywołaj w przeglądarce skrypt Web-
BOT.class.php . Po uruchomieniu bota
możesz się do niego zalogować – wyślij
do niego prywatną wiadomość o treści:
login: test . Wszelkie komendy wyda-
wane botowi mają postać: komenda: pa-
rametry oddzielone spacjami. Dwukro-
pek po instrukcji jest wymagany nawet,
gdy nie przyjmuje ona parametrów, np.
disconnect: .
Abstrakcja – oznacza, że każda kla-
sa w programie opisuje pewien model
rzeczywistości, będąc najczęściej swo-
istą abstrakcją obiektów rzeczywistych
(jak nasza lampka ). Dzięki temu progra-
mista może operować bezpośrednio na
modelowanych obiektach, modyiko-
wać oraz poznawać ich aktualny stan.
Enkapsulacja ( hermetyzacja ) – za-
mknięcie metod i pól wewnątrz klasy,
co wyklucza ich ewentualne kolizje z
metodami i polami innych klas. Dzięki
niej każda klasa jest odrębnym bytem.
W połączeniu z możliwością określe-
nia widoczności zmiennych (publicz-
ne, prywatne lub chronione – omówi-
my to później), enkapsulacja stanowi
jedną z najmocniejszych zalet progra-
mowania obiektowego.
Polimorizm – zapewnia możliwość
wykonywania różnych działań przez
tę samą metodę, np. w zależności od
Obiektowość w PHP5
Dzięki nowemu silnikowi PHP, Zend II,
modelo obiektowy PHP5 jest niezawod-
ny i wydajny i ma wiele nowych cech, ta-
kich jak:
• możliwość określenia widoczności
(ang. visibility ) każdej metody czy po-
la, czyli dostępu do niej, podobnie jak
ma to miejsce np. w Javie czy C++.
Cecha ta określa, czy metoda (lub po-
le) ma być publiczna (dostępna dla
Czym jest IRC
IRC jest jedną z usług internetowych. Protokół IRC został stworzony w roku 1988 roku
przez Jarkko Oikarinena. Umożliwia prowadzenie pogawędek internetowych, będąc proto-
plastą dzisiejszych czatów, które są dostępne na wielu witrynach internetowych. W przeci-
wieństwie jednak do czatów, IRC nie jest w żaden sposób powiązany ze stronami WWW,
lecz ma swoje serwery i oprogramowanie klienckie, którego potrzebujemy do prowadzenia
konwersacji. Najpopularniejsze programy klienckie IRC to:
• mIRC – komercyjny, dość wygodny w obsłudze program dla systemu Windows ( http://
www.mirc.com/ )
• ViRC – darmowy, całkiem dobry i rozbudowany klient IRC dla Windows ( http://
www.visualirc.net/ )
• XiRCON – inny darmowy klient IRC dla Windows ( http://www.xircon.com/ )
• ShadowIRC – klient IRC dla Macintosha ( http://www.shadowirc.com/ )
• ircII – klient IRC dla systemu UNIX ( http://www.eterna.com.au/ircii/ )
• Chatzilla – IRC w Twojej przeglądarce, czyli plugin dla Firefoksa oraz Mozilli ( http://
chatzilla.hacksrus.com/ )
wszystkich), prywatna (dostępna tyl-
ko dla klasy, w której została zdekla-
rowana), czy też chroniona (dostępna
dla klasy, w której została zdeklarowa-
na oraz jej klas pochodnych).
• wprowadzenie do klas destruktorów,
które pozwalają posprzątać po likwi-
dowanym obiekcie (powiemy o nich
później),
• ujednolicenie nazw konstrukto-
rów ( __construct() ) i destruktorów
( __destruct() ) dla wszystkich klas,
• możliwość automatycznego ładowa-
nia klas, bez konieczności używania
instrukcji typu include czy require
(nie jest to co prawda związane bez-
pośrednio z programowaniem obiek-
towym, jednak często bardzo ułatwia
pracę),
• wprowadzenie klas abstrakcyjnych
oraz interfejsów (opiszemy je dokład-
niej w dalszej części artykułu),
• możliwość deklarowania pól oraz me-
tod statycznych ( static ), dostępnych
bezpośrednio w klasie, a nie jej instan-
Po połączeniu się z serwerem, korzystamy z komend wydawanych w linii poleceń progra-
mu klienckiego, z których najważniejsze to:
/server nazwa _ serwera – łączy się z wybranym serwerem,
/join #nazwa _ kanału – wchodzi na określony kanał (jeżeli jesteśmy połączeni
z serwerem),
/msg nick wiadomość – wysyła prywatną wiadomość do użytkownika o określonym
nicku,
/say wiadomość – wysyła informację do aktywnego okna, dla wszystkich użytkowni-
ków (w większości klientów wpisywanie say nie jest potrzebne).
Komend IRC jest o wiele więcej. Ich pełną listę znajdziemy na stronach większości progra-
mów klienckich oraz w ich manualach.
Bardzo dużo jest również serwerów IRC i są one rozsiane po całym świecie. Więk-
szość z nich jest połączona w większe sieci (będąc podłączonymi do jednego serwe-
ra z takiej sieci możemy rozmawiać z osobami podłączonymi do innych), takie jak bar-
dzo popularny w Polsce IRCNet (w każdej chwili jest tam ok. 12000 polskich użytkowni-
ków), zobacz www.irc.pl . Oto kilka polskich serwerów należących do tej sieci IRC: – war-
szawa.irc.pl , krakow.irc.pl , poznan.irc.pl , lublin.irc.pl . Z serwerami tymi łączymy się korzy-
stając z portów od 6661 do 6667 . Warto także odwiedzić serwer irc.php.pl , a na nim kanał
#php.pl – oicjalny serwer IRC polskiego serwisu o PHP – www.php.pl . Serwer ten dodat-
kowo oferuje kanał #test , na którym możemy swobodnie testować swojego bota.
16
www.phpsolmag.org
PHP Solutions Nr 4/2006
440355768.007.png
IRCBot – programowanie obiektowe
Początki
cji. Teoretycznie było to możliwe już
w PHP4, ale wersja 4 pozwalała na ta-
kie traktowanie dowolnych metod i pól,
co nie jest wskazane,
• możliwość deklarowania klas oraz me-
tod jako inalne (po klasach inalnych
nie można dziedziczyć, zaś metod i-
nalnych przykryć (przedeiniować),
czyli dopasować ich zachowania do
wymagań klasy pochodnej),
• wprowadzenie obsługi błędów w po-
staci wyjątków, których tu nie opisze-
my (poświęciliśmy im inne artykuły,
w tym „Obsługa błędów za pomocą
wyjątków SPL”, z numeru „PHP Solu-
tions 2/2005).
tyczące operatorów i botów wyjaśniamy
w Ramce Opy i boty na IRC .
Dodajmy, że bot jest skryptem działa-
jącym jak klient IRC. Przeważnie pracuje
w linii poleceń, np. na tej samej maszynie,
na której stoi serwer IRC (choć nie jest to
konieczne), a wywołujemy go korzystając
z telnetu czy ssh. Nasz bot będzie mógł
działać zarówno w taki sposób, jak i za
pośrednictwem przeglądarki internetowej,
w której będzie aktywny aż do zamknię-
cia jej okna.
Czego jeszcze potrzebujemy? Zna-
jomości podstaw specyikacji protokołu,
na którym oparte są aplikacje klienckie
IRC. Jest on dosyć dobrze opisany (m.in.
w RFC 2812), nie powinieneś więc mieć
problemu z zagłębieniem się w jego tajniki
(zob. Ramka Protokół IRC w sieci ).
Protokół IRC w sieci
Oicjalny opis protokołu klienta IRC zaj-
muje 63 strony i jest opisany w dokumen-
cie RFC 2812 pt. Internet Relay Chat:
Client Protocol . Dokument ten znajdzie-
my w wielu miejscach w Internecie, m.in.
pod adresem http://www.faqs.org/rfcs/
rfc2812.html .
Suchy opis protokołu nie jest jed-
nak zbyt przyjazny. Zachęcamy więc
do rozpoczęcia lektury od strony http://
www.cybernexus.biz/irc/default.htm .
Znajdziesz tam wprowadzenie do pro-
tokołu oraz przykładowe logi komunika-
cji klienta IRC z serwerem, wraz z wyja-
śnieniami.
• odbieranie i wykonywanie poleceń wy-
dawanych wyłącznie przez zalogowa-
nych do niego użytkowników,
• śledzenie wydarzeń (ang. events ) za-
chodzących na wybranym kanale,
• możliwość pracy na wielu serwerach
i kanałach IRC jednocześnie,
• modularna budowa, pozwalająca na
dodawanie:
Nowości dotyczących programowania
obiektowego jest znacznie więcej. Już te
wymienione pokazują, jak zaawansowa-
nym językiem obiektowym stał się PHP5.
Pokażemy te możliwości na przykładzie
praktycznej aplikacji: stworzymy bota dzia-
łającego w sieciach IRC.
Koncepcja IRCBota
Zanim przystąpimy do tworzenia naszego
IRCBot-a, zastanówmy się, jakimi cechami
powinien się on wyróżniać. Są wśród nich:
Tworzymy obiektowego
IRCBota
Naszego bota nazwiemy IRCBot. Będzie
to skrypt, który działa na kanale IRC uda-
jąc zwykłego użytkownika i pełniąc rozma-
ite funkcje potrzebne administratorowi, ta-
kie jak piilnowanie porządku na tym ka-
nale, nadawanie statusu Opa (operato-
ra) wybranym osobom, czy ich wyrzucanie
(wykopywanie, ang. kick ) z kanału.
Jeśli nie znasz świata IRC, zajrzyj
do Ramki Czym jest IRC ; szczegóły do-
Listing 1. Klasa koniguracyjna bota
<? php
class Coniguration {
static public $arrConiguration = array (
'bot' = > array ( /* Koniguracja bota */
'Nick' = > 'AlaMaKota' , /* Nick bota na serwerach */
'Password' = > '' , /* Hasło do serwera – najczęściej puste */
'Ident' = > 'MSBot' , /* identyikator bota */
// Prawdziwa nazwa użytkownika (nazwa i wersja bota)
'Realname' = > 'MSBot R1' ,
'QuitMessage' = > 'Idę sobie...' , // informacja pożegnalna
'Host' = > 'localhost' , /* Nazwa hosta z pod jakiego łączy się bot */
) ,
// serwery, z którymi bot ma się połączyć po uruchomieniu
'Servers' = > array (
array (
'Host' = > 'irc.php.pl' , // host serwera
// Tablica z portami obsługiwanymi przez serwer
'Ports' = > array ( '6667' ) ,
// tablica z kanałami serwerów, na które bot ma wejść
'Channels' = > array ( '#test' ) ,
// czy komunikaty idą z/do serwera mają być logowane
'Logging' = > true,
) ,
) ,
/* Klasy eventy */
'Events' = > array (
'KickReJoinEvent' ,
) ,
'System' => array (
/* Plik z informacjami o administartorach */
'AdminsFile' => 'Coniguration\admins' ,
'LoggingClass' = > 'FileLogging' , /* klasa zapisująca logi */
'LogsDir' = > 'logs/' , // Katalog w którym mają być zapisywane logi
) ,
) ;
}
?>
Opy i boty na IRC
W IRCNecie (a także w wielu innych sie-
ciach IRC, które nie posiadają możliwo-
ści rejestrowania kanałów; dziś wiele no-
wych sieci oferuje taką funkcję), pierw-
sza osoba wchodząca na kanał otrzymu-
je status tzw. Opa (operatora czy admi-
nistratora).
Jego uprawnienia są ogromne – mo-
że on ustalać temat kanału (np. Dysku-
sja o PHP6), nadawać status Opa innym
użytkownikom kanału, wyrzucać z niego
niechciane osoby czy zabraniać im po-
nownego wstępu udzialając tzw. bana
(ang. ban znaczy zakaz ) na wybranego
nicka lub hosta.
Niestety, w momencie opuszcze-
nia kanału, Op traci swoje uprawnienia.
Aby temu zaradzić, administratorzy sto-
sują boty. Jak już wspomnieliśmy, bot to
skrypt udający zwykłego użytkownika ka-
nału (niektórzy nazywają go „sztuczną in-
teligencją”, ale jest to raczej określenie
na wyrost). Jego zadaniem jest przyjmo-
wanie i wykonywanie poleceń Opa.
PHP Solutions Nr 4/2006
www.phpsolmag.org
17
440355768.008.png 440355768.009.png 440355768.010.png
Początki
IRCBot – programowanie obiektowe
• obsługi nowych zdarzeń (eventów wy-
stępujących na danym kanale (np. wy-
kopania użytkownika). Każde zdarze-
nie będzie obsługiwane przez odręb-
ny moduł,
• nowych komend – bot będzie odbierał
komendy wysyłane do niego jako pry-
watne wiadomości,
• możliwość pracy zarówno w linii pole-
ceń, jak i w oknie przeglądarki.
Listing 2. Klasa IRCBot
abstract class IRCBot {
static public $strVersion = '0.1.0' ;
protected $arrServers = array () ;
private $arrServerLogs = array () ;
private $arrEvents = array () ;
private $objAdmins ;
public function __construct () {
$this - > objAdmins = Admin::getInstance ( $this ) ;
$this - > registerEvent ( 'CommandEvent' ) ;
$this - > registerEvent ( 'AdminLogoutEvent' ) ;
foreach ( Coniguration:: $arrConiguration [ 'Events' ] as $strEvent ) {
$this - > registerEvent ( $strEvent ) ; }
}
public function __destruct () { $this - > show ( ' ' , ' ' , '--- END --- ' ) ; }
public function run () {
foreach ( Coniguration:: $arrConiguration [ 'Servers' ] as $arrServer ) {
$this - > connect ( $arrServer ) ; }
for ( ;; ) {
if ( count ( $this - > arrServers ) ===0 ) { return ; }
usleep ( 50000 ) ; $this - > ircProc () ; // przetwarzamy komunikaty z serwera
}
}
public function connect ( $arrServer ) {
if ( isset ( $arrServer [ 'Logging' ]) && $arrServer [ 'Logging' ] ===true ) {
$this - > arrServerLogs [ $arrServer [ 'Host' ]] = new FileLogging ( $arrServer [
'Host' ]) ; }
$this - > arrServers [ $arrServer [ 'Host' ]] = new Server ( $arrServer ,
Coniguration:: $arrConiguration [ 'bot' ] , $this ) ;
$this - > arrServers [ $arrServer [ 'Host' ]] - > connect () ;
}
public function getServers () { return $this - > arrServers; }
protected function ircProc () {
foreach ( $this - > arrServers as $objServer ) {
$mixData = null;
if (( $objServer !== null ) &&
(( $arrData = $objServer - > serverProc ()) !== false ) &&
$arrData !== true ) { $this - > executeEvents ( $objServer , $arrData ) ; }
elseif ( $objServer !== null && $arrData !== true ) {
$objServer - > disconnect () ;
$this - > arrServers = array_diff_key (
$this - > arrServers, array ( $objServer - > getName () = > '' )) ;
}
}
}
public function executeEvents ( $objServer , $arrData ) {
if ( isset ( $this - > arrEvents [ $arrData [ 'type' ]])) {
foreach ( $this - > arrEvents [ $arrData [ 'type' ]] as $objEvent ) {
$objEvent - > execute ( $objServer , $arrData ) ; }
}
}
public function log ( $strServer , $strDirection , $strContent ) { }
public function registerEvent ( $strEventName ) {
if ( ile_exists ( ROOT_DIR. 'Events' .
DIRECTORY_SEPARATOR. $strEventName . '.class.php' )) {
require_once ( ROOT_DIR. 'Events' .
DIRECTORY_SEPARATOR. $strEventName . '.class.php' ) ;
$objEvent = new $strEventName ( $this ) ;
if ( ! ( $objEvent instanceof Event )) {
$this - > show ( ' ' , ' ' , "Nieznany typ klasy obsługującej zdarzenia
( $strEventName )" ) ; }
foreach ( $objEvent - > getEventNames () as $strEvent ) {
$this - > arrEvents [ $strEvent ][] = $objEvent ; }
} else { $this - > show ( ' ' , ' ' , "Brak klasy zdarzenia ( $strEventName )" ) ; }
}
abstract public function show ( $strServer , $strChannel , $strContent ) ;
}
Nasza aplikacja ma być w pełni obiekto-
wa, czyli składać się z klas realizujących
określoną funkcjonalność. Zastanówmy
się teraz, jakich klas potrzebujemy.
Klasy IRCBota
Bot będzie się składał z następujących
klas:
Coniguration – zawrzemy w niej spis
wszystkich ustawień naszego progra-
mu (m.in. nazwę użytkownika, adresy
i porty serwerów, listę obsługiwanych
wydarzeń, itd.),
IRCBot – główna klasa IRCbota, odpo-
wiadająca za inicjalizację i komunika-
cję z serwerami, a także obsługę wy-
darzeń i komend,
Server – będzie ona zapewniała ko-
munikację z wybranym serwerem IRC
(m.in. nawiązanie i zakończenie połą-
czenia),
Channel – klasa odpowiadająca jedne-
mu kanałowi, na którym przebywa bot,
Event – klasa bazowa dla klas obsłu-
gujących zdarzenia,
ILogging – nie jest klasą, lecz interfej-
sem, który jest potrzebny do logowa-
nia komunikatów,
Admin – odpowiada za zapamiętywa-
nie i zarządzanie zalogowanymi użyt-
kownikami.
Koniguracja
– klasa Coniguration
Zaczniemy od klasy Coniguration . Jak
już wiemy, jej zadaniem będzie prze-
chowywanie ustawień naszego bo-
ta: będzie się ono odbywało w zmien-
nej statycznej (ang. static ) o nazwie
$arrConiguration. Nazwa celowo roz-
poczyna się od arr (skrót od array ), aby
ułatwić rozpoznawanie typu zmiennej.
Stosowanie takiej zasady ułatwia póź-
niejsze modyikacje i pielęgnację kodu.
Zmiennej mogącej przechowywać da-
ne różnego typu nadalibyśmy przedro-
stek mix .
18
www.phpsolmag.org
PHP Solutions Nr 4/2006
440355768.011.png
Zgłoś jeśli naruszono regulamin