You are on page 1of 32

IDZ DO

PRZYKADOWY ROZDZIA
SPIS TRECI

KATALOG KSIEK
KATALOG ONLINE

PHP. 101 praktycznych


skryptw. Wydanie II
Autor: Marcin Lis
ISBN: 83-246-0796-X
Format: B5, stron: 296

ZAMW DRUKOWANY KATALOG

TWJ KOSZYK
DODAJ DO KOSZYKA

CENNIK I INFORMACJE
ZAMW INFORMACJE
O NOWOCIACH
ZAMW CENNIK

CZYTELNIA
FRAGMENTY KSIEK ONLINE

Wydawnictwo Helion
ul. Kociuszki 1c
44-100 Gliwice
tel. 032 230 98 63
e-mail: helion@helion.pl

Wykorzystaj w swoich projektach gotowe rozwizania


Przetwarzanie grafiki
Operacje na plikach
Komunikacja z bazami danych
PHP to jeden z najpopularniejszych jzykw wykorzystywanych do tworzenia
dynamicznych witryn WWW. Od pocztku swojej obecnoci na rynku zyska
ogromne uznanie programistw. Jest dostpny nieodpatnie i ma ogromne moliwoci.
Jego najnowsza wersja otworzya przed twrcami aplikacji nowe horyzonty, oferujc
im wszystkie korzyci wynikajce z programowania obiektowego. PHP jest dostpny
dla wikszoci popularnych systemw operacyjnych z rodziny Unix/Linux, Windows,
Mac OS oraz Risc OS. Wsppracuje te z wieloma serwerami HTTP, dziki czemu
jest niezwykle uniwersalny.
W ksice PHP. 101 praktycznych skryptw. Wydanie II znajdziesz gotowe skrypty,
dziki ktrym zdecydowanie przypieszysz swoj prac nad aplikacjami i serwisami
internetowymi. To wydanie zostao tak zaktualizowane w stosunku do poprzedniego,
e skrypty dziaaj prawidowo w najnowszej wersji jzyka PHP. Autor zapewni take
zgodno generowanych przez nie dokumentw HTML z obowizujcymi standardami
tego jzyka. Kady ze skryptw moesz po prostu wklei do swojego kodu bd
zmodyfikowa, aby dokadnie odpowiada Twoim potrzebom. Korzystajc z przykadw
znajdujcych si w tej ksice, moesz doda do swoich projektw funkcje obsugujce
system plikw, przetwarzajce grafik, zabezpieczajce witryny i aplikacje przed
nieautoryzowanym dostpem.
Operacje sieciowe
Praca z systemem plikw
Liczniki odwiedzin i ksigi goci
Przetwarzanie grafiki
Autoryzacja uytkownikw
Komunikacja z bazami danych
Przewodnik po najwaniejszych elementach jzyka PHP
Skorzystaj ze sprawdzonych rozwiza

Wstp .............................................................................................. 9
Rozdzia 1. Globalna sie ................................................................................. 11
Skrypt 1. Uzyskanie adresu IP ......................................................................................... 11
Skrypt 2. Odczytanie rekordw MX ................................................................................ 13
Skrypt 3. Nawizanie poczenia TCP ............................................................................ 14
Skrypt 4. Wysyanie poczty ............................................................................................. 17
Skrypt 5. Pobranie pliku z serwera ftp ............................................................................ 19
Skrypt 6. Wysanie pliku do serwera ftp ........................................................................... 20
Skrypt 7. Wysanie pliku do serwera (upload pliku) ....................................................... 21
Skrypt 8. Przekierowanie z uyciem znacznika <meta> ................................................. 24
Skrypt 9. Przekierowanie z uyciem nagwkw HTTP ................................................. 25
Skrypt 10. Przekierowanie ze wzgldu na adres IP ......................................................... 25
Skrypt 11. Przekierowanie na losow witryn ................................................................ 26
Skrypt 12. Zablokowanie wybranych adresw IP ........................................................... 27
Skrypt 13. Walidacja adresu e-mail ................................................................................. 28
Skrypt 14. Wysanie pliku do przegldarki ..................................................................... 28
Skrypt 15. Pobieranie plikw z listy I ............................................................................. 30
Skrypt 16. Pobieranie plikw z listy II ............................................................................ 32
Skrypt 17. Generowanie listy plikw do pobrania .......................................................... 35

Rozdzia 2. System plikw ............................................................................... 37


Skrypt 18. Wykonanie polecenia zewntrznego .............................................................. 37
Skrypt 19. Wywietlenie listy plikw .............................................................................. 38
Skrypt 20. Nawigacja po katalogach serwera .................................................................. 39
Skrypt 21. Usunicie zawartoci katalogu ....................................................................... 42
Skrypt 22. Rozmiar katalogu ........................................................................................... 43
Skrypt 23. Kopiowanie zawartoci katalogu ................................................................... 43
Skrypt 24. Wywietlenie plikw okrelonego typu jako odnonikw ............................ 44

Rozdzia 3. Liczniki, ksigi goci itp. ................................................................ 47


Skrypt 25. Prosty licznik tekstowy .................................................................................. 47
Skrypt 26. Licznik przechowujcy dat pocztkow ...................................................... 48
Skrypt 27. Licznik graficzny ........................................................................................... 50
Skrypt 28. Licznik filtrujcy adresy IP ............................................................................ 51
Skrypt 29. Licznik filtrujcy adresy IP II .......................................................................... 53
Skrypt 30. Licznik uwzgldniajcy tylko jedno odwoanie z danego IP ......................... 54

PHP. 101 praktycznych skryptw


Skrypt 31. Gosowanie (ankieta) ..................................................................................... 55
Skrypt 32. Ksiga goci ................................................................................................... 61
Skrypt 33. Ksiga goci z nawigacj ............................................................................... 65
Skrypt 34. Porada dnia ..................................................................................................... 69
Skrypt 35. Porada dnia z hasami w pliku ....................................................................... 70
Skrypt 36. Inna strona dla znanego uytkownika ............................................................ 71

Rozdzia 4. Grafika i obrazy .............................................................................. 73


Skrypt 37. Najprostsza galeria ......................................................................................... 73
Skrypt 38. Zautomatyzowana galeria .............................................................................. 75
Skrypt 39. Galeria z podpisami obrazw .......................................................................... 79
Skrypt 40. Galeria z miniaturami obrazw ...................................................................... 82
Skrypt 41. Zmiana rozdzielczoci obrazu ........................................................................ 86
Skrypt 42. Zmiana rozdzielczoci obrazu z zachowaniem proporcji .............................. 87
Skrypt 43. Zmiana rozdzielczoci z rozpoznaniem typu pliku ........................................ 88
Skrypt 44. Informacja o wykorzystywanej bibliotece graficznej .................................... 91
Skrypt 45. Zmiana rozdzielczoci obrazw z wybranego katalogu ................................ 92
Skrypt 46. Przeskalowanie serii obrazw ........................................................................ 93
Skrypt 47. Obracanie obrazu ........................................................................................... 94
Skrypt 48. Obracanie serii obrazw ................................................................................ 95
Skrypt 49. Konwersja obrazu do wybranego formatu ..................................................... 96
Skrypt 50. Konwersja obrazw z wybranego katalogu ................................................... 99
Skrypt 51. Tekst jako obrazek ....................................................................................... 101
Skrypt 52. Naoenie tekstu na obraz ............................................................................ 103

Rozdzia 5. Uytkownicy i hasa ...................................................................... 105


Skrypt 53. Haso dostpu do strony ............................................................................... 105
Skrypt 54. Logowanie uytkownikw ........................................................................... 107
Skrypt 55. Logowanie z kodowaniem hase .................................................................. 109
Skrypt 56. Zarzdzanie hasami ..................................................................................... 110
Skrypt 57. Haso dostpu z uyciem sesji ..................................................................... 114
Skrypt 58. Logowanie uytkownikw z wykorzystaniem sesji .................................... 118
Skrypt 59. Inna strona dla kadego uytkownika .......................................................... 120
Skrypt 60. Generowanie losowego hasa ....................................................................... 122
Skrypt 61. Automatyczne logowanie ............................................................................. 123

Rozdzia 6. Data i czas .................................................................................. 127


