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-
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
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
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
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
Plik z chomika:
Kapy97
Inne pliki z tego folderu:
2007.04_Aplikacje www _[Programy].pdf
(250 KB)
2006.04_Programowanie obiektowe w PHP na przykładzie IRCBota_[Programy].pdf
(841 KB)
2005.02_Tworzymy frontend do Wake-On-Lan w PHP-GTK_[Programy].pdf
(435 KB)
Inne foldery tego chomika:
Ajax
Atak
Bazy Danych
Bezpieczenstwo
Biblioteka
Zgłoś jeśli
naruszono regulamin