Skrypt 62. Bieca data i czas ....................................................................................... 127
Skrypt 63. Ile dni do? ................................................................................................ 128
Skrypt 64. Rnica midzy dwoma datami ................................................................... 129
Skrypt 65. Data ostatniej modyfikacji strony ................................................................ 132
Skrypt 66. Strona zalena od pory dnia ......................................................................... 133
Skrypt 67. Strona zalena od dnia tygodnia .................................................................. 134
Skrypt 68. Wywietlenie nazwy dnia tygodnia ............................................................. 134
Skrypt 69. Rysunek zaleny od dnia tygodnia .............................................................. 135
Skrypt 70. Czas generowania strony ............................................................................. 136
Skrypt 71. Kalendarz ..................................................................................................... 137

Rozdzia 7. Bazy danych ................................................................................. 141


Skrypt 72. Licznik wykorzystujcy baz danych .......................................................... 141
Skrypt 73. Ankieta ......................................................................................................... 143
Skrypt 74. Ksiga goci ................................................................................................. 146
Skrypt 75. Logowanie .................................................................................................... 150
Skrypt 76. Autoryzacja z wykorzystaniem sesji i kodowaniem danych ....................... 152
Skrypt 77. Zarzdzanie hasami ..................................................................................... 154

Spis treci

5
Skrypt 78. Zapamitanie danych uytkownika .............................................................. 157
Skrypt 79. Automatyczne logowanie ............................................................................. 163
Skrypt 80. Liczba osb obecnych na stronie ................................................................. 165
Skrypt 81. Liczba osb przegldajcych stron z rnych adresw IP ............................ 167
Skrypt 82. Statystyka strony (lista odwiedzin) .............................................................. 169
Skrypt 83. Liczba przegldajcych stron (z wykorzystaniem statystyki strony) ......... 171
Skrypt 84. Pobieranie plikw ........................................................................................ 172
Skrypt 85. Ranking plikw ............................................................................................ 176
Skrypt 86. Automatyczne generowanie nazw plikw ................................................... 180
Skrypt 87. Lista odnonikw ......................................................................................... 181
Skrypt 88. Zliczanie odwoa z kadego adresu IP ....................................................... 183
Skrypt 89. Porada dnia ................................................................................................... 186
Skrypt 90. Statystyka przegldarek ............................................................................... 187

Rozdzia 8. Rozmaitoci ................................................................................. 191


Skrypt 91. Lista odwiedzin ............................................................................................ 191
Skrypt 92. Rozpoznanie typu przegldarki .................................................................... 192
Skrypt 93. Rozpoznanie typu systemu operacyjnego .................................................... 194
Skrypt 94. Ocenzurowanie tekstu .................................................................................. 194
Skrypt 95. Ocenzurowanie tekstu z wykorzystaniem zewntrznego sownika ............. 195
Skrypt 96. Losowy baner ............................................................................................... 196
Skrypt 97. Losowy baner z wybranego katalogu .......................................................... 197
Skrypt 98. Banery wywietlane w okrelonej kolejnoci .............................................. 198
Skrypt 99. Ochrona przed spamem ................................................................................ 199
Skrypt 100. Adres e-mail w postaci obrazu ................................................................... 200
Skrypt 101. Zabezpieczenie witryny przed kopiowaniem ............................................. 202

Dodatek A Krtki przewodnik po PHP ............................................................ 205


Krtka historia PHP ....................................................................................................... 205
Instalacja ........................................................................................................................ 205
PHP i HTML ................................................................................................................. 206
Znaczniki PHP ......................................................................................................... 206
Pierwszy skrypt ....................................................................................................... 207
czenie skryptw ................................................................................................... 208
Komentarze ............................................................................................................. 209
Zmienne w PHP ............................................................................................................. 210
Typy danych ............................................................................................................ 210
Konwersje typw ..................................................................................................... 217
Zmienne globalne (superglobalne) .......................................................................... 221
Operatory ....................................................................................................................... 222
Operatory arytmetyczne .......................................................................................... 222
Operatory logiczne .................................................................................................. 222
Operatory bitowe ..................................................................................................... 223
Operatory porwnywania (relacyjne) ...................................................................... 223
Operatory przypisania ............................................................................................. 224
Operatory inkrementacji/dekrementacji .................................................................. 225
Pozostae operatory ................................................................................................. 226
Priorytety operatorw .............................................................................................. 227
Instrukcje ....................................................................................................................... 227
Instrukcje warunkowe ............................................................................................. 227
Ptle ......................................................................................................................... 229
Skadnia alternatywna ............................................................................................. 231
Funkcje .......................................................................................................................... 232
Argumenty funkcji .................................................................................................. 232

PHP. 101 praktycznych skryptw


Klasy i obiekty ............................................................................................................... 234
Dziedziczenie .......................................................................................................... 235
Konstruktory ............................................................................................................ 236
Operator zakresu ..................................................................................................... 237
Wsppraca z przegldark ............................................................................................ 238
Metoda GET ............................................................................................................ 239
Metoda POST .......................................................................................................... 241
Wsppraca z systemem ................................................................................................ 242
Odczyt i zapis plikw .............................................................................................. 242
Data i czas ............................................................................................................... 245
Bazy danych .................................................................................................................. 253
Obsuga baz danych ................................................................................................ 253
czenie z baz danych ........................................................................................... 253
Zapytania ................................................................................................................. 254
Pobieranie danych ................................................................................................... 255
Pobieranie wynikw zapytania ................................................................................ 257

Dodatek B Wybrane funkcje dostpne w PHP ................................................. 259


Funkcje systemu plikw ................................................................................................ 259
Funkcja basename ................................................................................................... 259
Funkcja chgrp .......................................................................................................... 260
Funkcja chmod ........................................................................................................ 260
Funkcja chown ........................................................................................................ 260
Funkcja clearstatcache ............................................................................................. 260
Funkcja copy ........................................................................................................... 261
Funkcja dirname ...................................................................................................... 261
Funkcja disk_free_space ......................................................................................... 261
Funkcja disk_total_space ........................................................................................ 261
Funkcja fclose ......................................................................................................... 262
Funkcja feof ............................................................................................................. 262
Funkcja fflush .......................................................................................................... 262
Funkcja fgetc ........................................................................................................... 262
Funkcja fgetcsv ....................................................................................................... 263
Funkcja fgets ........................................................................................................... 263
Funkcja fgetss .......................................................................................................... 263
Funkcja file_exists ................................................................................................... 263
Funkcja file_get_contents ....................................................................................... 264
Funkcja file_put_contents ....................................................................................... 264
Funkcja file .............................................................................................................. 264
Funkcja fileatime ..................................................................................................... 264
Funkcja filectime ..................................................................................................... 265
Funkcja filegroup .................................................................................................... 265
Funkcja fileinode ..................................................................................................... 265
Funkcja filemtime ................................................................................................... 265
Funkcja fileowner .................................................................................................... 265
Funkcja fileperms .................................................................................................... 266
Funkcja filesize ....................................................................................................... 266
Funkcja filetype ....................................................................................................... 266
Funkcja flock ........................................................................................................... 266
Funkcja fopen .......................................................................................................... 267
Funkcja fpassthru .................................................................................................... 268
Funkcja fputs ........................................................................................................... 268
Funkcja fread ........................................................................................................... 268
Funkcja fscanf ......................................................................................................... 268

Spis treci

7
Funkcja fseek ........................................................................................................... 269
Funkcja fstat ............................................................................................................ 269
Funkcja ftell ............................................................................................................. 269
Funkcja ftruncate ..................................................................................................... 269
Funkcja fwrite ......................................................................................................... 270
Funkcja glob ............................................................................................................ 270
Funkcja is_dir .......................................................................................................... 271
Funkcja is_executable ............................................................................................. 271
Funkcja is_file ......................................................................................................... 271
Funkcja is_link ........................................................................................................ 271
Funkcja is_readable ................................................................................................. 271
Funkcja is_uploaded_file ........................................................................................ 272
Funkcja is_writable ................................................................................................. 272
Funkcja is_writeable ............................................................................................... 272
Funkcja link ............................................................................................................. 272
Funkcja linkinfo ...................................................................................................... 272
Funkcja lstat ............................................................................................................ 273
Funkcja mkdir ......................................................................................................... 273
Funkcja move_uploaded_file .................................................................................. 273
Funkcja parse_ini_file ............................................................................................. 273
Funkcja pathinfo ...................................................................................................... 274
Funkcja pclose ......................................................................................................... 274
Funkcja popen ......................................................................................................... 274
Funkcja readfile ....................................................................................................... 274
Funkcja readlink ...................................................................................................... 275
Funkcja realpath ...................................................................................................... 275
Funkcja rename ....................................................................................................... 275
Funkcja rewind ........................................................................................................ 275
Funkcja rmdir .......................................................................................................... 275
Funkcja set_file_buffer ........................................................................................... 276
Funkcja stat ............................................................................................................. 276
Funkcja symlink ...................................................................................................... 276
Funkcja tempnam .................................................................................................... 276
Funkcja tmpfile ....................................................................................................... 277
Funkcja touch .......................................................................................................... 277
Funkcja unlink ......................................................................................................... 277
Funkcje sieciowe ........................................................................................................... 277
Funkcja checkdnsrr ................................................................................................. 277
Funkcja closelog ...................................................................................................... 278
Funkcja debugger_off ............................................................................................. 278
Funkcja debugger_on .............................................................................................. 278
Funkcja define_syslog_variables ............................................................................ 278
Funkcja dns_check_record ...................................................................................... 278
Funkcja dns_get_mx ............................................................................................... 279
Funkcja dns_get_record .......................................................................................... 279
Funkcja fsockopen ................................................................................................... 279
Funkcja gethostbyaddr ............................................................................................ 280
Funkcja gethostbyname ........................................................................................... 280
Funkcja gethostbynamel .......................................................................................... 280
Funkcja getmxrr ...................................................................................................... 280
Funkcja getprotobyname ......................................................................................... 280
Funkcja getprotobynumber ..................................................................................... 281
Funkcja getservbyname ........................................................................................... 281
Funkcja getservbyport ............................................................................................. 281

PHP. 101 praktycznych skryptw


Funkcja ip2long ....................................................................................................... 281
Funkcja long2ip ....................................................................................................... 281
Funkcja openlog ...................................................................................................... 282
Funkcja pfsockopen ................................................................................................. 282
Funkcja socket_get_status ....................................................................................... 282
Funkcja socket_set_blocking .................................................................................. 283
Funkcja socket_set_timeout .................................................................................... 283
Funkcja syslog ......................................................................................................... 283

Skorowidz .................................................................................... 285

Rozdzia 3.

Skrypt 25. Prosty licznik tekstowy


Bardzo popularne na witrynach internetowych s rnego rodzaju liczniki odwiedzin. Do
ich tworzenia doskonale nadaj si skrypty PHP, a najprostszy licznik tekstowy mona
zawrze w dosownie kilku wierszach kodu.
Dane naszego licznika, czyli liczb odwiedzin, bdziemy przechowywa w pliku counter.txt w postaci tekstowej. Dziki temu atwo bdziemy mogli wprowadzi warto
pocztkow, korzystajc z dowolnego edytora tekstu. Plik ten otworzymy przy pomocy
funkcji fopen w trybie r+, czyli do zapisu i odczytu. Po otworzeniu wczytamy jedn
lini tekstu i przypiszemy j do zmiennej $count. Warto tej zmiennej zwikszymy
o jeden i wywietlimy j na ekranie. Po wykonaniu tych czynnoci trzeba bdzie przesun wskanik pooenia w pliku na jego pocztek i ponownie zapisa w nim warto
zmiennej $count. Na koniec plik naley zamkn przy pomocy funkcji fclose. Caa
konstrukcja prezentuje si nastpujco:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
<title>Liczni< te<stowy</title>
</head>
<body>
<div style="text-align:center">
<h2>Tutaj znajduje si tre strony.</h2>
<br /><br />
</div>
<div style="text-align:center">
Ta strona zostaa odwiedzona
<?php
/*S<rypt pochodzi z <si<i "PHP. 101 pra<tycznych s<ryptw"
autor: Marcin Lis
http://marcinlis.com*/

48

PHP. 101 praktycznych skryptw


function getHits()
{
if(($fp = @fopen("counter.txt" "r(")) === false)
return false;
$count = fgets($fp);
$count = $count ( 1;
fsee<($fp 0);
fputs($fp $count);
fclose($fp);
return $count;
}
echo(getHits());
?>
razy od 18 <wietnia 2008 r.
</div>
</body>
</html>

Uruchomienie tego skryptu spowoduje pojawianie si strony jak na rysunku 3.1. Jak
wida, realizacja najprostszego licznika nie powinna sprawi kopotu nawet pocztkujcym
programistom. Naley jedynie pamita, aby ustawi uprawnienia pliku counter.txt,
tak aby PHP mia moliwo jego odczytu i zapisu.
Rysunek 3.1.
Dziaanie licznika
tekstowego

Skrypt 26. Licznik przechowujcy


dat pocztkow
Cz licznikw zawiera informacj o dacie, od ktrej rozpoczo si zliczanie liczby
odwiedzin. W skrypcie 25. bya ona umieszczana w treci strony, jednak mona j rwnie umieci w pliku przechowujcym liczb odwiedzin. Dla uproszczenia dzie, miesic i rok mona zapisa w kolejnych liniach, dziki czemu nie bdzie potrzebna adna
analiza danych po wczytaniu, ich edycja bdzie wyjtkowo prosta, a posta daty prezentowanej na witrynie zalena jedynie od sposobu jej przetwarzania w kodzie PHP.
Zasada dziaania skryptu jest taka sama jak w przypadku skryptu 25. Nowe elementy
to wczytanie trzech linii zawierajcych elementy skadowe daty. Wykorzystane zostan
w tym celu trzy dodatkowe wywoania funkcji fgets, w postaci:

Rozdzia 3. Liczniki, ksigi goci itp.

49

$dzien = trim(fgets($fp));
$miesiac = trim(fgets($fp));
$ro< = trim(fgets($fp));

Zastosowana w wywoaniach funkcja trim suy do usunicia znakw koca linii, ktre
pozostaj w cigu wynikowym zwracanym przez fgets. Odczytane w ten sposb dane
zostan wywietlone na stronie w formacie: dzie-miesic-rok.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
<title>Liczni< te<stowy</title>
</head>
<body>
<div style="text-align:center">
<h2>Tutaj znajduje si tre strony.</h2>
<br /><br />
</div>
<div style="text-align:center">
Ta strona zostaa odwiedzona
<?php
/*S<rypt pochodzi z <si<i "PHP. 101 pra<tycznych s<ryptw"
autor: Marcin Lis
http://marcinlis.com*/
function printHits()
{
$end_line = "\r\n";
if(($fp = fopen("counter.txt" "r")) === false)
return false;
$count = fgets($fp);
$dzien = trim(fgets($fp));
$miesiac = trim(fgets($fp));
$ro< = trim(fgets($fp));
$count = $count ( 1;
fclose($fp);
if(!($fp = fopen("counter.txt" "wb")) === false){
fputs($fp $count.$end_line);
fputs($fp $dzien.$end_line);
fputs($fp $miesiac.$end_line);
fputs($fp $ro<.$end_line);
fclose($fp);
}
echo("$count razy od $dzien-$miesiac-$ro< r.");
}
printHits();
?>
</div>
</body>
</html>

50

PHP. 101 praktycznych skryptw

Skrypt 27. Licznik graficzny


Skrypty 25. i 26. pokazyway, w jaki sposb umieci na stronie WWW liczniki tekstowe pokazujce liczb odwiedzin. Atrakcyjnym rozwizaniem moe by rwnie wykorzystanie licznika prezentujcego dane w postaci graficznej. W tym celu naley przygotowa dziesi obrazw przedstawiajcych kolejne cyfry od 0 do 9. Do ich wykonania
mona wykorzysta dowolny edytor graficzny lub poszuka gotowych grafik w internecie. Obrazy naley zapisa w plikach, ktrych nazwy odpowiadaj poszczeglnym
cyfrom, czyli 0.jpg, 1.jpg itd.
Podstawowa cz skryptu bdzie taka sama jak w poprzednich dwch przykadach.
Dane dotyczce liczby odwiedzin oraz daty uruchomienia licznika zapisane s w pliku
counter.txt w postaci tekstowej. Po wczytaniu tych danych trzeba jednak bdzie dokona
ich analizy tak, aby mona byo wczyta odpowiednie pliki z grafik.
Skorzystamy z moliwoci poruszania si po acuchu znakw, tak jak po tablicy. Wystarczy zatem napisa ptl, ktra bdzie pobieraa kolejne znaki z cigu oznaczajcego liczb
odwiedzin i wygeneruje odpowiednie znaczniki <img>. Ptla taka bdzie miaa posta:
for($i = 0; $i < $strLength; $i((){
$temp = $count[$i]. '.jpg';
$imgStr .= "<img src=\"$temp\" alt=\"{$count[$i]}\">";
}

Zmienna $count zawiera liczb odwiedzin w postaci cigu znakw, a $strLength to dugo tego cigu. Po wykonaniu caej ptli zmienna $imgStr bdzie zawieraa odpowiedni
cig znacznikw <img>. Na przykad dla liczby 123 bdzie to:
<img src="1.jpg" alt="1"><img src="2.jpg" alt="2"><img src="3.jpg" alt="3">

Oczywicie zakadamy, e obraz cyfry 1 znajduje si w pliku o nazwie 1.jpg, cyfry 2


w pliku 2.jpg itd. Ostatecznie kod skryptu przyjmie posta widoczn na poniszym listingu,
a wczytanie go do przegldarki spowoduje wywietlenie widoku jak na rysunku 3.2.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
<title>Liczni< graficzny</title>
</head>
<body>
<div style="text-align:center">
<h2>Tutaj znajduje si tre strony.</h2>
<br /><br />
</div>
<div style="text-align:center">
Ta strona zostaa odwiedzona
<?php
/*S<rypt pochodzi z <si<i "PHP. 101 pra<tycznych s<ryptw"
autor: Marcin Lis
http://marcinlis.com*/

Rozdzia 3. Liczniki, ksigi goci itp.

51

Rysunek 3.2.
Licznik odwiedzin
w formie graficznej

function getHits()
{
if(($fp = @fopen("counter.txt" "r(")) === false)
return false;
$count = fgets($fp);
$count = $count ( 1;
fsee<($fp 0);
fputs($fp $count);
fclose($fp);
$count = strval($count);
$strLength = strlen($count);
$imgStr = "";
for($i = 0; $i < $strLength; $i((){
$temp = $count[$i]. '.jpg';
$imgStr .= "<img src=\"$temp\" alt=\"{$count[$i]}\">";
}
return $imgStr;
}
echo(getHits());
?>
razy od 18 <wietnia 2008 r.
</div>
</body>
</html>

Skrypt 28. Licznik filtrujcy adresy IP


Prosta modyfikacja skryptu 25. pozwoli nam na odrzucenie zliczania wywoa strony,
przychodzcych z wybranych adresw IP. W ten sposb moemy zablokowa wywoania np. z adresu lokalnego 127.0.0.1. Adresy, ktre chcemy zablokowa, umiecimy
w tablicy $ip_table. Sprawdzaniem, czy dane IP znajduje si w tej tablicy, zajmie si
funkcja banIP. Zwrci ona warto true, jeli dane wywoanie ma zosta odrzucone,
lub warto false w przeciwnym wypadku. Wystarczy zatem sprawdza warto zwracan przez badIP i w zalenoci od tego zwiksza lub nie warto licznika. Adres IP,

52

PHP. 101 praktycznych skryptw

z ktrego nadeszo biece wywoanie strony, odczytujemy z tablicy $_SERVER, odwoujc


si do klucza REMOTE_ADDR.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
<title>Moja strona WWW</title>
</head>
<body>
<div style="text-align:center">
<h2>Tutaj znajduje si tre strony.</h2>
<br /><br />
</div>
<div style="text-align:center">
Ta strona zostaa odwiedzona
<?php
/*S<rypt pochodzi z <si<i "PHP. 101 pra<tycznych s<ryptw"
autor: Marcin Lis
http://marcinlis.com*/
function badIP($ip)
{
$ip_table = array(
0 => "127.0.0.1"
1 => "10.0.0.1"
);
foreach($ip_table as $bannedIP){
if($bannedIP == $ip)
return true;
}
return false;
}
function getHits()
{
if(($fp = @fopen("counter.txt" "r(")) === false)
return false;
$count = fgets($fp);
if(!badIP($_SERVER['REMOTE_ADDR'])){
$count = $count ( 1;
fsee<($fp 0);
fputs($fp $count);
}
fclose($fp);
return $count;
}
echo(getHits());
?>
razy od 18 <wietnia 2008 r.
</div>
</body>
</html>

Rozdzia 3. Liczniki, ksigi goci itp.

53

Skrypt 29. Licznik filtrujcy adresy IP II


Czasami istnieje konieczno czstego uaktualniania listy adresw IP, ktre maj by
pomijane przy zliczaniu odwoa do naszej strony. W przypadku skryptu 28. jest to moliwe, jednak ingerujemy wtedy bezporednio w jego tre. Moe to by niezbyt wygodne,
np. w sytuacji, kiedy jedna osoba zajmuje si programowaniem skryptu, a inna uaktualnianiem bazy adresw IP. Dobrym rozwizaniem takiego problemu moe by przechowywanie listy adresw w oddzielnym pliku tekstowym.
Modyfikacji, a dokadniej napisania od nowa, wymaga znana nam ju z wczeniejszego
przykadu funkcja badIP. Naley w niej otworzy plik z danymi, moe on mie nazw
np. banned_ip.txt, oraz sprawdzi, czy ktry ze znajdujcych si w nim zapisw odpowiada adresowi IP, z ktrego nadeszo biece wywoanie. Plik ten bdzie w postaci tekstowej, a kady jego wiersz bdzie zawiera dokadnie jeden adres. Do odczytu kolejnych
wierszy wykorzystamy funkcj fgets.
Stosujc skrypt tego typu, musimy jednak pamita, e przy kadym wywoaniu strony
odwouje si on do pliku banned_txt. Przy duej liczbie odwiedzajcych bdzie on wic
mniej wydajny ni skrypt 28., gdzie adresy IP byy wpisane bezporednio w kod. Pamitajmy rwnie, e plik z adresami musi by utworzony przez nas rcznie. Skrypt nie
podejmuje bowiem prby jego utworzenia.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
<title>Moja strona WWW</title>
</head>
<body>
<div style="text-align:center">
<h2>Tutaj znajduje si tre strony.</h2>
<br /><br />
</div>
<div style="text-align:center">
Ta strona zostaa odwiedzona
<?php
/*S<rypt pochodzi z <si<i "PHP. 101 pra<tycznych s<ryptw"
autor: Marcin Lis
http://marcinlis.com*/
function badIP($ip)
{
$fd = fopen("banned_ip.txt" "r");
while (!feof ($fd)) {
$line = trim(fgets($fd));
if($line == $ip){
fclose($fd);
return true;
}
}
fclose($fd);
return false;
}

54

PHP. 101 praktycznych skryptw


function getHits()
{
if(($fp = @fopen("counter.txt" "r(")) === false)
return false;
$count = fgets($fp);
if(!badIP($_SERVER['REMOTE_ADDR'])){
$count = $count ( 1;
fsee<($fp 0);
fputs($fp $count);
}
fclose($fp);
return $count;
}
echo(getHits());
?>
razy od 18 <wietnia 2008 r.
</div>
</body>
</html>

Skrypt 30. Licznik uwzgldniajcy


tylko jedno odwoanie z danego IP
Odpowiednio modyfikujc kod zaprezentowany w skrypcie 29., moemy pokusi si
o stworzenie licznika, ktry bdzie uwzgldnia tylko jedno odwoanie z danego adresu
IP. To znaczy, e jeli z danego komputera nastpio chocia jedno odwoanie do strony,
to ju nie bdzie ono wicej uwzgldniane przez licznik.
Ponownie naley zatem zmodyfikowa funkcj badIP. Po pierwsze, dodamy instrukcje sprawdzajce, czy plik banned_ip.txt istnieje. Jeli nie, podejmiemy prby jego utworzenia. Po drugie, jeli adres, z ktrego nastpio biece wywoanie, nie znajduje si
w tym pliku, odpowiednio uaktualnimy dane. Zapisu dokonamy za pomoc funkcji fputs.
Naley rwnie pamita, aby przed zapisem przesun wskanik pliku na jego koniec,
korzystajc z kombinacji funkcji fseef i filesize.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
<title>Moja strona WWW</title>
</head>
<body>
<div style="text-align:center">
<h2>Tutaj znajduje si tre strony.</h2>
<br /><br />
</div>
<div style="text-align:center">
Ta strona zostaa odwiedzona
<?php

Rozdzia 3. Liczniki, ksigi goci itp.

55

/*S<rypt pochodzi z <si<i "PHP. 101 pra<tycznych s<ryptw"


autor: Marcin Lis
http://marcinlis.com*/
function badIP($ip)
{
$end_line = "\r\n";
if(file_exists("banned_ip.txt")){
$fd = fopen("banned_ip.txt" "r(");
}
else{
$fd = fopen("banned_ip.txt" "a(");
}
if(!$fd) return false;
while (!feof ($fd)) {
$line = trim(fgets($fd));
if($line == $ip){
fclose($fd);
return true;
}
}
fsee<($fd filesize("banned_ip.txt"));
fputs($fd $ip.$end_line);
fclose($fd);
return false;
}
function getHits()
{
if(($fp = @fopen("counter.txt" "r(")) === false)
return false;
$count = fgets($fp);
if(!badIP($_SERVER['REMOTE_ADDR'])){
$count = $count ( 1;
fsee<($fp 0);
fputs($fp $count);
}
fclose($fp);
return $count;
}
echo(getHits());
?>
razy od 18 <wietnia 2008 r.
</div>
</body>
</html>

Skrypt 31. Gosowanie (ankieta)


Rwnie popularne jak liczniki s ankiety umoliwiajce zbieranie opinii na rne
tematy. Napisanie takiego skryptu wymaga nieco wicej pracy ni w przypadku zwykego licznika, nie jest jednak szczeglnie skomplikowane. Nasza ankieta bdzie si

56

PHP. 101 praktycznych skryptw

skadaa z dwch czci. Pierwsza z nich to kod HTML wywietlajcy pytanie oraz formularz umoliwiajcy wybranie odpowiedzi, druga to skrypt PHP przetwarzajcy dane
oraz wywietlajcy wyniki. Kod formularza HTML bdzie mia nastpujc posta:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
<title>An<ieta</title>
</head>
<body>
<div>
<p style="font-weight:bold">Ja<i jest Twj ulubiony <olor?</p>
</div>
<div>
<form method="get" action="an<ieta.php">
<table>
<tr>
<td>czerwony</td>
<td>
<input type="radio" name="vote" value="czerwony">
</td>
</tr>
<tr>
<td>zielony</td>
<td>
<input type="radio" name="vote" value="zielony">
<td>
</tr>
<tr>
<td>niebies<i</td>
<td>
<input type="radio" name="vote" value="niebies<i">
<td>
</tr>
<tr>
<td>fioletowy</td>
<td>
<input type="radio" name="vote" value="fioletowy">
<td>
</tr>
<tr>
<td>czarny</td>
<td>
<input type="radio" name="vote" value="czarny">
<td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Gosuj">
<input type="hidden" name="action" value="vote">
</td>
</tr>
</table>
</form>
</div>

Rozdzia 3. Liczniki, ksigi goci itp.

57

<div>
<a href="an<ieta.php?action=show"> Zobacz wyni<i </a>
</div>
</body>
</html>

Po wczytaniu go do przegldarki ujrzymy widok zaprezentowany na rysunku 3.3. Jak


wida, ankieta bdzie pozwalaa na oddanie gosu na ulubiony kolor. Oczywicie jest
to tylko przykad, ktry moe by dowolnie modyfikowany. Formularz zosta utworzony
za pomoc standardowych znacznikw HTML <form> i <input>, a do jego formatowania
zostaa uyta zwyka tabela. Dane przekazywane bd do skryptu ankieta.php za pomoc
metody GET.
Rysunek 3.3.
Formularz
umoliwiajcy
gosowanie

Za formularzem zosta umieszczony odnonik, ktry bdzie umoliwia obejrzenie wynikw gosowania bez oddawanie gosu. Odnonik ten ma posta:
<a href="http://localhost/an<ieta.php?action=show">

a zatem jeli do skryptu ankieta.php zostanie przekazany parametr action o wartoci show,
bdzie to oznaczao, e ankieta ma zosta jedynie wywietlona na ekranie, jeli natomiast
parametr action bdzie mia warto vote (zapewnia to ukryte pole formularza: <input
type="hidden" name="action" value="vote">), bdzie to oznaczao, e ma zosta zapisany nowy gos.
Tre skryptu przetwarzajcego dane (zapisanego w pliku ankieta.php) bdzie nastpujca:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
<title>Wyni<i gosowania</title>
</head>
<body>
<div>
<?php
/*S<rypt pochodzi z <si<i "PHP. 101 pra<tycznych s<ryptw"
autor: Marcin Lis
http://marcinlis.com*/

58

PHP. 101 praktycznych skryptw


function vote()
{
if(!isSet($_GET["vote"]) || $_GET["vote"] == ""){
echo("Nie zosta zaznaczony aden z <olorw.");
return false;
}
else{
$color = $_GET["vote"];
}
if(file_exists("colors.txt")){
if(($fp = fopen("colors.txt" "r(")) === false){
echo("Bd serwera. Gos nie zosta uwzgldniony.");
return false;
}
}
else{
if(($fp = fopen("colors.txt" "w(")) === false){
echo("Bd serwera. Gos nie zosta uwzgldniony.");
return false;
}
}
$czerwony = intval(fgets($fp));
$zielony = intval(fgets($fp));
$niebies<i = intval(fgets($fp));
$fioletowy = intval(fgets($fp));
$czarny = intval(fgets($fp));

switch($color){
case "czerwony":$czerwony((;brea<;
case "zielony":$zielony((;brea<;
case "niebies<i":$niebies<i((;brea<;
case "fioletowy":$fioletowy((;brea<;
case "czarny":$czarny((;brea<;
}
fsee<($fp 0);
fputs($fp $czerwony."\r\n");
fputs($fp $zielony."\r\n");
fputs($fp $niebies<i."\r\n");
fputs($fp $fioletowy."\r\n");
fputs($fp $czarny."\r\n");
fclose($fp);
return true;

function show()
{
if(file_exists("colors.txt")){
if(($fp = fopen("colors.txt"
echo("Bd serwera. Wyni<i
return;
}
}
else{
if(($fp = fopen("colors.txt"
echo("Bd serwera. Wyni<i

"r")) === false){


an<iety nie s dostpne.");

"w(")) === false){


an<iety nie s dostpne.");

Rozdzia 3. Liczniki, ksigi goci itp.

return;

$czerwony = intval(fgets($fp));
$zielony = intval(fgets($fp));
$niebies<i = intval(fgets($fp));
$fioletowy = intval(fgets($fp));
$czarny = intval(fgets($fp));
$votes_no = $czerwony ( $zielony ( $niebies<i ( $fioletowy ( $czarny;
$votes_no == 0?$votes_no = 1:0;
$czerwony_proc = sprintf("%.2f" $czerwony * 100 / $votes_no);
$zielony_proc = sprintf("%.2f" $zielony * 100 / $votes_no);
$niebies<i_proc = sprintf("%.2f" $niebies<i * 100 / $votes_no);
$fioletowy_proc = sprintf("%.2f" $fioletowy * 100 / $votes_no);
$czarny_proc = sprintf("%.2f" $czarny * 100 / $votes_no);
echo("<table border='1'>");
echo("<tr><td>Nazwa <oloru</td><td>Liczba gosw</td>");
echo("<td>Procent gosw</td></tr>");
echo("<tr><td>czerwony</td><td>$czerwony</td>");
echo("<td>$czerwony_proc</td></tr>");
echo("<tr><td>zielony</td><td>$zielony</td>");
echo("<td>$zielony_proc</td></tr>");
echo("<tr><td>niebies<i</td><td>$niebies<i</td>");
echo("<td>$niebies<i_proc</td></tr>");
echo("<tr><td>fioletowy</td><td>$fioletowy</td>");
echo("<td>$fioletowy_proc</td></tr>");
echo("<tr><td>czarny</td><td>$czarny</td>");
echo("<td>$czarny_proc</td></tr>");
}

echo("</table>");

if(isSet($_GET["action"])){
if($_GET["action"] == "show"){
show();
}
else if($_GET["action"] == "vote"){
if(vote()) show();
}
else{
echo("Otrzymano nieprawidowe dane.");
}
}
else{
echo("Otrzymano nieprawidowe dane.");
}
?>

59

60

PHP. 101 praktycznych skryptw


</div>
</body>
</html>

Jego wykonywanie rozpoczyna si od sprawdzenia, czy w tablicy $_GET znajduje si indeks


o nazwie action. Jeli nie, oznacza to, e do skryptu nie zostay przekazane odpowiednie
dane, do przegldarki jest wic wysyany odpowiedni komunikat i skrypt koczy dziaanie. Jeli jednak indeks action jest obecny, sprawdzana jest jego warto. Jeli jest to cig
show, wywoywana jest funkcja show wywietlajca dane, jeli natomiast jest to cig vote,
to wywoywana jest funkcja vote zapisujca nowy gos oraz jeeli wywoanie vote zakoczyo si sukcesem, rwnie funkcja show. W przypadku, kiedy wartoci klucza action
nie jest ani vote, ani show, do przegldarki wysyany jest komunikat o nieprawidowym
wywoaniu skryptu (nieprawidowych danych).
Zadaniem funkcji show jest wywietlenie tabeli zawierajcej wyniki gosowania. Przykadowy wygld takiej tabeli zosta zaprezentowany na rysunku 3.4. Dziaanie funkcji
rozpoczyna si od sprawdzenia, czy istnieje plik colors.txt zawierajcy dane. Jeli plik
istnieje, nastpuje prba otwarcia go w trybie do odczytu, jeli natomiast nie istnieje,
nastpuje prba utworzenia go przez wywoanie funkcji fopen w trybie w+. Jeeli ktrakolwiek z tych operacji zakoczy si niepowodzeniem, funkcja wywietla komunikat
o bdzie i skrypt koczy dziaanie.
Rysunek 3.4.
Tabela zawierajca
wyniki ankiety

Po otwarciu pliku za pomoc funkcji fread odczytywane s jego kolejnego wiersze. Pierwszy wiersz zawiera informacj o liczbie gosw oddanych na kolor czerwony, drugi
o liczbie gosw oddanych na kolor zielony itd. Odczytane wartoci poddawane s konwersji do typu int (odpowiadaj za to wywoania funkcji intval) i przypisywane zmiennym: $czerwony, $zielony, $niebiesfi, $fioletowy i $czarny. Cakowita liczba oddanych gosw jest zapisywana w zmiennej $votes_no, warto ta jest nastpnie wykorzystywana do obliczenia, jaki procent gosw uzyska kady z kolorw. Do obliczenia
procentowego udziau gosw wykorzystywany jest wzr:
procent = liczba gosw na dany <olor * 100 / ca<owita liczba gosw

Wyniki s formatowane z dokadnoci do dwch miejsc po przecinku za pomoc funkcji sprintf. Uzyskane w ten sposb dane umieszczane s w tabeli HTML generowanej
za pomoc standardowych znacznikw: <table>, <tr> i <td>, i wysyane do przegldarki za pomoc instrukcji echo.

Rozdzia 3. Liczniki, ksigi goci itp.

61

Zadaniem funkcji vote jest umieszczenie aktualnie otrzymanego gosu w pliku colors.txt.
Jej dziaanie rozpoczyna si od sprawdzenia, czy w tablicy $_GET znajduje si klucz
o nazwie vote oraz czy nie jest on pustym cigiem znakw. Jeeli jeden z wymienionych
warunkw jest prawdziwy, oznacza to, e do skryptu nie zostay przekazane poprawne
dane, a zatem funkcja wywietla komunikat o bdzie i koczy dziaanie. Jeli jednak
klucz o nazwie vote istnieje, jego warto jest przypisywana zmiennej color. Po wykonaniu tych czynnoci sprawdzane jest, czy istnieje plik colors.txt. Jeli istnieje, podejmowana jest prba otwarcia go w trybie r+, jeli natomiast nie istnieje, podejmowana jest
prba otwarcia go w trybie w+ (co jest w tym przypadku rwnoznaczne z prb utworzenia pliku na dysku). Jeeli prby te zakocz si niepowodzeniem, funkcja wywietla komunikat o bdzie i koczy dziaanie.
Po otwarciu pliku nastpuje odczyt jego zawartoci, analogicznie jak miao to miejsce
w przypadku funkcji show. Liczba gosw oddanych na poszczeglne kolory przypisywana jest zmiennym: $czerwony, $zielony, $niebiesfi, $fioletowy i $czarny. Nastpnie za pomoc instrukcji wyboru switch sprawdzane jest, na jaki kolor zosta oddany
biecy gos (czyli jaki kolor wskazuje zmienna $color), i opowiadajca mu zmienna
jest zwikszana o jeden. Na zakoczenie wskanik pozycji w pliku jest przesuwany na
pozycj zerow (na pocztek pliku), wszystkie dane s ponownie zapisywane i plik jest
zamykany za pomoc funkcji fclose.

Skrypt 32. Ksiga goci


Skrypt generujcy ksig goci bdzie si skada z trzech czci: szablonu gwnego,
ktry naley zapisa pod nazw guestbook.php, formularza sucego do dodawania wpisw, ktry naley zapisa pod nazw add.inc, oraz skryptu zarzdzajcego wpisami,
ktry naley zapisa pod nazw guestbook.inc. Wygld przykadowej ksigi goci utworzonej przez taki zestaw skryptw obrazuje rysunek 3.5.
Szablon gwny (plik guestbook.php) bdzie mia posta:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
<title>Ksiga goci</title>
</head>
<body>
<p style="text-align:center;bac<ground-color:red;
color:white;font-weight:bold">
Dodaj wpis:
</p>
<?php include("add.inc"); ?>
<p style="text-align:center;bac<ground-color:red;
color:white;font-weight:bold">

62

PHP. 101 praktycznych skryptw

Rysunek 3.5. Przykadowa ksiga goci


A<tualne wpisy:
</p>
<?php include("guestboo<.inc"); ?>
</body>
</html>

Zawiera on jedynie kod HTML tworzcy struktur strony. Znajduj si w nim dyrektywy include, ktre wczytuj pozostae czci skryptu, czyli pliki add.inc i guestbook.inc.
W pliku add.inc znajduje si formularz pozwalajcy na dodawanie wpisw. Formularz
zosta utworzony za pomoc standardowych elementw jzyka HTML, czyli znacznikw
<form> oraz <input>; jest on pozycjonowany za pomoc typowej tabeli i ma posta:
<form action="guestboo<.php"
method="post"
>
<table border="0"
align="center"
style="bac<ground-color:yellow;"
>
<tr>
<td>Imi:</td>
<td>
<input type="text" name="imie" style="width:150">
</td>
<td>Nazwis<o:</td>

Rozdzia 3. Liczniki, ksigi goci itp.

63

<td>
<input type="text" name="nazwis<o" style="width:152">
</td>
</tr><tr>
<td>Adres email:</td>
<td colspan="3">
<input type="text" name="email" style="width:380">
</td>
</tr><tr>
<td>Wpis:</td>
<td colspan="3">
<textarea name="contents" rows="5" cols="45" style="width:380"></textarea>
</td>
</tr><tr>
<td colspan="4" align="center">
<input type="submit" value="Dodaj">
</td>
</tr>
</table>
</form>

Czci najwaniejsz jest jednak sam skrypt zarzdzajcy wpisami znajdujcy si


w pliku guestbook.inc:
<?php
/*S<rypt pochodzi z <si<i "PHP. 101 pra<tycznych s<ryptw"
autor: Marcin Lis
http://marcinlis.com*/
function removeTags($str)
{
return htmlentities($str);
}
function readGuestBoo<()
{
$contents = "";
if(($fp = fopen("guestboo<.txt" "r")) === false)
return false;
while(!feof($fp)){
$contents .= fgets($fp) . "<br />";
}
fclose($fp);
return $contents;
}
function addToGuestBoo<($imie $nazwis<o $email $contents)
{
if(($fp = @fopen("guestboo<.txt" "r")) === false)
return false;
$imie = removeTags($imie);
$nazwis<o = removeTags($nazwis<o);
$email = removeTags($email);
$contents = removeTags($contents);
$tempC = fread($fp filesize("guestboo<.txt"));
fclose($fp);

64

PHP. 101 praktycznych skryptw

$fp = fopen("guestboo<.txt" "w");


fputs($fp $imie."\r\n");
fputs($fp $nazwis<o."\r\n");
fputs($fp $email."\r\n");
fputs($fp $contents."\r\n");
fputs($fp "\r\n");
fputs($fp $tempC);
fclose($fp);

if(isSet($_POST["imie"])){
$imie = $_POST["imie"];
}
else{
$imie = "";
}
if(isSet($_POST["nazwis<o"])){
$nazwis<o = $_POST["nazwis<o"];
}
else{
$nazwis<o = "";
}
if(isSet($_POST["email"])){
$email = $_POST["email"];
}
else{
$email = "";
}
if(isSet($_POST["contents"])){
$contents = $_POST["contents"];
}
else{
$contents = "";
}
if($imie == "" && $nazwis<o == ""
&& $email == "" && $contents == ""){
echo(readGuestBoo<());
}
else{
addToGuestBoo<($imie $nazwis<o $email $contents);
echo(readGuestBoo<());
}
?>

Wykonywanie kodu rozpoczyna si od odczytania zawarto tablicy $_POST i przypisania wartoci poszczeglnych pl do zmiennych: $imie, $nazwisfo, $email i $contents.
Jeli po tym przypisaniu co najmniej jedna z wymienionych zmiennych nie zawiera
pustego cigu znakw, oznacza to, e uytkownik klikn klawisz Dodaj i naley dokona wpisu do ksigi goci.
Za dodanie nowego wpisu odpowiada funkcja o nazwie addToGuestBoof. Wszystkie
niezbdne dane dotyczce wpisu, czyli: imi, nazwisko, adres e-mail oraz tre wpisu, s

Rozdzia 3. Liczniki, ksigi goci itp.

65

jej przekazywane w postaci argumentw. W tej funkcji otwierany jest plik guestbook.txt
w trybie r, czyli tylko do odczytu, a nastpnie jego zawarto jest odczytywana i przypisywana tymczasowej zmiennej $tempC.
Po wykonaniu wymienionych operacji plik jest zamykany za pomoc funkcji fclose,
a nastpnie ponownie otwierany, tym razem w trybie w tylko do zapisu. Otwarcie
w tym trybie powoduje obcicie dugoci pliku do zera, a tym samym skasowanie starej
zawartoci. Za pomoc serii instrukcji fputs zapisywane s zatem wszystkie nowe dane,
a na kocu dopisywana jest zawarto tymczasowej zmiennej $tempC. Dziki temu ostatnio wprowadzone przez uytkownika dane zawsze bd znajdoway si na pocztku
ksigi goci.
Do wywietlenia zawartoci pliku guestbook.txt wykorzystywana jest funkcja printGuestBoof. Jej konstrukcja jest bardzo prosta w ptli while za pomoc funkcji fgets
s wczytywane i dopisywane do zmiennej $contents kolejne wiersze tekstu. Dodatkowo
do kadego odczytanego acucha znakw jest dodawany znacznik HTML <br />. Ostatecznie, po osigniciu koca pliku, zmienna $contents bdzie zawieraa gotow do
wywietlenia na ekranie tre ksigi goci.
Skrypt zawiera rwnie funkcjonalno polegajc na uniemoliwieniu uytkownikowi wprowadzenia do treci wpisu znacznikw HTML, ktre mogyby zaburzy ukad
ksigi. Taka blokada moe by wprowadzona na wiele rnych sposobw, mona na
przykad zdefiniowa, ktre znaczniki HTML bd akceptowane, i odrzuca pozostae,
mona te filtrowa wprowadzone dane i usuwa kady napotkany znacznik (np. przy
uyciu funkcji strip_tags). Innym sposobem jest wprowadzenie sekwencji znakw
specjalnych. Naley wtedy zamieni wszystkie wystpienia < na &lt; i wszystkie wystpienia > na &gt; lub, lepiej, uy funkcji htmlentities. Zalet tego sposobu jest prostota
oraz to, e w ksidze pojawi si dokadnie to, co wpisa uytkownik, wcznie ze
wszystkimi znacznikami (rysunek 3.6 przy skrypcie 33.).
Wyboru konkretniej techniki pozbycia si niebezpieczestwa zwizanego ze znacznikami HTML naley dokona wedug wasnych potrzeb i uznania. Za usuwanie znacznikw odpowiada funkcja removeTags i to od jej wewntrznej realizacji zaley sposb
wykonania tego zadania. W powyszym skrypcie zostaa wykorzystana ostatnia z omawianych wczeniej metod, czyli wprowadzenie do kodu sekwencji znakw specjalnych,
za pomoc funkcji htmlentities.
Funkcja removeTags jest wywoywana w funkcji addToGuestBoof i przetwarza zawarto
zmiennych $imie, $nazwisfo, $email i $contents.

Skrypt 33. Ksiga goci z nawigacj


Ksiga goci przedstawiona w skrypcie 32. sprawdzaa si dobrze w sytuacji, kiedy
wpisw nie byo zbyt wiele. Gdyby jednak wpisw miao si pojawi bardzo duo, to ze
wzgldu na to, e wszystkie byyby wywietlane na jednej stronie, strona adowaaby
si dosy dugo, a samo przegldanie ksigi mogoby by nuce. Ten problem mona

66

PHP. 101 praktycznych skryptw

rozwiza przez dodanie do ksigi moliwoci nawigacyjnych, wymaga to jednak znacznej modyfikacji skryptu z poprzedniego przykadu. Bez zmian pozostan pliki pomocnicze: add.inc i guestbook.php, natomiast zmodyfikowany kod skryptu guestbook.inc
jest widoczny na poniszym listingu:
<?php
/*S<rypt pochodzi z <si<i "PHP. 101 pra<tycznych s<ryptw"
autor: Marcin Lis
http://marcinlis.com*/
$ile = 2;
$re<_size = 5;
function removeTags($str)
{
return htmlentities($str);
}
function s<ipRe<ord($fp $re<_size)
{
for($i = 0; $i < $re<_size; $i((){
fgets($fp);
if(feof($fp)){
return false;
}
}
return true;
}
function readGuestBoo<($from $ile $re<_size)
{
$contents = "";
if(($fp = fopen("guestboo<.txt" "r")) === false)
return false;
for($i = 0; $i < $from; $i((){
if(!s<ipRe<ord($fp $re<_size))
brea<;
}
for($i = $from * $re<_size; $i < ($from ( $ile) * $re<_size; $i((){
if(feof($fp)){
brea<;
}
$tempStr = fgets($fp);
$contents .= $tempStr."<br />";
}
fclose($fp);
return trim($contents);
}
function addToGuestBoo<($imie $nazwis<o $email $contents)
{
if(($fp = @fopen("guestboo<.txt" "r")) === false)
return false;
$imie = removeTags($imie);
$nazwis<o = removeTags($nazwis<o);
$email = removeTags($email);
$contents = removeTags($contents);

Rozdzia 3. Liczniki, ksigi goci itp.

$tempC = fread($fp filesize("guestboo<.txt"));


fclose($fp);
$fp = fopen("guestboo<.txt" "w");
fputs($fp $imie."\r\n");
fputs($fp $nazwis<o."\r\n");
fputs($fp $email."\r\n");
fputs($fp $contents."\r\n");
fputs($fp "\r\n");
fputs($fp $tempC);
fclose($fp);

if(isSet($_GET["from"])){
$from = $_GET["from"];
}
else{
$from = 0;
}
if($from <= 0){
$from = 0;
$prev = 0;
$next = $ile;
}
else{
$prev = $from - $ile;
$next = $from ( $ile;
}
if(isSet($_POST["imie"])){
$imie = $_POST["imie"];
}
else{
$imie = "";
}
if(isSet($_POST["nazwis<o"])){
$nazwis<o = $_POST["nazwis<o"];
}
else{
$nazwis<o = "";
}
if(isSet($_POST["email"])){
$email = $_POST["email"];
}
else{
$email = "";
}
if(isSet($_POST["contents"])){
$contents = $_POST["contents"];
}
else{
$contents = "";
}

67

68

PHP. 101 praktycznych skryptw


if($imie == "" && $nazwis<o == ""
&& $email == "" && $contents == ""){
$tempStr = readGuestBoo<($from $ile $re<_size);
if($tempStr == "" || $tempStr == "\r\n"){
echo("Koniec wpisw"."<br />");
$next -= $ile;
}
else{
echo($tempStr);
}
}
else{
addToGuestBoo<($imie $nazwis<o $email $contents);
echo(readGuestBoo<($from $ile $re<_size));
}
$code = <<<TEMP
<a href="guestboo<.php?from=$prev">Poprzednie</a>
<a href="guestboo<.php?from=$next">Nastpne</a>
TEMP;
echo("$code");
?>

Na pocztku zostay zdefiniowane dwie nowe zmienne: $ile, wskazujca liczb wpisw
wywietlanych na pojedynczej stronie, oraz $ref_size, okrelajca, ile linii zawiera
pojedynczy wpis. Bardzo przydatna jest rwnie dodatkowa funkcja o nazwie sfipReford, ktra przesuwa wskanik aktualnej pozycji w pliku na nastpny wpis. Jej dziaanie polega na odczytaniu liczby linii wskazywanych przez zmienn $ref_size.
Odczytem danych z ksigi goci zajmuje si funkcja readGuestBoof. W stosunku do
przedstawionej w skrypcie 32. wymagaa ona jednak wielu zmian. Przede wszystkim
w aktualnej wersji otrzymuje trzy argumenty: $from, $ile oraz $ref_size. Znaczenie
dwch ostatnich zostao wyjanione w poprzednim akapicie, argument $from oznacza
natomiast, od ktrego rekordu ma si zacz czytanie pliku, i jest wykorzystywany
w dodatkowej ptli pomijajcej zadan liczb rekordw.
Kolejna ptla, zajmujca si waciwym odczytem danych, musi w obliczeniach uwzgldnia przesunicie o $from rekordw. Niezbdne jest zatem wykonanie kilku dodatkowych dziaa arytmetycznych, tak aby prawidowo wyliczy warunek jej zakoczenia.
Std posta ptli:
for($i = $from * $re<_size; $i < ($from ( $ile) * $re<_size; $i((){
if(feof($fp)){
brea<;
}
$contents .= fgets($fp)."<br />";
}

Do nawigacji pomidzy kolejnymi wpisami s wykorzystywane typowe odnoniki


HTML definiowane znacznikami <a>. S one wywietlane na dole ksiki goci, po
ostatnim wpisie na stronie (rysunek 3.6). Odnoniki maj posta:
<a href="guestboo<.php?from=$prev">Poprzednie</a>
<a href="guestboo<.php?from=$next">Nastpne</a>

Rozdzia 3. Liczniki, ksigi goci itp.

69

Rysunek 3.6. Znaczniki HTML zostay przedstawione w postaci tekstowej

Kady odnonik ponownie wywouje skrypt, przypisujc polu from warto zawart
w zmiennej $prev lub $next. Zmienne te musz by oczywicie odpowiednio zainicjowane. Jeeli $from bdzie mniejsze lub rwne 0, to $prev otrzymuje warto 0, a $next
warto $ile. W przeciwnym przypadku (czyli kiedy $from jest wiksze od 0), $prev
otrzymuje warto $from - $ile, a $next warto $from + $ile. Niezbdne jest rwnie zablokowanie moliwoci powikszania wartoci zmiennej $next w nieskoczono. W tym celu jest sprawdzane, czy funkcja readGuestBoof zwrcia pusty cig znakw lub te cig oznaczajcych koniec linii tekstu. W obu przypadkach na ekranie jest
wywietlany tekst Koniec wpisw, a zmienna $next jest pomniejszana o warto zapisan w zmiennej $ile.

Skrypt 34. Porada dnia


Prostym, jednak czsto spotykanym, skryptem jest tak zwana porada dnia, czyli wywietlenie pewnej sentencji wybranej losowo z przygotowanego wczeniej zbioru. Moe to
by myl filozoficzna, przysowie lub dowcip, zaley to jedynie od pomysowoci autora
witryny oraz jej charakteru. Porada dnia moe zosta wygenerowana za pomoc poniszego skryptu:
<?php
/*S<rypt pochodzi z <si<i "PHP. 101 pra<tycznych s<ryptw"
autor: Marcin Lis
http://marcinlis.com*/
$porady = array(
0 => "Porada numer 1"

70

PHP. 101 praktycznych skryptw


1
2
3
4
);

=>
=>
=>
=>

"Porada
"Porada
"Porada
"Porada

numer
numer
numer
numer

2"
3"
4"
5"

function getText()
{
srand((float) microtime() * 10000000);
$arr = $GLOBALS["porady"];
return($arr[array_rand($arr)]);
}
echo(getText());
?>

Lista porad powinna zosta zapisana w tablicy o nazwie porady. Za wylosowanie jednej
z nich odpowiada funkcja getText. Inicjuje ona najpierw generator liczb pseudolosowych1, nastpnie przypisuje do zmiennej $arr globaln tablic $porady. Losowanie
odbywa si za pomoc funkcji array_rand, ktra zwraca losowy indeks tablicy przekazanej tej funkcji w postaci argumentu. Wylosowany tekst jest zwracany za pomoc
instrukcji return.

Skrypt 35. Porada dnia


z hasami w pliku
Skrypt 34. pokazywa, w jaki sposb wywietli na stronie porad dnia. Wszystkie hasa
przechowywane byy jednak bezporednio w kodzie skryptu w globalnej tablicy $porady.
Jeli porad jest duo i czsto si zmieniaj lub s uaktualnianie, lepszym rozwizaniem
moe by umieszczenie ich w zewntrznym pliku, tak jak pokazuje to poniszy kod:
<?php
/*S<rypt pochodzi z <si<i "PHP. 101 pra<tycznych s<ryptw"
autor: Marcin Lis
http://marcinlis.com*/
function readArray()
{
$texts = array();
if(!$fd = @fopen("porady.txt" "r")) return false;
$counter = 0;
while (!feof ($fd)){
$str = trim(fgets($fd));
if($str != "")
$texts[$counter((] = $str;

Poczwszy od PHP 4.0.2, inicjalizacja generatora liczb pseudolosowych nie jest konieczna (ta czynno
jest wykonywana automatycznie), jednak w celu zachowania maksymalnej kompatybilnoci zostaa
pozostawiona w skrypcie.

Rozdzia 3. Liczniki, ksigi goci itp.

71

}
return $texts;

function getText()
{
if(($arr = readArray()) != false){
srand((float) microtime() * 10000000);
return($arr[array_rand($arr)]);
}
else return "Bra< porady dnia na dzisiaj...";
}
echo(getText());
?>

Wszystkie porady powinny znale si w pliku tekstowym o nazwie porady.txt; kada


w oddzielnym wierszu. Dane z tego pliku odczytywane s w funkcji readArray. Kady
wiersz tekstu po odczytaniu jest umieszczany w oddzielnej komrce tablicy $texts.
Tablica ta jest nastpnie zwracana za pomoc instrukcji return. W przypadku gdyby
odczytanie danych z pliku nie powiodo si, funkcja zwrci warto false.
Za wylosowanie jednego z tekstw odpowiada funkcja getText. Pobiera ona tablic
tekstw za pomoc wywoania funkcji readArray. Jeeli wywoanie to powiedzie si,
to znaczy zwrcona zostanie warto rna od false, inicjowany jest generator liczb
pseudolosowych (srand((float) microtime() * 10000000);) oraz wykonywane jest
samo losowanie (odpowiada za to funkcja array_rand). Wylosowana warto jest zwracana za pomoc instrukcji return.

Skrypt 36. Inna strona


dla znanego uytkownika
Wykorzystujc pliki cookies, moemy spowodowa, aby uytkownikom, ktrzy pierwszy
raz wchodz na nasz stron, wywietlaa si inna witryna ni tym, ktrzy ju nas kiedy odwiedzili. Uyjemy do tego celu cookie o nazwie znany. Jeli bdzie ono obecne na
komputerze uytkownika, wczytywa bdziemy plik index1.html, w przeciwnym razie
index2.html. W tym drugim przypadku bdziemy rwnie ustawia cookie, wykorzystujc w tym celu funkcj setCoofie. Cay skrypt bdzie mia nastpujc posta:
<?php
/*S<rypt pochodzi z <si<i "PHP. 101 pra<tycznych s<ryptw"
autor: Marcin Lis
http://marcinlis.com*/
if(isSet($_COOKIE["znany"])){
include('index1.html');
}
else{
setCoo<ie("znany" "ta<" time() ( 3600 * 24 * 30);
include('index2.html');
}
?>

You might also like