Professional Documents
Culture Documents
Matt Zandstra
a
PHP4
használatát
000cimnegyed.qxd 8/3/2001 6:09 PM Page iv
A szerzõrõl
Matt Zandstra (matt@corrosive.co.uk) a Corrosive Web Design céget vezeti
(http://www.corrosive.co.uk/) üzleti partnerével, Max Guglielminóval.
Mint a parancsnyelvekért rajongó programozó, PHP, Java, JavaScript, Perl, Lingo és
AppleScript nyelveken fejlesztett különbözõ programokat. Elõször bölcsészdiplomát
szerzett, majd úgy tanulta ki mesterségét, hogy újra feltalálta a kereket és kiele-
mezte, miért nem halad egyenesen. HTML, JavaScript, Perl és PHP tanfolyamokon
oktatott, majd szerzõként közremûködött a Dynamic HTML Unleashed címû könyv-
ben. Amikor nem kódot ír, Matt elkötelezett városi biciklista, Guinness-ivó, megszál-
lott olvasó és novellista, aki kiadhatatlan történeteket alkot. Azt állítja, egyszer talán
még regényt is fog írni.
000cimnegyed.qxd 8/3/2001 6:09 PM Page ix
Köszönetnyilvánítás
A nyílt forráskódú programoknak köszönhetem karrieremet és e könyv létrejöttét
is. Szeretném megköszönni mindazoknak, akiknek önzetlen segítõkészsége
mindig felülmúlja a kapott elismerést.
Tartalomjegyzék
Bevezetõ
xiv
short_open_tag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Hibajelentések beállításai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Változókra vonatkozó beállítások . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Segítség! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Összefoglalás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Kérdések és válaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Mûhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Kvíz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4. óra Az alkotóelemek . . . . . . . . . . . . . . . . . . . . 35
Változók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Dinamikus változók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Hivatkozások a változókra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Adattípusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Típus módosítása a settype() segítségével . . . . . . . . . . . . . . . . . . . . . 43
Típus módosítása típusátalakítással . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Mûveletjelek és kifejezések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Hozzárendelés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Aritmetikai mûveletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Összefûzés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
További hozzárendelõ mûveletek . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Összehasonlítás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Bonyolultabb összehasonlító kifejezések létrehozása
logikai mûveletek segítségével . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
002tartalom.qxd 8/3/2001 6:09 PM Page xv
xv
6. óra Függvények . . . . . . . . . . . . . . . . . . . . . . . 75
Mit nevezünk függvénynek? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Függvények hívása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Függvények létrehozása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
Függvények visszatérési értéke . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Dinamikus függvényhívások . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Változók hatóköre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Hozzáférés változókhoz a global kulcsszó segítségével . . . . . . . . . . . 84
Állapot megõrzése a függvényhívások között
a static kulcsszó segítségével . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Paraméterek további tulajdonságai . . . . . . . . . . . . . . . . . . . . . . . . 89
Paraméterek alapértelmezett értéke . . . . . . . . . . . . . . . . . . . . . . . . . . 89
002tartalom.qxd 8/3/2001 6:09 PM Page xvi
xvi
7. óra Tömbök . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Mit nevezünk tömbnek? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
Tömbök létrehozása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Tömbök létrehozása az array() függvény segítségével . . . . . . . . . . . . 99
Tömb létrehozása vagy elem hozzáadása a tömbhöz
szögletes zárójel segítségével . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Asszociatív tömbök . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Asszociatív tömbök létrehozása
az array() függvény segítségével . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Asszociatív tömbök létrehozása
és elérése közvetlen értékadással . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Többdimenziós tömbök . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Tömbök elérése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
Tömb méretének lekérdezése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
Tömb bejárása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
Asszociatív tömb bejárása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Többdimenziós tömb bejárása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Mûveletek tömbökkel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
Két tömb egyesítése az array_merge() függvény segítségével . . . . . 110
Egyszerre több elem hozzáadása egy tömbhöz
az array_push() függvény segítségével . . . . . . . . . . . . . . . . . . . . . . 110
Az elsõ elem eltávolítása
az array_shift() függvény segítségével . . . . . . . . . . . . . . . . . . . . . . . 112
Tömb részének kinyerése
az array_slice() függvény segítségével . . . . . . . . . . . . . . . . . . . . . . . 113
Tömbök rendezése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Számmal indexelt tömb rendezése
a sort() függvény segítségével . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Asszociatív tömb rendezése érték szerint
az asort() függvény segítségével . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Asszociatív tömb rendezése kulcs szerint
a ksort() függvény segítségével . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Összegzés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Kérdések és válaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Mûhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Kvíz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
002tartalom.qxd 8/3/2001 6:09 PM Page xvii
xvii
xviii
xix
xx
xxi
xxii
xxiii
xxiv
xxv
Mûhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467
Kvíz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467
Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467
Tárgymutató
003bevezeto.qxd 8/3/2001 6:10 PM Page xxvii
Bevezetõ
Ez a könyv egy nyílt forráskódú webes parancsnyelvrõl (szkriptrõl), a PHP-rõl
szól, amely csatlakozott a Perl-höz, az ASP-hez és a Javához a dinamikus webes
alkalmazások készítéséhez rendelkezésre álló nyelvek palettáján. A kötet progra-
mozási ismeretekkel is foglalkozik. A rendelkezésre álló lapokon nem jut elég
hely egy teljes PHP programozási útmutató közlésére vagy a PHP összes lehetõsé-
gének és eljárásának ismertetésére, mindazonáltal a könyvben található lépések
elég információt adnak ahhoz, hogy használni kezdhessük a PHP-t, akár rendel-
kezünk programozói tapasztalttal, akár újak vagyunk a parancsnyelvek világában.
A PHP 4 webes programozási nyelv. Ahhoz, hogy a lehetõ legtöbb hasznát ve-
gyük a könyvnek, célszerû némi ismerettel rendelkezni a Világhálóval és a HTML-
lel kapcsolatban. Ha nem rendelkezünk ilyen ismeretekkel, akkor is hasznos lehet
e könyv, ám meggondolandó egy HTML ismertetõ beszerzése. Ha kényelmesen
létre tudunk hozni egyszerû HTML dokumentumokat táblázatokkal, akkor ele-
gendõ tudással rendelkezünk.
Könyvünk szerkezete
Kötetünk négy fõ részbõl áll:
Az elsõ rész az elsõtõl a harmadik óráig tart és egy egyszerû parancsfájl futtatásáig
vezeti el az olvasót:
Az elsõ óra PHP: személyes honlaptól a portálig címmel bemutatja a PHP tör-
ténetét és képességeit, valamint a PHP tanulása mellett néhány érvet sorol fel.
A második óra A PHP telepítése címmel végigvezeti az olvasót a PHP telepí-
tésén UNIX rendszeren, valamint azon fordítási és beállítási lehetõségekkel
foglakozik, amelyek a környezet kialakítása szempontjából fontosak lehetnek.
A harmadik óra Elsõ PHP oldalunk címmel bemutatja, hogyan építhetünk
PHP kódot HTML oldalainkba és hogyan készíthetünk a böngészõ számára
kimenetet adó programot.
Bevezetõ xxix
I. RÉSZ
Az elsõ lépések
1. óra PHP: személyes honlaptól a portálig
2. óra A PHP telepítése
3. óra Elsõ PHP oldalunk
01_ora.qxd 8/3/2001 6:10 PM Page 2
01_ora.qxd 8/3/2001 6:10 PM Page 3
1. ÓRA
PHP: személyes honlaptól
a portálig
Üdvözlet a PHP világában! Ebben a könyvben végigtekintjük a PHP nyelv majd-
nem minden elemét. Mielõtt azonban részletesebben megnéznénk, mire lehetünk
képesek segítségével, tárjuk fel múltját, fõbb tulajdonságait és jövõjét.
Mi a PHP?
4 1. óra
Mi a PHP?
A PHP nyelv túlnõtt eredeti jelentõségén. Születésekor csupán egy makrókészlet
volt, amely személyes honlapok karbantartására készült. Innen ered neve is:
Personal Home Page Tools. Késõbb a PHP képességei kibõvültek, így egy önál-
lóan használható programozási nyelv alakult ki, amely képes nagyméretû webes
adatbázis-alapú alkalmazások mûködtetésére is.
A PHP fejlõdése
A PHP elsõ változatát amely néhány webalkalmazás-készítést segítõ makrót tar-
talmazott Rasmus Lerdorf készítette 1994-ben. Ezen eszközöket együttesen
a Personal Home Page Tools névvel azonosították. Késõbb, a kód újraírása után,
egy friss elem került a csomagba, a Form Interpreter (Ûrlapfeldolgozó), így
PHP/FI néven vált ismertebbé. A felhasználók szemszögébõl a PHP/FI nagyon
hasznos segédeszköz volt, így népszerûsége töretlenül nõtt. Több fejlesztõ is felfi-
gyelt rá, így 1997-re már számos programozó dolgozott rajta.
Ez természetesen nem jelenti azt, hogy a PHP nem használható más környezetben,
más eszközökkel. A PHP számos adatbázis-alkalmazással és webkiszolgálóval
képes együttmûködni. 1
A PHP népszerûségének növekedésére hatással volt a webes alkalmazások fejlesz-
tésében történt váltás is. Az 1990-es évek közepén természetesnek számított, hogy
akár egy nagyobb webhelyet is több száz, egyenként kézzel kódolt HTML lap fel-
használásával készítsenek el. Mára azonban a fejlesztõk egyre inkább kihasználják
az adatbázisok nyújtotta kényelmi szolgáltatásokat, hogy a megjelenítendõ tartal-
mat hatékonyan kezeljék és az egyes felhasználóknak lehetõséget adjanak
a webhelyek testreszabására.
Ebben a környezetben már nem meglepõ, hogy egy ilyen kifinomult és rugalmas
nyelv, mint a PHP, ekkora népszerûségre tett szert.
A PHP 4 újdonságai
A PHP 4-es változata számos a programozók életét megkönnyítõ új szolgálta-
tással rendelkezik. Nézzük ezek közül a legfontosabbakat:
6 1. óra
A Zend Engine
A PHP 3 készítésekor az alapoktól indulva teljesen új feldolgozóegységet írtak
a nyelvhez. A PHP 4-esben hasonló változás figyelhetõ meg a programokat futtató
magban, ez azonban jelentõsebb.
A Zend Engine a PHP modulok mögött található, a programokat futtató mag elne-
vezése. Kifejezetten a teljesítmény jelentõs növelésére fejlesztették ki.
Miért a PHP?
Van néhány megcáfolhatatlan érv, amiért a PHP 4-est érdemes választani. Ha más 1
programnyelveket is ismerünk, számos alkalmazás fejlesztése során észlelni fog-
juk, hogy a programozási szakasz érezhetõen gyorsabb, mint várnánk. A PHP,
mint nyílt forráskódú termék jó támogatással rendelkezik, amit a képzett fejlesztõi
gárda és az elkötelezett közösség nyújt számunkra. Ráadásul a PHP a legfontosabb
operációs rendszerek bármelyikén képes futni, a legtöbb kiszolgálóprogrammal
együttmûködve.
A fejlesztés sebessége
Mivel a PHP lehetõséget ad a HTML elemek és a programkódok elkülönítésére,
az alkalmazások fejlesztésekor lehetõség van elválasztani a kódolási, tervezési, és
összeállítási szakaszt. Ez jelentõsen megkönnyíti a programozók életét, azzal, hogy
elmozdítja az akadályokat a hatékony és rugalmas alkalmazások kialakításának
útjából.
8 1. óra
Teljesítmény
A hatékony Zend Engine-nek köszönhetõen a PHP 4-es jól vizsgázik az ASP-vel
szemben végzett méréseken, néhányban megelõzve azt. A lefordított PHP messze
maga mögött hagyja az ASP-t.
Hordozhatóság
A PHP-t alapvetõen úgy tervezték, hogy alkalmas legyen számos operációs rend-
szeren való használatra, együttmûködve különbözõ kiszolgálókkal és adatbázis-
kezelõkkel. Fejleszthetünk UNIX rendszerre és áttérhetünk NT alapokra minden
probléma nélkül. A PHP alkalmazásokat kipróbálhatjuk Personal Web Serverrel és
késõbb telepíthetjük azokat egy UNIX rendszerre, ahol a PHP-t Apache modulként
használjuk.
Összefoglalás
Ebben az órában bemutattuk a PHP-t. Láttuk, hogyan alakult át a nyelv egyszerû
makrókészletbõl hatékony programnyelvvé. Megismertük a Zend Engine-t, és
megnéztük, milyen új lehetõségeket teremt a PHP 4-es változatában. Végül átte-
kintettünk néhány tulajdonságot, amelyek ellenállhatatlanná teszik a PHP-t.
Kérdések és válaszok
Könnyû megtanulni a PHP nyelvet?
Röviden: igen! Valóban meg lehet tanulni a PHP alapjait 24 órában! A PHP meg-
számlálhatatlanul sok függvényt bocsát rendelkezésünkre, melyek megvalósításá-
hoz más nyelvekben saját kódot kellene írni. A PHP automatikusan kezeli a külön-
bözõ adattípusokat és memóriafoglalásokat (hasonlóan a Perl-höz).
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában 1
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Mit jelentett eredetileg a PHP betûszó?
Feladatok
1. A könyvet átlapozva annak felépítése alaposabban szemügyre vehetõ.
Gondolkozzunk el a témákon, és azon, hogyan segíthetnek jövõbeni
alkalmazásaink elkészítésében.
02_ora.qxd 8/3/2001 6:10 PM Page 11
2.ÓRA
A PHP telepítése
Mielõtt megkezdenénk az ismerkedést a PHP nyelvvel, be kell szereznünk, telepí-
tenünk és beállítanunk a PHP-értelmezõt. A feldolgozóprogram számos operációs
rendszerre elérhetõ és több kiszolgálóval is képes együttmûködni.
12 2. óra
A PHP telepítése 13
A PHP beszerzése
A PHP 4-es változata a http://www.php.net/ címrõl tölthetõ le. Mivel a PHP
nyílt forráskódú, nem kell a bankkártyánkat kéznél tartanunk, amikor letöltjük
az értelmezõt. Magyarországon a http://hu.php.net/ tükörkiszolgálót érde-
mes meglátogatni.
A PHP 4 telepítése
Apache webkiszolgálót használó Linuxra
Ebben a részben végigvezetünk egy PHP telepítést egy Apache webkiszolgálót
használó Linux rendszeren. A folyamat többé-kevésbé ugyanez más UNIX platfor-
mokon is. Elképzelhetõ, hogy az általunk használt rendszerre készült elõre fordított
változat is, így még egyszerûbben telepíthetnénk az értelmezõt, a PHP fordítása
azonban nagyobb szabadságot ad a feldolgozóba kerülõ szolgáltatásokat illetõen.
/www/bin/httpd -l
02_ora.qxd 8/3/2001 6:10 PM Page 14
14 2. óra
Ha még nem tettük meg, le kell töltenünk a PHP legfrissebb változatát. A tar fájl
gzip-pel tömörített, így elsõ lépésben ki kell csomagolnunk:
cd ../php-4.x.x
./configure --enable-track-vars \
--with-gd \
--with-mysql \
--with-apxs=/www/bin/apxs
make
make install
A PHP telepítése 15
./configure --help
Mivel a lista rendkívül hosszú, célszerû elõbb egy szövegfájlba irányítani, így
kényelmesebben elolvasható:
Annak ellenére, hogy a fenti parancs kimenete eléggé érthetõ, néhány fontos lehe-
tõséget meg kell említenünk mégpedig azokat, amelyek a könyv szempontjából
2
számunkra érdekesek.
--enable-track-vars
Ez a szolgáltatás automatikusan elõállítja számunkra a PHP oldalakon kívülrõl érke-
zõ adatokhoz tartozó asszociatív tömböket. Ezek a GET vagy POST kéréssel érkezett
adatok, a visszaérkezõ süti-értékek, a kiszolgálói és környezeti változók. A tömbök-
kel a hetedik órában foglalkozunk bõvebben, a HTTP kapcsolatokat a tizenharma-
dik órában részletezzük. A fenti rendkívül gyakran használt configure paraméter,
mivel nagyon kellemes lehetõség a beérkezõ adatok követésére. A PHP 4.0.2-es
változatától kezdve mindig be van kapcsolva, így nem kell külön megadni.
--with-gd
A --with-gd paraméter engedélyezi a GD könyvtár támogatását. Amennyiben
a GD könyvtár telepítve van a rendszeren, ez a paraméter lehetõséget ad dinamikus
GIF, JPEG vagy PNG képek készítésére a PHP programokból. A dinamikus képek
elõállításáról a tizennegyedik órában írunk. Ha a GD-t korábban nem az alapbeállí-
tású könyvtárba telepítettük, megadható a szokásostól eltérõ elérési út is:
--with-gd=/eleresi/ut/a/megfelelo/konyvtarhoz
--with-mysql
A --with-mysql engedélyezi a MySQL adatbázisok támogatását. Ha a rendszeren
a MySQL nem az alapbeállítású könyvtárban található, megadható a szokásostól
eltérõ elérési út is:
--with-mysql=/eleresi/ut/a/megfelelo/konyvtarhoz
Mint már tudjuk, a PHP támogat számos más adatbázisrendszert is. Az 1.2-es táblá-
zatban ezek közül láthatunk néhányat, a hozzájuk tartozó configure paramé-
terekkel.
02_ora.qxd 8/3/2001 6:10 PM Page 16
16 2. óra
Az Apache beállítása
Miután sikeresen lefordítottuk az Apache-t és a PHP-t, módosítanunk kell
az Apache beállításait tartalmazó httpd.conf fájlt. Ez az Apache könyvtárának
conf alkönyvtárban található.
A következõ sorok hozzáadása szükséges:
A PHP telepítése 17
php.ini
A PHP mûködését a fordítás vagy telepítés után is befolyásolhatjuk, a php.ini hasz-
nálatával. UNIX rendszereken az alapbeállítású könyvtár a php.ini fájl számára
a /usr/local/lib, Windows rendszereken a Windows könyvtára. Emellett
a feldolgozásra kerülõ PHP oldal könyvtárában a munkakönyvtárban elhelye-
zett php.ini fájlban felülbírálhatjuk a korábban beállított értékeket, így akár
könyvtáranként különbözõ beállításokat adhatunk meg.
A letöltött PHP csomag könyvtárában található egy minta php.ini fájl, amely
a gyári beállításokat tartalmazza. Ezek az értékek lépnek érvénybe akkor, ha
a PHP nem talál egy php.ini fájlt sem.
A php.ini fájl beállításai egy névbõl, egy egyenlõségjelbõl és egy értékbõl áll-
nak. A szóközöket a feldolgozó figyelmen kívül hagyja.
18 2. óra
short_open_tag
A short_open_tag beállítás határozza meg, hogy használhatjuk-e a rövid <?
kód ?> formát a PHP kódblokkok írására. Ha ez ki van kapcsolva, az alábbi sorok
valamelyikét láthatjuk:
short_open_tag = Off
short_open_tag = False
short_open_tag = No
short_open_tag = On
short_open_tag = True
short_open_tag = Yes
Hibajelentések beállításai
Ha hibákat keresünk programjainkban, hasznos a hibaüzenetek kiírása a HTML
oldalba a böngészõ számára. Ez alapbeállításban bekapcsolt:
display_errors = On
Beállíthatjuk a hibajelentési szintet is. Ez azt jelenti, hogy mivel többféle hibaüzenet-
típus is rendelkezésre áll, letilthatjuk egyik vagy másik típust, amennyiben nem
szeretnénk PHP oldalaink kimenetében látni az abba a csoportba tartozó hibákat.
A hibakezelés beállításával alaposabban a huszonkettedik órában foglalkozunk,
addig az alábbi értékadás tökéletesen megfelel:
Ezzel a PHP minden hibát jelezni fog a lehetséges problémákat jelölõ figyelmezte-
tések kivételével. Ezek a figyelmeztetések megakadályoznák néhány szokásos
PHP módszer alkalmazását, ezért ez az alapbeállítás.
02_ora.qxd 8/3/2001 6:10 PM Page 19
A PHP telepítése 19
register_globals = On
Segítség!
A segítség mindig kéznél van az Interneten, különösen a nyílt forráskódú progra-
mokkal kapcsolatos problémák esetén. Ezért mielõtt a levelezõprogramunk Küldés
gombját megnyomnánk, gondolkozzunk el egy kicsit. Akármennyire is mûködés-
képtelennek tûnhet a telepített értelmezõnk, beállításunk vagy programozási megol-
dásunk, jó esélyünk van rá, hogy nem vagyunk ezzel egyedül. Valaki talán már
megválaszolta kérdésünket.
Ha falba ütközünk, az elsõ hely, ahol segítséget kereshetünk, a PHP hivatalos hon-
lapja a http://www.php.net/ címen, különösen az ott található, olvasói kiegészí-
tésekkel ellátott kézikönyv: http://www.php.net/manual/. Sok segítséget és
információt találhatunk a Zend webhelyén is: http://www.zend.com/. A magyar
PHP fejlesztõk a weblabor.hu webmester honlapon találhatnak rengeteg információt:
http://weblabor.hu/php/. Itt készítjük a magyar PHP dokumentációt is.
Ha nem sikerült megtalálni a megoldást, hasznos segítség lehet, hogy a PHP hivatalos
webhelyén keresést is végezhetünk. A tanács, ami után kutatunk, talán egy sajtóköz-
leményben, vagy egy FAQ-fájlban rejtõzik. Egy másik kitûnõ forrás a PHP
Knowledge Base: http://www.faqts.com/knowledge-base/index.phtml.
Keresés itt is végezhetõ.
02_ora.qxd 8/3/2001 6:10 PM Page 20
20 2. óra
Amennyiben ezek után is meg vagyunk gyõzõdve arról, hogy problémánk még nem
merült fel korábban, jó szolgálatot tehetünk a PHP közösségnek, ha felhívjuk rá
a figyelmet.
Miért kell ilyen sok szempontot figyelembe vennünk, mielõtt egy levelezõlistára
postáznánk kérdésünket? Elõször is a fejlesztési problémák megoldásában szerzett
tapasztalat elõnyös lehet a késõbbi munka során. Egy tapasztalt programozó álta-
lában gyorsan és hatékonyan tud problémákat megoldani. Egy alapvetõ kérdés
feltevése technikai jellegû listán többnyire egy-két olyan választ eredményez,
amelyben felhívják figyelmünket, hogy erre a kérdésre az archívumban megtalál-
ható a válasz.
02_ora.qxd 8/3/2001 6:10 PM Page 21
A PHP telepítése 21
Összefoglalás
A PHP 4 nyílt forráskódú. Nyílt abban az értelemben is, hogy nem szükséges egy
meghatározott kiszolgálót, operációs rendszert vagy adatbázist használnunk
a fejlesztéshez. Ebben az órában láttuk, honnan szerezhetõ be a PHP és más
a webhelyek szolgáltatásaiban segítõ nyílt forráskódú programok. Megnéztük,
hogyan fordítható le a PHP Apache modulként Linux rendszeren. Ha nem a for-
ráskódot töltjük le a hálózatról, hanem egy lefordított változatot, akkor a csomag-
ban részletes információkat találunk a telepítéssel kapcsolatban. Áttekintettünk
néhány configure paramétert, melyekkel a feldolgozó képességeit befolyásol-
hatjuk. Tanultunk a php.ini fájlról és néhány beállítási lehetõségrõl, amit meg-
adhatunk benne. Végül megnéztük, hol találhatunk segítséget, ha problémáink
akadnak. Ezzel készen állunk arra, hogy megbirkózzunk a PHP nyelvvel.
Kérdések és válaszok
A telepítést Apache webkiszolgálót használó Linux operációs rendszeren
vezettük végig. Ez azt jelenti, hogy a könyv nem megfelelõ más rendszer
vagy kiszolgálóprogram használata esetén?
A PHP egyik nagy erõssége, hogy több rendszeren is képes futni. Ha problémák
adódnak az adott rendszeren a PHP telepítésével, olvassuk el a csomagban talál-
ható dokumentációt és a PHP kézikönyv megfelelõ fejezetét. Általában széles körû
lépésrõl-lépésre leírt utasításokat kapunk a telepítéshez. Ha továbbra sem sikerül
megoldani a problémát, a Segítség! címû részben ismertetett módszerek célrave-
zetõk lehetnek.
02_ora.qxd 8/3/2001 6:10 PM Page 22
22 2. óra
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Hol érhetõ el a PHP kézikönyv?
Feladatok
1. Telepítsük a PHP-t. Ha sikerült, nézzük át a PHP beállítófájlt és ellenõrizzük
a telepítés helyességét.
03_ora.qxd 8/3/2001 6:10 PM Page 23
3.ÓRA
Elsõ PHP oldalunk
A PHP telepítése és beállítása után eljött az ideje, hogy elkezdjünk vele dolgozni.
Ebben az órában elkészítjük az elsõ programunkat és elemezzük a kódot. Az óra
végére képesek leszünk olyan oldalak készítésére, amelyek HTML és PHP kódot is
tartalmaznak.
24 3. óra
Elsõ programunk
Vágjunk a közepébe és kezdjük egy kész PHP oldallal! A kezdéshez nyissuk meg
kedvenc szövegfájl-szerkesztõnket! A HTML dokumentumokhoz hasonlóan a PHP
állományok is formázás nélküliek, tisztán szövegfájlok. Ez azt jelenti, hogy bármi-
lyen szövegfájl szerkesztésére íródott programmal készíthetünk PHP állományokat.
Ilyenek például a Windows Jegyzettömbje, a Simple Text vagy a BBEdit MacOS
alatt, vagy a VI és az Emacs UNIX esetében. A legnépszerûbb HTML-szerkesztõk
általában nyújtanak valamilyen különleges támogatást PHP-szerkesztéshez is.
Ilyenek például a kódszínezés, a kifejezésszerkesztõ vagy a tesztelõ.
3.1. ábra
Elsõ PHP oldalunk
begépelve a KEdit
programban
A kiterjesztés igen fontos, mivel ez jelzi a kiszolgáló számára, hogy a fájl PHP kó-
dot tartalmaz és futtatásához meg kell hívni a feldolgozót. Az alapbeállítású PHP
kiterjesztés a .php, ez azonban a kiszolgáló beállításainak módosításával megvál-
toztatható. Ezzel az elõzõ órában részletesen foglalkoztunk.
3.2. ábra
Siker: a 3.1. program
kimenete
3.3. ábra
Kudarc: a kiterjesztés
nem azonosítható
26 3. óra
A 3.1. táblázatban látható lehetõségek közül csak az elsõ és az utolsó áll minden
beállítás esetén rendelkezésre. A rövid és ASP stílusú elemeket engedélyezni kell
a php.ini fájlban. Az elõzõ órában tárgyaltuk a beállítás módszerét.
short_open_tag = On
asp_tags = On
Ez akkor lehet hasznos, ha olyan termékkel készítünk PHP oldalakat, amely törli
a PHP blokkokat, de az ASP részeket érintetlenül hagyja.
Nézzük meg, hogyan fest egy PHP fájl, amely a fent említett formákat használja az
elõzõ program kibõvítéseként. Ha engedélyeztük, bármely négy kezdõ- és
záróelemet használhatjuk a programban:
<?
print ("Hello Web!");
?>
<?php
print ("Hello Web!");
?>
<%
print ("Hello Web!");
%>
3
<SCRIPT LANGUAGE="PHP">
print ("Hello Web!");
</SCRIPT>
Ha PHP-ben egysoros kódot írunk, nem kell külön sorba tennünk a kezdõ- és
záróelemeket, illetve a programsort:
A print() függvény
A print() függvény kiírja a kapott adatokat. A legtöbb esetben minden,
ami a print() függvény kimenetén megjelenik, a böngészõhöz kerül. A függvé-
nyek olyan parancsok, amelyek valamilyen mûveletet végeznek, többnyire attól
függõen, hogy milyen adatokat kapnak. A függvényeknek átadott adatokat majd-
nem mindig zárójelbe kell tennünk a függvény neve után. Ebben az esetben
a print() függvénynek egy karakterláncot adtunk át. A karakterláncokat mindig
(egyes vagy kettõs) idézõjelbe kell tenni.
28 3. óra
Mivel a 3.1. programban az egyetlen megadott utasítás a blokk végén áll, a pon-
tosvesszõ elhagyható.
Látható, hogy HTML kód beépítése a PHP oldalakba egyszerûen a HTML tartalom
begépelésébõl áll. A PHP feldolgozó figyelmen kívül hagy mindent a PHP nyitó-
és záróelemeken kívül. Ha a 3.2. programot megnézzük böngészõvel, a Hello
Web! szöveget látjuk vastagon, mint ahogy ez a 3.4. ábrán megfigyelhetõ. Ha
a dokumentum forrását is megnézzük, ahogy a 3.5. ábra mutatja, a kód hagyomá-
nyos HTML dokumentumnak tûnik.
03_ora.qxd 8/3/2001 6:10 PM Page 29
3.4. ábra
Ha a 3.2 programot
megnézzük böngé-
szõvel, a Hello Web!
szöveget látjuk
vastagon
3
3.5. ábra
Ha a dokumentum
forrását nézzük, a
kód hagyományos
HTML dokumen-
tumnak tûnik
03_ora.qxd 8/3/2001 6:10 PM Page 30
30 3. óra
A PHP egysoros megjegyzései két perjellel (//) vagy egy kettõskereszt karakterrel
(#) kezdõdhetnek. Az ezen jelzések után található szöveget a PHP-értelmezõ
mindig figyelmen kívül hagyja, a sor vagy a PHP blokk végéig.
// Ez megjegyzés
# Ez is megjegyzés
/*
Ez egy megjegyzés.
A PHP-értelmezõ
ezen sorok egyikét
sem fogja feldolgozni.
*/
Összefoglalás
Mostanra rendelkezésünkre állnak azok az eszközök, melyekkel képesek vagyunk
egy egyszerû PHP program futtatására egy megfelelõen beállított kiszolgálón.
Kérdések és válaszok
Melyik a legjobb kezdõ- és záróelem?
Ez nagyrészt saját döntésünkön múlik. A hordozhatóság szem elõtt tartásával
a hagyományos <?php ?> megoldás a legjobb döntés. A rövid kezdõelemek alap-
esetben engedélyezettek és rendelkeznek a tömörség elõnyös tulajdonságával.
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. A felhasználó böngészõjével elolvashatja-e a PHP kódot?
Feladatok
1. Gyakoroljuk a PHP oldalak elkészítését, feltöltését és futtatását!
04_ora.qxd 8/3/2001 6:10 PM Page 33
II. RÉSZ
A PHP nyelv
4. óra Az alkotóelemek
5. óra Vezérlési szerkezetek
6. óra Függvények
7. óra Tömbök
8. óra Objektumok
04_ora.qxd 8/3/2001 6:10 PM Page 34
04_ora.qxd 8/3/2001 6:10 PM Page 35
4. ÓRA
Az alkotóelemek
Ebben az órában már mélyebben elmerülünk a nyelv rejtelmeiben. Az alapokkal
kezdünk, így a kezdõ programozónak rengeteg új információt kell majd feldol-
goznia. Aggodalomra azonban semmi ok, bármikor vissza lehet lapozni a könyv-
ben. A lényeg, hogy a fejezetben leírtak megértésére törekedjünk, ne csupán
a memorizálásra.
A gyakorlott programozóknak is ajánlatos legalábbis átlapozniuk ezen óra anya-
gát. Az órában a következõket tanuljuk meg:
36 4. óra
Változók
A változók különleges tárolók, amiket abból a célból hozunk létre, hogy értéket he-
lyezzünk el bennük. A változók egy dollárjelbõl ($) és egy tetszõlegesen választott
névbõl tevõdnek össze. A név betûket, számokat és aláhúzás karaktereket (_) tartal-
mazhat (számmal azonban nem kezdõdhet!), szóközöket és más olyan karaktereket,
amelyek nem számok vagy betûk, nem. Íme néhány érvényes változónév:
$a;
$egy_hosszabb_valtozonev;
$elalszom_zzzzzzzzzzzzzz;
Ne feledjük, hogy a pontosvesszõ (;) a PHP utasítás végét jelzi, így az elõzõekben
a pontosvesszõ nem része a változók nevének.
Amint látjuk, rengeteg féle nevet adhatunk változóinknak, bár a csak számokból
álló változónevek nem szokványosak. Változó létrehozásához (deklarálásához, va-
gyis bevezetéséhez) egyszerûen csak bele kell írni azt a programunkba. Létreho-
záskor általában rögtön értéket is szoktunk adni a változónak.
$szam1 = 8;
$szam2 = 23;
Itt két változót hoztunk létre és a hozzárendelõ mûveletjellel (=) értéket is adtunk
azoknak. Az értékadásról bõvebben a Mûveletjelek és kifejezések címû részben ta-
nulunk, az óra késõbbi részében. Miután értéket adtunk változóinknak, úgy kezel-
hetjük azokat, mintha maguk lennének az értékek. Vagyis a fenti példánál marad-
va a létrehozás után írt
print $szam1;
hatása megegyezik a
print 8;
Az alkotóelemek 37
Dinamikus változók
Változót tehát úgy hozunk létre, hogy egy dollárjel után írjuk a változó nevét. Szo-
katlan, ám hasznos, hogy a változó nevét is tárolhatjuk változóban. Tehát ha az
alábbi módon értéket rendelünk egy változóhoz
$felhasznalo = "Anna";
$tarolo = "felhasznalo";
$$tarolo = "Anna";
$felhasznalo = "Anna";
print $felhasznalo;
azonos a
$felhasznalo = "Anna";
$tarolo = "felhasznalo";
print $$tarolo;
kóddal, eltekintve természetesen attól, hogy itt létrehoztunk egy $tarolo nevû
változót, melynek értéke "felhasznalo".
04_ora.qxd 8/3/2001 6:10 PM Page 38
38 4. óra
$felhasznalo = "Anna";
$tarolo = "felhasznalo";
print "$$tarolo";
a böngészõ nem az "Anna" szöveget jeleníti meg, mint ahogy várnánk, hanem
kiírja a dollárjelet, majd a "felhasznalo" szöveget, vagyis összességében azt,
hogy "$felhasznalo".
$felhasznalo = "Anna";
$tarolo = "felhasznalo";
print "${$tarolo}";
már az "Anna" szöveget írja ki, ami a $felhasznalo nevû változó értéke.
Az alkotóelemek 39
Hivatkozások a változókra
A PHP alapértelmezés szerint értékadáskor a változók értékeit használja. Ez azt jele-
nti, hogy ha az $egyikValtozo-t hozzárendeljük egy $masikValtozo-hoz,
akkor a $masikValtozo-ba az $egyikValtozo értékének másolata kerül.
Az $egyikValtozo tartalmának késõbbi módosítása nincs semmiféle hatással 4
a $masikValtozo-ra. A 4.2. példaprogram ezt mutatja be.
40 4. óra
Az alkotóelemek 41
Adattípusok
A különféle típusú adatok több-kevesebb helyet foglalnak a memóriában, a nyelv
pedig mindegyiket némileg más módon kezeli. Ezért néhány programozási nyelv
megköveteli, hogy a programozó elõre meghatározza a változótípusát. A PHP 4
gyengén típusos, ami azt jelenti, hogy az adattípusokat úgy kezeli, mintha a típus
az adathoz rendelt kiegészítõ információ lenne. A PHP vegyes megközelítést hasz-
nál. Egyfelõl ez azt jelenti, hogy a változók rugalmasan használhatók: egyszer
karakterlánc, másszor esetleg szám lehet bennük. Másfelõl, nagyobb méretû prog-
ramokban zavar forrása lehet, ha egy adott típusú változót várunk egy változóban,
miközben valami teljesen más van benne.
A 4.1. táblázat a PHP 4-ben elérhetõ hat fontosabb adattípust tartalmazza, rövid le-
írással és példával.
42 4. óra
integer
string
double
boolean
Az integer egész szám, vagyis olyan szám, amelyben nincs tizedesjegy (tizedes-
pont).
Az alkotóelemek 43
44 4. óra
Az alkotóelemek 45
Mûveletjelek és kifejezések
Most már képesek vagyunk adatokat helyezni változóinkba, meghatározhatjuk,
sõt meg is változtathatjuk egy változó típusát. Egy programozási nyelv azonban
nem túl hasznos, ha a tárolt adatokkal nem végezhetünk mûveleteket. A mûvelet-
jelek (operátorok) olyan jelek, amelyek azon mûveleteket jelzik, melyek lehetõvé
teszik, hogy egy vagy több értékbõl egy új értéket hozzunk létre. Az értéket,
amellyel a mûveletet végezzük, operandusnak hívjuk.
46 4. óra
4 + 5
Hozzárendelés
Már találkoztunk a hozzárendelõ mûveletjellel, valahányszor értéket adtunk válto-
zóinknak. A hozzárendelõ operátor egyetlen karakterbõl áll, az egyenlõségjelbõl
(=). Jelentése: a mûveletjel jobb oldalán álló kifejezés értékét hozzárendeljük a bal
oldali operandushoz.
Az alkotóelemek 47
Aritmetikai mûveletek
Az aritmetikai mûveletek pontosan azt teszik, amit elvárunk tõlük. A 4.2. táblázat
a megfelelõ mûveletjeleket sorolja fel. Az összeadó mûveletjel hozzáadja a jobb
oldali operandust a bal oldalihoz, a kivonó mûveletjel a jobb oldali operandust
kivonja a bal oldaliból, az osztó mûveletjel a bal oldali operandust elosztja a jobb
oldalival, a szorzó mûveletjel pedig összeszorozza a bal és a jobb oldali
operandusokat. A maradékképzõ (modulus) mûveletjel a bal és a jobb operandus
egész osztásának maradékát adja.
Összefûzés
Az összefûzés jele a pont (.). Mindkét operandust karakterláncnak tekintve,
a jobb oldali elemet hozzáfûzi a bal oldalihoz. Vagyis a
kifejezés értéke:
"Para Zita"
48 4. óra
$x = 4;
$x += 4; // $x most 8
$x = 4;
$x = $x + 4; // $x most 8
A 4.3. táblázat minden példájában a $x változó értéke változik meg, a jobb oldali
operandusnak megfelelõen.
Összehasonlítás
Az összehasonlító mûveletek az operandusokon vizsgálatokat végeznek. Logikai
értékkel térnek vissza, vagyis értékük true lesz, ha a feltételezett viszony fennáll,
és false, ha nem. Ez a típusú kifejezés az olyan vezérlési szerkezetekben hasz-
nos, mint az if és while utasítások. Ezekkel az ötödik órában találkozunk majd.
Ha meg szeretnénk vizsgálni, hogy az $x-ben tárolt érték kisebb-e 5-nél, a kisebb,
mint jelet használhatjuk:
$x < 5
04_ora.qxd 8/3/2001 6:10 PM Page 49
Az alkotóelemek 49
true || false
50 4. óra
Az alkotóelemek 51
$x = $x + 1; // $x értéke eggyel nõ
$x += 1; // $x értéke eggyel nõ
Ha hasonló módon két mínuszjelet írunk a változó neve után, a változó értéke
eggyel csökken.
$x = 3;
$x++ < 4; // igaz
52 4. óra
$x = 3;
++$x < 4; // hamis
4 + 5
4 + 5 * 2
Itt már egy problémával találkozunk szembe: a kifejezés azt jelenti, hogy vedd
a négyet és az ötöt, add össze õket, majd az eredményt szorozd meg kettõvel,
vagyis 18 az értéke? Esetleg azt, hogy add hozzá a négyhez az öt és a kettõ
szorzatát, vagyis az eredmény 14? Ha egyszerûen balról jobbra olvasnánk, akkor
az elsõ változatot kellene elfogadnunk. A PHP-ben azonban minden mûveletjelhez
tartozik egy elsõbbségi tényezõ (prioritás). Mivel a szorzás elsõbbséget élvez az
összeadással szemben, így (iskolai tanulmányainkkal összhangban) a második vá-
lasz a helyes megoldás.
( 4 + 5 ) * 2
Az alkotóelemek 53
$x || $y and $z
( $x || $y ) && $z
Állandók
A változók rugalmas adattárolási lehetõséget nyújtanak számunkra. Megváltoztat-
hatjuk értéküket, sõt típusukat is, bármely pillanatban. Ha azonban azt szeretnénk,
hogy egy adott név alatt tárolt érték ne változzon a program futása során, létrehoz-
hatunk állandókat (konstansokat) is. Ezt a PHP beépített define() függvénye
segítségével tehetjük meg. Miután az állandót létrehoztuk, annak értékét nem
szabad (nem tudjuk) megváltoztatni. Az állandó nevét, mint karakterláncot és
az értéket vesszõvel elválasztva a zárójeleken belülre kell írnunk.
Az állandó értéke természetesen lehet szám, karakterlánc vagy logikai típusú is.
Az a szokás, hogy az állandók neve CSUPA NAGYBETÛBÕL áll. Az állandók neve
nem tartalmaz dollárjelet, így az állandók elérése csupán a név leírásából áll.
04_ora.qxd 8/3/2001 6:10 PM Page 54
54 4. óra
Összefoglalás
Ebben az órában végigvettük a PHP nyelv néhány alapvetõ tulajdonságát. Tanul-
tunk a változókról és arról, hogyan rendelhetünk hozzájuk értéket. Hallottunk
a dinamikus, vagyis változó változókról. Megtanultuk azt is, hogyan kell a válto-
zó értékének másolata helyett a változókra hivatkozni. Új mûveletjeleket ismer-
tünk meg és megtanultuk, hogyan kell azokat összetettebb kifejezésekké össze-
gyúrni. Végül megtanultuk, hogyan kell állandókat létrehozni és használni.
04_ora.qxd 8/3/2001 6:10 PM Page 55
Az alkotóelemek 55
Kérdések és válaszok
Mikor kell tudnunk egy változó típusát?
Elõfordul, hogy a változó típusa behatárolja, milyen mûveleteket végezhetünk vele.
Például mielõtt egy matematikai kifejezésben használunk egy változót, megnézhet-
jük, hogy egyáltalán egész vagy lebegõpontos számot tartalmaz-e. Az ehhez hason-
ló kérdésekkel kicsit késõbb, a tizenhatodik fejezetben foglalkozunk.
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Az alábbiak közül melyek NEM lehetnek változónevek?
$egy_felhasznalo_altal_elkuldott_ertek
$44444444444xyz
$xyz44444444444
$______________szamlalo______________
$az elso
$fajl-nev
56 4. óra
Feladatok
1. Készítsünk programot, amely legalább öt különbözõ változót tartalmaz.
Adjunk nekik különbözõ típusú értékeket, majd használjuk a gettype()
függvényt a változók típusainak meghatározására.
5. ÓRA
Vezérlési szerkezetek
Az elõzõ órában létrehozott programok minden futtatáskor ugyanazt az eredményt
adták, mindig ugyanazok az utasítások hajtódtak végre ugyanabban a sorrendben.
Ez nem biztosít túl nagy teret a rugalmasságnak.
58 5. óra
Elágazások
A legtöbb program feltételeket értékel ki és azok eredményének megfelelõen
változtatja viselkedését. A lehetõséget, hogy a PHP oldalak tartalma dinamikussá
váljék, az teszi lehetõvé, hogy a programok kimenete bizonyos feltételektõl
függhet. A legtöbb programozási nyelvhez hasonlóan a PHP 4-es változata is
biztosítja erre a célra az if utasítást.
Az if utasítás
Az if utasítás kiértékeli a zárójelek közötti kifejezést. Ha a kifejezés értéke igaz,
az utasításhoz tartozó programrész végrehajtódik. Ha a kifejezés hamis, a blokk
egyszerûen figyelmen kívül marad. Ez teszi lehetõvé a programoknak, hogy
döntéseket hozzanak.
if ( kifejezés )
{
// ha a kifejezés értéke igaz,
// ez a blokk végrehajtódik
}
Vezérlési szerkezetek 59
if ( $hangulat == "boldog" )
print "Hurrá, jó kedvem van!";
if (feltétel)
{
// itt következik az a programrész, amely akkor kerül
// végrehajtásra, ha a feltétel értéke igaz
}
5
else
{
// itt pedig az a programrész található, amely akkor fut le,
// ha a feltétel értéke hamis
}
60 5. óra
if ( feltétel )
{
// ez a rész akkor fut le, ha a feltétel igaz
}
elseif ( másik feltétel )
{
// ez a rész akkor fut le, ha a másik feltétel igaz,
// és minden elõzõ feltétel hamis
}
// itt még tetszõleges számú elseif rész következhet
05_ora.qxd 8/3/2001 6:11 PM Page 61
Vezérlési szerkezetek 61
else
{
// ez a rész akkor kerül végrehajtásra, ha egyik
// feltétel sem volt igaz
}
Ha az elsõ feltétel értéke hamis, a hozzá tartozó programrész nem kerül végre-
hajtásra. Ezután a PHP megvizsgálja az elseif kifejezés értékét. Ha a kifejezés
igaz, a hozzá tartozó programblokk fut le. Végül, ha egyik feltétel sem igaz,
az else utáni rész kerül végrehajtásra. Annyi elseif-et írhatunk a programba,
amennyi csak jólesik. Sõt, ha nincs szükségünk else ágra, vagyis olyan program-
részre, amely akkor hajtódik végre, ha egyik feltétel sem igaz, akár el is hagyhatjuk.
62 5. óra
A switch utasítás
A switch utasítás egy lehetséges módja annak, hogy egy kódrészletet egy kifeje-
zés értékétõl függõen hajtsunk végre. Van azonban néhány különbség az imént
tanult if és a switch között. Az if-et az elseif-fel használva több kifejezés
értékétõl tehetjük függõvé, hogy mi történjen. A switch esetében a program
csak egy kifejezést vizsgál meg és annak értékétõl függõen különbözõ sorokat
futtat. A kifejezésnek egyszerû típusnak kell lennie (szám, karakterlánc vagy
logikai érték). Az if feltétele csak igaz vagy hamis lehet, a switch kifejezését
akárhány értékkel összehasonlíthatjuk. De nézzük inkább az általános szerkezetet:
switch ( kifejezés )
{
case érték1:
// ez történjen, ha kifejezés értéke érték1
break;
case érték2:
// ez történjen, ha kifejezés értéke érték2
break;
default:
// ez történjen, ha a kifejezés értéke
// egyik felsorolt értékkel sem egyezett meg
break;
// az ördög nem alszik, jobban járunk, ha kitesszük
// ezt a felesleges break utasítást
}
Vezérlési szerkezetek 63
switch( $hetnapja )
{
case "Péntek":
print "Kikapcsolni a vekkert, holnap nem kell
dolgozni!<br>";
case "Hétfõ":
case "Szerda":
print "Ma délelõtt dolgozom<br>";
break;
case "Kedd":
case "Csütörtök":
print "Ma délután dolgozom<br>";
break;
case "Vasárnap":
print "Bekapcsolni a vekkert!<br>";
case "Szombat":
print "Hurrá, szabadnap!<br>";
break;
default:
print "Azt hiszem ideje lenne egy új programo-
5
zót és/vagy egy jobb naptárat
keríteni<br>";
break;
}
A fenti kis program azt közli, mikor kell mennünk dolgozni és az ébresztõóra keze-
lésében is segít. A programot úgy építettük fel, hogy több esetben is ugyanazt a kó-
dot kelljen végrehajtani, így hasznos, hogy nem adtuk meg minden case címkénél
a break utasítást. Elég gyakori azonban, hogy a kezdõ programozó elfelejti meg-
adni a break utasítást. Hasonló helyzetekben jusson eszünkbe ez a példa.
64 5. óra
A ?: mûveletjel
A ?: ternális (háromoperandusú) mûveletjel egy olyan if utasításhoz hasonlít,
amely értéket is képes visszaadni. A visszaadott értéket a vizsgált feltétel
határozza meg:
Vezérlési szerkezetek 65
Ciklusok
Most már láttuk, hogyan kell döntések eredményétõl függõen különbözõ program-
részleteket futtatni. PHP programokkal arra is képesek vagyunk, hogy megmond-
juk, hányszor kell lefuttatni egy adott programrészt. Erre valók a ciklusok. Segítsé-
gükkel elérhetjük, hogy egyes programrészletek ismétlõdjenek. Szinte kivétel
nélkül igaz, hogy egy ciklus addig fut, amíg egy feltétel teljesül, vagy meg nem
mondjuk, hogy fejezõdjön be az ismétlés.
05_ora.qxd 8/3/2001 6:11 PM Page 66
66 5. óra
A while ciklus
A while ciklus szerkezete rendkívül hasonlít az if elágazáséhoz:
while ( feltétel )
{
// valamilyen tevékenység
}
Amíg a while feltétele igaz, a hozzá tartozó programrész újból és újból végrehaj-
tódik. A programrészen belül általában megváltoztatunk valamit, ami hatással lesz
a while feltételére; ha ezt nem tesszük meg, a ciklusunk a végtelenségig futni
fog. Az 5.6. példaprogram a while ciklus segítségével írja ki a kettes szorzótáblát.
Vezérlési szerkezetek 67
A do..while ciklus
A do..while ciklus kicsit hasonlít a while-hoz. A lényegi különbség abban van,
hogy ebben a szerkezetben elõször hajtódik végre a kód és csak azután értékelõdik
ki a feltétel:
do
{
// végrehajtandó programrész
} while ( feltétel );
A do..while ciklus megnézi, hogy a $szam változó értéke 200 és 400 között
van-e. Mivel a $szam változónak az 1 kezdeti értéket adtuk, így a feltétel hamis.
Ennek ellenére a programblokk egyszer végrehajtódik, mégpedig a feltétel kiérté-
kelése elõtt, ezért a böngészõben egy sor kiírásra kerül.
05_ora.qxd 8/3/2001 6:11 PM Page 68
68 5. óra
A for ciklus
A for semmi újat nem nyújt a while ciklushoz képest. A for ciklus használatával
azonban sokszor takarosabb, biztonságosabb módon közelíthetjük meg ugyanazt
a problémát. Korábban az 5.6. példaprogramban létrehoztunk egy változót
a while cikluson kívül, majd a while kifejezése megvizsgálta ennek a változónak
az értékét. Végül a változó értékét a ciklus végén eggyel növeltük. A for ciklus
mindezt egyetlen sorban teszi lehetõvé. Ez tömörebb programot eredményez és rit-
kábban fordulhat elõ, hogy a változót elfelejtjük növelni, ami végtelen ciklust okoz.
változó_hozzárendelése;
while ( feltétel )
{
// a végrehajtandó programblokk
számláló_növelése;
}
Vezérlési szerkezetek 69
70 5. óra
Vezérlési szerkezetek 71
72 5. óra
Vezérlési szerkezetek 73
A külsõ for ciklus az $y változónak az 1 kezdeti értéket adja. A ciklus addig fog
futni, amíg a változó nem nagyobb 12-nél, az utolsó kifejezés pedig biztosítja,
hogy $y értéke minden ismétlés után eggyel nõjön. A ciklus törzse minden ismét-
lés során kiír egy tr (table row táblázatsor) HTML elemet, majd egy újabb
for ciklus kezdõdik. A belsõ ciklus az $x változó értékét a külsõ ciklushoz
hasonlóan végigfuttatja 1-tõl 12-ig. A ciklus törzsében egy td (table data
táblázatcella) elemet ír ki, amelybe az $x*$y érték kerül. Az eredmény egy
ízlésesen formázott szorzótábla lesz.
Összefoglalás
Ebben az órában a vezérlési szerkezetekrõl tanultunk és arról, hogyan segítenek
minket programjaink változatosabbá és rugalmasabbá tételében. A legtöbb megta-
nult szerkezet újból és újból meg fog jelenni a könyv hátralevõ részében.
Megtanultuk, hogyan hozzunk létre if utasításokat, hogyan egészítsük ki azokat
elseif és else ágakkal. Hallottunk arról, hogyan használjuk a switch utasítást,
hogy egy kifejezés adott értékei esetén más és más történjen. Tanultunk a ciklusok-
ról, pontosabban a while és a for ciklusokról, és arról, hogy a break és
5
a continue utasítások segítségével hogyan léphetünk ki végleg a ciklusból, illetve
hogyan hagyhatunk ki egy-egy ismétlést. Végül megtanultuk, hogyan kell cikluso-
kat egymásba ágyazni és erre gyakorlati példát is láttunk.
Kérdések és válaszok
A vezérlési szerkezetek feltételes kifejezéseinek mindenképpen logikai
értéket kell adniuk?
Végsõ soron igen, bár a feltételes kifejezéseknél a kiértékelés szempontjából min-
den, ami nulla, üres karakterlánc vagy nem meghatározott változó, false-nak,
minden egyéb true-nak számít.
74 5. óra
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Hogyan használnánk az if vezérlési szerkezetet olyan program írására, hogy
ha az $eletkor változó értéke 18 és 35 között van, az
"Üzenet fiataloknak" szöveget írja ki? Ha az $eletkor értéke
bármi más, az "Általános üzenet" szöveg jelenjen meg a böngészõben.
Feladatok
1. Nézzük végig a vezérlési szerkezetek utasításformáját! Gondoljuk végig,
hogyan lehetnek ezek a szerkezetek a segítségünkre!
6. ÓRA
Függvények
A függvény a jól szervezett program lelke, mert a programot könnyen olvashatóvá és
újrahasznosíthatóvá teszi. Függvények nélkül a nagy programok kezelhetetlenek len-
nének. Ebben az órában a függvényeket tanulmányozzuk és mutatunk rá néhány
példát, hogyan kímélhetnek meg minket az ismétlõdésekbõl adódó pluszmunká-
tól. Az órában a következõket tanuljuk meg:
76 6. óra
Ha a kedves Olvasónak egy süteményt kell csinálnia, maga süti meg. De ha több
ezret, akkor esetleg készít vagy beszerez egy süteménysütõ gépezetet. Hasonló-
képp, amikor elhatározzuk, hogy függvényt írunk, a legfontosabb szempont, amit
mérlegelnünk kell, az, hogy az ismétlõdések csökkentésével akkorává zsugorodik-
e a program, hogy rövidebb lesz a függvény használatával.
Függvények hívása
Kétféle függvény létezik: a nyelvbe beépített függvény és az általunk létrehozott
függvény. A PHP 4-ben rengeteg beépített függvény van. A könyv legelsõ
PHP oldala egyetlen függvényhívásból állt:
Függvények 77
78 6. óra
Függvények létrehozása
Függvényt a function kulcsszó segítségével hozhatunk létre:
Függvények 79
A fenti program egyszerûen kiírja a "HELLO" szöveget egy <H1> HTML elemben.
A programban egy olyan nagyHello() nevû függvényt hoztunk létre, amely
nem vesz át paramétereket. Ezért hagytuk üresen a zárójelpárt. Bár a nagyHello()
mûködõ függvény, mégsem túl hasznos. A 6.3. példaprogramban olyan függvényt
láthatunk, amely egy paramétert fogad és valami hasznosat csinál vele.
6.1. ábra
6
Függvény, amely egy
karakterláncot, majd
egy <br> HTML
elemet ír ki.
06_ora.qxd 8/3/2001 6:11 PM Page 80
80 6. óra
Függvények 81
A 6.4. példaprogram a 8-as számot írja ki. Az osszead() függvényt két paramé-
terrel kell meghívni (itt a két paraméter a 3 és az 5 volt). Ezek az $elsoszam és
a $masodikszam nevû változókban tárolódnak. Várhatóan az osszead()
függvény e két változó eredményét adja össze és tárolja az $eredmeny nevû
változóban. Az $eredmeny nevû segédváltozó használatát kiküszöbölhetjük:
return 4;
return ( $a / $b );
Dinamikus függvényhívások
Lehetõségünk van rá, hogy karakterláncba tegyük egy függvény nevét és ezt a vál-
tozót pontosan úgy tekintsük, mint ha maga a függvény neve lenne. Ezt a 6.5. pél-
daprogramon keresztül próbálhatjuk ki.
6
6.5. program Dinamikus függvényhívás
1: <html>
2: <head>
3: <title>6.5. program Dinamikus függvényhívás</title>
4: </head>
5: <body>
6: <?php
06_ora.qxd 8/3/2001 6:11 PM Page 82
82 6. óra
Miért jó ez? A fenti példában csak még több munkát csináltunk magunknak azzal,
hogy a "koszon" karakterláncot rendeltük a $fuggveny_tarolo nevû válto-
zóhoz. A dinamikus függvényhívás akkor igazán hasznos, ha a program folyását
bizonyos körülményektõl függõen változtatni szeretnénk. Például szeretnénk mást
és mást csinálni egy URL-kérés paraméterétõl függõen. Ezt a paramétert feldolgoz-
hatjuk és értékétõl függõen más és más függvényt hívhatunk meg.
Változók hatóköre
A függvényben használt változók az adott függvényre nézve helyiek maradnak.
Más szavakkal: a változó a függvényen kívülrõl vagy más függvényekbõl nem lesz
elérhetõ. Nagyobb projektek esetén ez megóvhat minket attól, hogy véletlenül két
függvény felülírja azonos nevû változóik tartalmát.
Függvények 83
6.2 ábra
Kísérlet függvényen
belüli változóra
hivatkozásra.
84 6. óra
6.3. ábra
Globális változó
elérési kísérlete
függvényen belülrõl
06_ora.qxd 8/3/2001 6:11 PM Page 85
Függvények 85
86 6. óra
Tegyük fel például, hogy tudni szeretnénk, hányszor fut le egy adott függvény.
Miért? Példánkban a függvény célja számozott címsor készítése, ami egy dinami-
kusan létrejövõ dokumentációt eredményez.
Függvények 87
6.5. ábra
A függvényhívások
számának nyomon
követése a global
kulcsszó használa-
tával
88 6. óra
Függvények 89
90 6. óra
6.6. ábra
Függvény, amely
formázott karakter-
láncokat ír ki a bön-
gészõbe
Függvények 91
92 6. óra
Lehetõségünk van arra is, hogy ne a változó értékét, hanem arra mutató hivatko-
zást adjunk át. (Ezt cím szerinti paraméterátadásnak is hívják.) Ez azt jelenti, hogy
a változóra mutató hivatkozással dolgozunk a függvényben és nem a változó érté-
kének másolatával. A paraméteren végzett bármilyen mûvelet megváltoztatja az
eredeti változó értékét is. Hivatkozásokat függvényeknek úgy adhatunk át, hogy
az átadandó változó vagy a paraméter neve elé egy & jelet teszünk. A 6.14. és
a 6.15. példaprogram az elõzõ problémára mutatja be a két elõbb említett
módszert.
Függvények 93
94 6. óra
Kérdések és válaszok
A global kulcsszón kívül van más mód arra, hogy egy függvény hozzá
tudjon férni vagy módosítani tudjon egy globális változót?
A globális változókat a programon belül bárhonnan elérhetjük a $GLOBALS nevû
asszociatív tömb segítségével. A $proba nevû globális változót például
$GLOBALS["proba"]-ként érhetjük el. Az asszociatív tömbökrõl a következõ
órában tanulunk.
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Igaz-e, hogy ha egy függvénynek nem kell paramétert átadni, akkor a függ-
vény neve után nem szükséges kitenni a zárójelpárt?
function tizszer()
{
$szam = $szam * 10;
}
tizszer();
print $szam;
06_ora.qxd 8/3/2001 6:11 PM Page 95
Függvények 95
function tizszer()
{
global $szam;
$szam = $szam * 10;
}
tizszer();
print $szam;
function tizszer($sz)
{
$sz = $sz * 10;
}
tizszer($szam);
print $szam;
function tizszer(&$sz)
{
$sz = $sz * 10;
}
$tizszer($szam);
6
print $szam;
Feladatok
1. Írjunk függvényt, amely négy karakterlánc típusú értéket fogad és olyan karak-
terlánccal tér vissza, amely paramétereit HTML cellaelemekbe (TD) zárja!
06_ora.qxd 8/3/2001 6:11 PM Page 96
07_ora.qxd 8/3/2001 6:16 PM Page 97
7. ÓRA
Tömbök
A tömbök és a kezelésüket segítõ eszközök nagy mértékben növelik a PHP 4
programok rugalmasságát. Ha jól értünk a tömbökhöz, képesek vagyunk nagy
méretû, összetett adatokat tárolni és kezelni.
98 7. óra
Tömbök 99
Tömbök létrehozása
A tömbök alapértelmezés szerint értékek számmal indexelt listái. Értéket egy
tömbhöz kétféleképpen is rendelhetünk: Az egyik mód az array() függvény,
a másik a tömbazonosító használata szögletes zárójelekkel ([]). A következõ két
részben mind a kétféle változattal találkozni fogunk.
print $felhasznalok[2];
Ne felejtsük el, hogy a tömbök indexelése nullától indul, így bármely tömbelem
indexe eggyel kisebb a tömbelem tömbbéli helyénél. (Az elsõ elem indexe 0,
a második elem indexe 1.)
7
Tömb létrehozása vagy elem hozzáadása a tömbhöz
szögletes zárójel segítségével
Tömböket úgy is létrehozhatunk, illetve meglevõ tömbökhöz új elemeket adha-
tunk, ha a tömb neve után olyan szögletes zárójelpárt írunk, amelynek belsejében
nincs index.
07_ora.qxd 8/3/2001 6:16 PM Page 100
100 7. óra
$felhasznalok[] = "Berci";
$felhasznalok[] = "Mariska";
$felhasznalok[] = "Aladár";
$felhasznalok[] = "Eleonóra";
Figyeljük meg, hogy nem kellett számot írnunk a szögletes zárójelbe. A PHP 4
automatikusan meghatározza az indexértéket, így nem kell nekünk bajlódni azzal,
hogy kiszámítsuk a következõ olyan indexet, amelyben még nincs érték.
$felhasznalok[0] = "Berci";
$felhasznalok[200] = "Mariska";
A tömbnek így mindössze két eleme van, de az utolsó elem indexe 200. A PHP 4
nem fog értéket adni a köztes elemeknek, ami félreértésekre adhat okot az elemek
elérésekor.
Asszociatív tömbök
A számmal indexelt tömbök akkor hasznosak, ha abban a sorrendben szeretnénk
tárolni az elemeket, amilyen sorrendben a tömbbe kerültek. Néha azonban jó lenne,
ha a tömb elemeit meg tudnánk nevezni. Az asszociatív tömb egy karakterláncokkal
indexelt tömb. Képzeljünk el egy telefonkönyvet: melyik a jobb megoldás: a név
mezõt a 4-gyel vagy a név-vel indexelni?
Tömbök 101
$karakter = array
(
"nev" => "János",
"tevekenyseg" => "szuperhõs",
"eletkor" => 30,
"kulonleges kepesseg" => "röntgenszem"
);
print $karakter["eletkor"];
7
ha egyszerûen a megnevezett elemhez (mezõhöz) új értéket adunk. Az alábbiak-
ban újra létrehozzuk a $karakter nevû tömböt, úgy, hogy az egyes kulcsokhoz
egyenként rendelünk értékeket.
07_ora.qxd 8/3/2001 6:16 PM Page 102
102 7. óra
Többdimenziós tömbök
Eddig azt mondtuk, hogy a tömbök elemei értékek. A $karakter tömbünkben
az elemek közül három karakterláncot tartalmaz, egy pedig egy egész számot.
A valóság ennél egy kicsit bonyolultabb. Egy tömbelem valójában lehet érték, ob-
jektum vagy akár egy másik tömb is. A többdimenziós tömb valójában tömbök
tömbje. Képzeljük el, hogy van egy tömbünk, amelynek tömbök az elemei. Ha el
akarjuk érni a második elem harmadik elemét, két indexet kell használnunk:
$tomb[1][2]
A tény, hogy egy tömbelem lehet tömb is, lehetõséget biztosít arra, hogy kifino-
multabb adatszerkezeteket kezeljünk viszonylag egyszerûen. A 7.1. példaprogram
egy tömböt ír le, amelynek elemei asszociatív tömbök.
Tömbök 103
7
07_ora.qxd 8/3/2001 6:16 PM Page 104
104 7. óra
Tömbök elérése
Eddig azt láttuk, hogyan kell tömböket létrehozni és elemeket adni azokhoz.
Most végignézünk néhány lehetõséget, amit a PHP 4 a tömbök elérésére biztosít.
print $felhasznalo[4];
A tömbök rugalmassága miatt nem mindig egyszerû feladat kideríteni, hány elem
van a tömbben. A PHP a count() függvényt biztosítja erre a feladatra.
A count() a tömbben levõ elemek számával tér vissza. Az alábbi programrész-
ben egy számokkal indexelt tömböt hozunk létre, majd a count() függvényt
használjuk a tömb utolsó elemének elérésére.
Figyeljük meg, hogy egyet ki kellett vonnunk a count() által visszaadott értékbõl.
Ez azért van így, mert a count() nem az utolsó elem indexét adja vissza, hanem
a tömbelemek számát.
A fenti kódot futtatva azt tapasztaljuk, hogy az "Az utolsó elem: " szöveg
után semmi nem íródik ki. Ez azért van, mert a tömbnek nincs 1 indexû eleme.
Az elsõ elem a 0 indexen található, a második a 2 indexen, mivel az értékadáskor
az indexet közvetlenül határoztuk meg.
A tömbök indexelése alapértelmezés szerint nullától indul, de ezt meg lehet
változtatni. Ha azonban világos és következetes programokat szeretnénk írni,
ne éljünk ezzel a lehetõséggel.
Tömb bejárása
Több módja van annak, hogy egy tömb minden elemét végigjárjuk. Mi most a PHP 4
igen hatékony foreach szerkezetét használjuk, de a tizenhatodik órában további
módszereket is megvizsgálunk.
07_ora.qxd 8/3/2001 6:16 PM Page 105
Tömbök 105
foreach($tombnev as $atmeneti)
{
}
7.1. ábra
Tömb bejárása
106 7. óra
Figyeljük meg, hogy annak ellenére, hogy a tömb lyukas, a program a foreach
szerkezet segítségével bejárt tömb minden elemét kiírta és az utolsó sor elõtt nem
jelentek meg üres sorok, tehát a 3 és 9 indexek közötti tömbelemeket (melyek
nem meghatározottak, vagyis üres karakterláncok) nem írja ki a program.
ahol $tomb a tömb neve, amin végig szeretnénk menni, $kulcs a változó,
amelyben az elem kulcsa jelenik meg, a $ertek pedig a kulcshoz tartozó tömb-
elem értéke.
Tömbök 107
7.2. ábra
Asszociatív tömb
bejárása
7
07_ora.qxd 8/3/2001 6:16 PM Page 108
108 7. óra
Tömbök 109
A 7.3. példaprogram kimenetét a 7.3. ábrán láthatjuk. Két foreach ciklust hasz-
nálunk. A külsõ ciklusban a számmal indexelt $karakterek tömb elemeit
vesszük végig, az egyes elemek pedig a $karakter nevû változóba kerülnek.
A $karakter maga is egy tömb, ezért ennek értékeit is egy foreach ciklussal
járjuk végig. Mivel a $karakter egy asszociatív tömb, a foreach szerkezetet
az ennek megfelelõ formában használjuk, a kulcs-érték párok pedig a $kulcs és
az $ertek változókba kerülnek.
Annak érdekében, hogy ez a módszer jól mûködjön, biztosnak kell lennünk abban,
hogy a $karakter változó valóban mindig tömböt tartalmaz. A kódot megbízha-
tóbbá tehetnénk, ha meghívnánk a $karakter változóra az is_array() függ-
vényt. Az is_array() függvény számára egy paramétert kell megadnunk.
A visszatérési érték true lesz, ha a változó típusa tömb, minden más esetben
false értéket ad.
110 7. óra
Mûveletek tömbökkel
Most már fel tudunk tölteni tömböket elemekkel, elérhetjük azokat, de a PHP ren-
geteg függvénnyel segíti a tömbök feldolgozását is. A Perlben jártas olvasó bizo-
nyára ismerõsnek fogja találni ezen függvények nagy részét.
Tömbök 111
Figyeljük meg, hogy a "$elso" karakterlánc elé egy fordított perjelet kellett
tennünk. Ha a PHP egy macskakörmös (kettõs idézõjeles) karakterláncban egy
dollárjelet követõ betû- és/vagy számsorozatot talál, változóként próbálja értel-
mezni azt és megkísérli az értékét beírni. A fenti példában mi a '$elso' karak-
tersorozatot szerettük volna megjeleníteni, ezért kellett a dollárjel elé a fordított
perjel karakter. Így a PHP már nem próbálja meg változóként értelmezni, hanem
kiírja a karaktereket. Ezt a módszert a szakirodalomban gyakran escape-ként
emlegetik.
112 7. óra
<?php
$egy_tomb = array( "a", "b", "c" );
7.4. ábra
A tömb egyes elemei-
nek törlése és kiíratá-
sa az array_shift()
függvény segítségével
Az array_shift() akkor lehet hasznos, amikor egy sor elemein kell valamilyen
tevékenységet végezni, amíg a sor ki nem ürül.
Tömbök 113
Az alábbi példában létrehozunk egy tömböt, majd egy új, három elemû tömböt ál-
lítunk elõ belõle:
A fenti példa a "c", "d" és "e" elemeket írja ki, a <br> kódelemmel elválasztva.
Mivel kezdõpozícióként a kettõt adtuk meg, így az elsõ elem, ami a $masodik
tömbbe kerül, az $elso[2].
7
Tömbök rendezése
Talán a rendezés a legnagyszerûbb mûvelet, amit egy tömbön el lehet végezni.
A PHP 4 függvényeinek köszönhetõen egykettõre rendet teremthetünk a káosz-
ban. A következõ rész néhány olyan függvényt mutat be, amelyek számmal és ka-
rakterlánccal indexelt tömböket rendeznek.
07_ora.qxd 8/3/2001 6:16 PM Page 114
114 7. óra
Tömbök 115
asort( $a_tomb );
foreach( $a_tomb as $kulcs => $ertek )
{
print "$kulcs = $ertek<br>";
}
7
Ennek a programocskának a kimenetét a 7.5. ábrán láthatjuk.
07_ora.qxd 8/3/2001 6:16 PM Page 116
116 7. óra
7.5. ábra
Asszociatív tömb
érték szerinti rende-
zése az asort() függ-
vény segítségével
ksort( $tomb );
7.6. ábra
Asszociatív tömb
rendezése kulcs
szerint a ksort() függ-
vény segítségével
07_ora.qxd 8/3/2001 6:16 PM Page 117
Tömbök 117
Összefoglalás
Ebben az órában a tömbökrõl és a hozzájuk kapcsolódó eszközökrõl tanultunk,
melyeket a PHP 4 a rajtuk végzett mûveletekhez nyújt. Most már tudunk normál
(számmal indexelt) és asszociatív (karakterlánccal indexelt) tömböket is létrehozni,
illetve tömböket bejárni a foreach ciklus segítségével.
Többdimenziós tömböket is létre tudunk hozni, a bennük levõ információt pedig
ki tudjuk nyerni egymásba ágyazott foreach ciklusokkal. A tömbökhöz egyszerre
több elemet is adhatunk, illetve onnan kivehetünk. Végül megtanultuk, hogy
a PHP 4-es változata milyen lehetõségeket nyújt a tömbök rendezésére.
Kérdések és válaszok
Ha a foreach ciklus csak a PHP 4-esben került a nyelvbe, akkor a PHP 3-as
változatát használó programozók hogyan jártak végig egy tömböt?
A PHP 3-asban az each() függvényt használták egy while() ciklusban.
Errõl bõvebben a tizenhatodik órában olvashatunk.
Mûhely
7
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Melyik függvénnyel hozhatunk létre tömböket?
118 7. óra
Feladatok
1. Hozzunk létre egy többdimenziós tömböt, amely filmeket tartalmaz, zsáner
szerint rendezve! Pontosabban hozzunk létre egy asszociatív tömböt, amelynek
kulcsai filmtípusok ("Scifi", "Akció", "Romantikus"
)! A tömb elemei
legyenek tömbök, amelyek filmcímeket tartalmaznak ("2001", "Alien",
"Terminator",...)!
8. ÓRA
Objektumok
Az objektumközpontú programozás veszélyes. Megváltoztatja a programozásról való
gondolkodásmódunkat és ha egyszer a hatalmába kerít, nem tudunk tõle szabadul-
ni. A PHP a Perlhöz hasonlóan fokozatosan építette be az objektumközpontúságot
a nyelvtanba. A PHP 4-es változatának megjelenésével képessé váltunk arra, hogy
programjainkat teljes mértékben objektumközpontú szemléletmódban írjuk.
120 8. óra
Objektumok 121
Objektum létrehozása
Ahhoz, hogy létre tudjunk hozni egy objektumot, elõször létre kell hozni
a sablont, amelyre épül. Ezt a sablont hívjuk osztálynak. A PHP 4-es változatában
ilyen sablont a class kulcsszóval hozhatunk létre:
class elso_osztaly
{
// ez egy nagyon buta osztály
}
Objektumtulajdonságok
Az objektumok a tulajdonság néven említett különleges változók révén mûköd-
nek. Ezek az osztályban bárhol létrehozhatók, de az átláthatóság kedvéért
az osztálymeghatározás elejére célszerû kigyûjteni azokat, így mi is ezt tesszük.
A tulajdonságok lehetnek értékek, tömbök, de más objektumok is:
class elso_osztaly
{
var $nev = "Gizike"; 8
}
08_ora.qxd 8/3/2001 6:19 PM Page 122
122 8. óra
Figyeljük meg, hogy a változót a var kulcsszó segítségével hoztuk létre; ha ezt egy
osztályon belül nem írjuk ki, értelmezési hibát (parse error) kapunk. Most, hogy ezt
a változót létrehoztuk, minden elso_osztaly típusú objektumnak lesz egy nev
tulajdonsága, melynek "Gizike" lesz a kezdeti értéke. Ehhez a tulajdonsághoz az
objektumon kívülrõl is hozzá lehet férni, sõt meg is lehet változtatni:
class elso_osztaly
{
var $nev = "Gizike";
}
$obj1 = new elso_osztaly();
$obj2 = new elso_osztaly();
$obj1->nev = "Bonifác";
print "$obj1->nev<br>";
print "$obj1->nev<br>";
A -> mûveletjel teszi lehetõvé, hogy egy objektum tulajdonságait elérhessük vagy
módosíthassuk. Bár az $obj1 és az $obj2 objektumokat "Gizike" névvel
hoztuk létre, rábírtuk az $obj2 objektumot, hogy meggondolja magát, a nev
tulajdonsághoz a "Bonifác" értéket rendelve, mielõtt a -> jelet ismét használva
kiítuk volna mindkét objektum nev tulajdonságának értékét.
Az objektumok tagfüggvényei
A tagfüggvény olyan függvény, amelyet egy osztályon belül hozunk létre. Minden
objektumpéldány képes meghívni osztálya tagfüggvényeit. A 8.1. példaprogram
az elso_osztaly nevû osztályt egy tagfüggvénnyel egészíti ki.
08_ora.qxd 8/3/2001 6:19 PM Page 123
Objektumok 123
124 8. óra
Objektumok 125
Még mindig van egy fogás, amit nem ismertünk meg. Ha egy metódusnak éppen
azt a nevet adjuk, mint az osztálynak (az elõzõ példában ez az elso_osztaly),
akkor a metódus automatikusan meghívódik, amikor egy új objektumpéldány
létrejön. E módszer segítségével már születésükkor testreszabhatjuk objektuma-
inkat. A létrejövõ példány az ezen függvénynek átadott paraméterek vagy más
tényezõk alapján hozhatja magát alapállapotba. Ezeket a különleges metódusokat
konstruktoroknak (létrehozó függvényeknek) hívjuk. A 8.4. példaprogramban
az elso_osztaly objektumtípus konstruktorral kiegészített változatát láthatjuk.
126 8. óra
Az osztály tulajdonságai
Elõször is el kell döntenünk, hogy milyen tulajdonságokat tároljunk az objektumban.
Az oszlopok neveit egy tömbben tároljuk, a sorokat pedig egy kétdimenziós tömb-
ben. A táblázat oszlopainak számát külön, egy egész típusú változóba helyezzük.
08_ora.qxd 8/3/2001 6:19 PM Page 127
Objektumok 127
class Tablazat
{
var $tablazatSorok = array();
var $oszlopNevek = array();
var $oszlopszam;
}
A konstruktor
A táblázat létrehozásakor a programnak már tudnia kell, mik lesznek a feldolgo-
zandó oszlopok nevei. Ez az információ az objektumhoz a konstruktor egy karak-
terlánc típusú tömbparamétere segítségével fog eljutni. Ha az oszlopok neveit
a konstruktor már ismeri, könnyûszerrel meghatározhatja az oszlopok számát és
beírhatja az $oszlopszam tulajdonságba:
Az ujSor() tagfüggvény
A Tablazat osztály a sorokat tömbök formájában kapja meg. Ez persze csak
akkor mûködik helyesen, ha a tömbben és a fejlécben az oszlopok sorrendje
azonos:
Az ujSor() tagfüggvény egy tömböt vár, amit a $sor nevû változóban kap meg.
A táblázat oszlopainak számát már az $oszlopszam tulajdonságba helyeztük,
így most a count() függvénnyel ellenõrizhetjük, hogy a kapott $sor paraméter
megfelelõ számú oszlopot tartalmaz-e. Ha nem, akkor a függvény false értéket 8
ad vissza.
08_ora.qxd 8/3/2001 6:19 PM Page 128
128 8. óra
Az ujNevesSor() tagfüggvény
Az ujSor() tagfüggvény csak akkor használható kényelmesen, ha a tömbként
átadott paraméterben az elemek sorrendje megfelelõ. Az ujNevesSor()
tagfüggvény ennél több szabadságot ad. A metódus egy asszociatív tömböt vár,
ahol az egyes elemek kulcsa az oszlopok neve. Ha olyan kulcsú elem kerül
a paraméterbe, amely a Tablazat objektum $oszlopNevek tulajdonságában nem
szerepel, az adott elem egyszerûen nem kerül bele a táblázatba. Ha egy oszlopnév
nem jelenik meg a paraméterben kulcsként, akkor az adott oszlopba egy üres
karakterlánc kerül.
Objektumok 129
A kiir() tagfüggvény
A kiir() tagfüggvény kiírja a böngészõbe a táblázat fejlécét és
a $tablazatSorok tömböt. A függvény csak nyomkövetési célokat szolgál.
Az óra késõbbi részében egy sokkal szebb megoldást fogunk látni.
function kiir()
{
print "<pre>";
foreach ( $this->oszlopNevek as $oszlopNev )
print "<B>$oszlopNev</B> ";
print "\n";
foreach ( $this->tablazatSorok as $y )
{
foreach ( $y as $xcella )
print "$xcella ";
print "\n";
}
print "</pre>";
}
Összeáll a kép
A 8.5. példaprogram eddigi munkánk gyümölcsét, a Tablazat osztályt tartalmazza,
majd a program végén létrehoz egy Tablazat típusú objektumot és meghívja
valamennyi tagfüggvényét.
8
08_ora.qxd 8/3/2001 6:19 PM Page 130
130 8. óra
Objektumok 131
8.5. program (folytatás)
40: function kiir()
41: {
42: print "<pre>";
43: foreach ( $this->oszlopNevek as $oszlopNev )
44: print "<B>$oszlopNev</B> ";
45: print "\n";
46: foreach ( $this->tablazatSorok as $y )
47: {
48: foreach ( $y as $xcella )
49: print "$xcella ";
50: print "\n";
51: }
52: print "</pre>";
53: }
54: }
55:
56: $proba = new Tablazat( array("a","b","c"));
57: $proba->ujSor( array(1,2,3));
58: $proba->ujSor( array(4,5,6));
59: $proba->ujNevesSor( array ( "b"=>0, "a"=>6, "c"=>3 ));
60: $proba->kiir();
61: ?>
62: </body>
63: </html>
8.1. ábra
Egy Tablazat típusú
objektum kimenete
8
08_ora.qxd 8/3/2001 6:19 PM Page 132
132 8. óra
A kimenet csak akkor jelenik meg helyesen, ha az egy oszlopban levõ elemek
egyforma hosszúak.
Elõször is a kódot újra fel lehet használni. Ennek célja jól meghatározott: bizonyos
általános adatkezelést tesz lehetõvé, amelyet ezután beilleszthetünk bármely prog-
ramba, melynek arra van szüksége, hogy ilyen típusú adatokat kezeljen és kiírjon.
Másodszor, a Tablazat osztály tevékeny: megkérhetjük arra, hogy adatokat írjon ki,
anélkül, hogy bajlódnunk kellene azzal, hogy végigjárjuk a $tablazatSorok
elemeit.
Objektumok 133
Öröklés
Ahhoz, hogy olyan osztályt hozzunk létre, amely szolgáltatásait szülõjétõl örökli,
egy kicsit módosítanunk kell az osztály meghatározását. A 8.6. példaprogram
ismét a fejezet elsõ felében levõ témakörbõl mutat egy példát.
8
08_ora.qxd 8/3/2001 6:19 PM Page 134
134 8. óra
Objektumok 135
8
08_ora.qxd 8/3/2001 6:19 PM Page 136
136 8. óra
szuloOsztalyNeve::tagfuggvenyNeve()
sémát használva bármely felülírt tagfüggvényt meghívhatunk. A séma új, a PHP 3-as
változatában még hibát okozott volna.
08_ora.qxd 8/3/2001 6:19 PM Page 137
Objektumok 137
Egy új osztályt hoztunk létre, amely a Tablazat osztálytól fog örökölni. Két új
tulajdonságot adtunk meg, az egyiknek a kezdõértékét is meghatároztuk.
A konstruktor
Már láthattuk, hogy a szülõ konstruktora hívódik meg, ha a gyermekosztályban
nem hozunk létre konstruktort. Most azonban azt szeretnénk, hogy konstruktorunk
többre legyen képes, mint amennyit a Tablazat osztály konstruktora tett, ezért
azt felül kell írnunk.
138 8. óra
nem foglalkozunk a táblázat kezelésével (ha egyszer már megírtuk, akkor használ-
juk is
). A konstruktor másik dolga a HTMLTablazat hatterSzin tulajdonsá-
gának beállítása.
A cellaMargoAllit() tagfüggvény
A származtatott osztály saját, új tagfüggvényeket is létrehozhat.
A cellaMargoAllit() tagfüggvény segítségével a felhasználó a táblázat
szövege és a táblázat közötti üres rés nagyságát állíthatja be. Persze megtehetné
ezt a cellaMargo tulajdonság közvetlen elérésével is ,de ez nem túl jó ötlet.
Alapszabály, hogy az objektumot használó személy érdekében legjobb tagfügg-
vényeket létrehozni erre a célra. Az osztályok bonyolultabb leszármazottaiban
a cellaMargoAllit() tagfüggvény esetleg más tulajdonságokat is kénytelen
módosítani, hogy megváltoztathassa a margó méretét. Sajnos nincs elegáns mód
ennek a kikényszerítésére.
A kiir() tagfüggvény
A kiir() tagfüggvény felülírja a Tablazat osztály azonos nevû tagfüggvényét.
Ez a függvény a szülõ osztály logikájával azonos módon írja ki a táblázatot, de
a HTML table elemét használja a táblázat formázására.
function kiir()
{
print "<table cellPadding=\"$this->cellaMargo\"
border=1>\n";
print "<tr>\n";
foreach ( $this->oszlopNevek as $oszlopNev )
print "<th bgColor=\"$this
->hatterSzin\>$oszlopNev</th>;
print "</tr>\n";
08_ora.qxd 8/3/2001 6:19 PM Page 139
Objektumok 139
8
08_ora.qxd 8/3/2001 6:19 PM Page 140
140 8. óra
Objektumok 141
142 8. óra
8.2. ábra
Egy HTMLTablazat
típusú objektum
kimenete
Képzeljük el, hogy egy ügyfél azt a megbízást adja nekünk, hogy hozzunk létre egy
osztályt, amely olyan táblázatok kezelésére képes, ahol a táblázat oszlopainak neve
van. Ha egyetlen részbõl álló osztályt hozunk létre, amelybe minden szolgáltatást
(a HTML megjelenítés minden apró részletével) beleépítünk, elsõ látásra minden
szépnek és jónak tûnhet. De ha visszajön az ügyfél, hogy szeretné, ha a program
ízlésesen formázott szöveges kimenetet eredményezne, valószínûleg újabb tagfügg-
vényeket kellene megpróbálnunk felvenni, melyek megoldják a problémát.
08_ora.qxd 8/3/2001 6:19 PM Page 143
Objektumok 143
8.3. ábra
Kapcsolatok
a Tablazat osztály és
gyermekei között
Összefoglalás
Sajnos nincs rá mód, hogy az objektumközpontú programozást minden szempontból
megvizsgáljuk egy rövidke óra alatt, de remélem, hogy a fontosabb lehetõségeket
sikerült bemutatni.
144 8. óra
Kérdések és válaszok
Ebben az órában néhány barátságtalan fogalommal találkoztunk. Való-
ban szükséges az objektumközpontúságot megérteni ahhoz, hogy jó
PHP programozó válhasson az emberbõl?
Erre a rövid válasz: nem. A legtöbb PHP programozó alig vagy egyáltalán nem ír
objektumközpontú programot. Az objektumközpontú megközelítés nem tesz
számunkra olyan dolgokat lehetõvé, amelyek eddig elérhetetlenek voltak. A dolog
lényege a programok szervezésében, az egyszer megírt programrészek újrahasz-
nosításában és a könnyû fejleszthetõségben rejlik. Még ha el is határoznánk, hogy
soha nem fogunk objektumközpontú programot írni, elõfordulhat, hogy bele kell
javítanunk mások által írt programokba, amelyekben osztályok vannak, ezért érte-
nünk kell a szemlélet alapjait. Ez az óra ebben is segítséget nyújthat.
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Hogyan hoznánk létre egy uresOsztaly nevû osztályt, amelynek nincsenek
tagfüggvényei és tulajdonságai?
2. Adott egy uresOsztaly nevû osztály. Hogyan hoznánk létre egy példányát?
Objektumok 145
8. Mit kell tennünk, ha azt szeretnénk, hogy egy osztály más osztálytól
örököljön?
Feladatok
1. Hozzuk létre a Szamolo nevû osztályt, amely két egész számot tárol.
Írjunk hozzá egy kiszamol() nevû tagfüggvényt, amely kiírja a két számot
a böngészõbe!
8
08_ora.qxd 8/3/2001 6:19 PM Page 146
09_ora.qxd 8/3/2001 6:20 PM Page 147
III. RÉSZ
Munka a PHP-vel
9. óra Ûrlapok
10. óra Fájlok használata
11. óra A DBM függvények használata
12. óra Adatbázisok kezelése MySQL
13. óra Kapcsolat a külvilággal
14. óra Dinamikus képek kezelése
15. óra Dátumok kezelése
16. óra Az adatok kezelése
17. óra Karakterláncok kezelése
18. óra A szabályos kifejezések használata
19. óra Állapotok tárolása sütikkel és GET típusú lekérdezésekkel
20. óra Állapotok tárolása munkamenet-függvényekkel
21. óra Munka kiszolgálói környezetben
22. óra Hibakeresés
09_ora.qxd 8/3/2001 6:20 PM Page 148
09_ora.qxd 8/3/2001 6:20 PM Page 149
9. ÓRA
Ûrlapok
A könyv eddigi példáiban egy nagyon fontos dolgot nem láttunk. Létrehoztunk
változókat és tömböket, készítettünk és meghívtunk különbözõ függvényeket,
különféle objektumokkal dolgoztunk, eddigi ismereteink azonban értelmetlenek,
amíg a felhasználó által megadott adatokat kezelni nem tudjuk. Ebben az órában
ezt a témakört tekintjük át.
150 9. óra
Ûrlapok 151
/php-konyv/urlapok/9.1.program.php
09_ora.qxd 8/3/2001 6:20 PM Page 152
152 9. óra
Egy HTML ûrlapot hoztunk létre, amely egy "felhasznalo" nevû szövegmezõt,
egy "cim" nevû szövegterületet, és egy gombot tartalmaz. Könyvünk nem fogla-
kozik részletesen a HTML ismertetésével, ha mégis nehéznek találjuk a példákat,
olvassunk el egy, a HTML nyelvvel foglalkozó kötetet vagy számítógépes leírást.
A FORM elem ACTION paramétere a 9.3.program.php fájlra mutat, amely
feldolgozza az ûrlapon megadott adatokat. Mivel az ACTION csak a fájl nevét adja
meg, a HTML és PHP kódot tartalmazó fájloknak egy könyvtárban kell lenniük.
Ûrlapok 153
Ez a könyv elsõ olyan programja, amelyet nem hivatkozáson keresztül hívunk meg
és nem közvetlenül a böngészõbe írjuk be a címét. A 9.3. példában található kódot
az 9.3.program.php fájlban tároljuk. A fájlban lévõ kódot akkor hívjuk meg,
amikor a felhasználó kitölti a 9.2. példában található ûrlapot. A program
a $felhasznalo és a $cim változók értékét írja ki, amelyek a HTML ûrlap
"felhasznalo" szövegmezõjének és "cim" területének értékét tartalmazzák.
Látható, hogy a PHP 4 segítségével milyen egyszerûen kezelhetõek az ûrlapok.
Bármilyen megadott információ globális változóként hozzáférhetõ és a változók ne-
ve megegyezik a megfelelõ HTML elem nevével.
154 9. óra
Ûrlapok 155
Nem csak a SELECT elem engedélyezi több elem kiválasztását. Ha több jelölõ-
négyzetnek ugyanazt a nevet adjuk, ahol a felhasználó több elemet is kiválaszthat,
csak az utolsó kiválasztott értéket kapjuk meg, de ha a nevet üres szögletes záróje-
lek követik, az adott nevû elemeket a PHP tömbként kezeli. A 9.4. példa SELECT
elemét jelölõnégyzetekre cserélhetjük és ugyanazt a hatást érjük el:
156 9. óra
A fenti kód a GET kérelmen keresztül érkezett paraméterek neveit és értékeit írja ki.
Természetesen itt még nem kezeltük azt az esetet, amikor valamelyik átadott para-
méter tömb. Ha a 9.4. példaprogrammal olyan HTML ûrlapról érkezõ adatok feldol-
gozását végeztetjük, amelyben több elem kiválasztását engedélyezõ SELECT mezõ
szerepel, valami hasonlót olvashatunk:
Ûrlapok 157
158 9. óra
Ûrlapok 159
A fenti ûrlap saját magát hívja meg, mert a FORM elem ACTION paraméterének
a $PHP_SELF értéket adtunk. Vegyük észre, hogy nem készítettünk gombot,
amely elküldi a beírt számot. Az újabb böngészõk a szövegmezõ kitöltése és
az ENTER lenyomása után automatikusan elküldik a megadott adatot, viszont
néhány régebbi böngészõ ezt nem teszi meg.
A 9.9. példában lévõ program nem dinamikus, hiszen nem ír ki semmit, ami a fel-
használótól függ. A 9.10. példában további PHP kódot építünk az oldalba. Elõször
meg kell adnunk a számot, amit a felhasználónak ki kell találnia. A teljes változatban
valószínûleg véletlenszámot állítanánk elõ, most azonban egyszerûen megadjuk,
mondjuk a 42-t. Ezután megnézzük, hogy az ûrlapot kitöltötték-e már, különben
09_ora.qxd 8/3/2001 6:20 PM Page 160
160 9. óra
olyan változóval számolnánk, amely még nem létezik. A $tipp változó létezésének
ellenõrzésével megtudhatjuk, hogy az ûrlapot kitöltötték-e már. Amikor az ûrlap el-
küldi a "tipp" paramétert, a $tipp változó globális változóként hozzáférhetõ lesz
a programban. A $tipp változó létezése esetén egészen biztosak lehetünk benne,
hogy az ûrlapot a felhasználó kitöltötte, így elvégezhetjük a további vizsgálatokat.
Ûrlapok 161
162 9. óra
Ûrlapok 163
A felhasználó átirányítása
Programunknak van egy nagy hátulütõje. Az ûrlap mindig újratöltõdik, akár kita-
lálta a felhasználó a számot, akár nem. A HTML nyelvben sajnos elkerülhetetlen
az egész oldal újratöltése, a felhasználót azonban átirányíthatjuk egy gratuláló
oldalra, ha kitalálta a számot.
164 9. óra
Ûrlapok 165
Elõször létre kell hoznunk egy HTML ûrlapot, amely tartalmazza a fájlfeltöltõ me-
zõt, melynek egyik paramétere kötelezõen a következõ:
ENCTYPE="multipart/form-data"
A feltöltõ mezõ elõtt meg kell adnunk egy rejtett mezõt is. Ennek neve
MAX_FILE_SIZE kell, hogy legyen, és a fogadandó fájl lehetséges legnagyobb
méretét adja meg, bájtban. Nem lehet nagyobb, mint a php.ini fájlban megadott
09_ora.qxd 8/3/2001 6:20 PM Page 166
166 9. óra
Vegyük észre, hogy a program meghívja az oldalt, amely tartalmazza, hogy PHP
kóddal kezeljük a fájlt. A legnagyobb fájlméretet 50 kilobájtban adjuk meg és
"fajl"-nak nevezzük el.
Ûrlapok 167
168 9. óra
Ûrlapok 169
lónév alatt futnak, ezért mielõtt másolatot készítenénk a fájlról, ellenõriznünk kell,
hogy a mûvelet engedélyezett-e. Az or mûvelettel a die() függvényt használjuk,
ha a másolás sikertelen. Ezt a módszert a tizedik, a fájlokkal foglalkozó órában részle- 9
tesebben áttekintjük.
Másolás után az eredeti fájlt nem kell törölnünk, a PHP ezt megteszi helyettünk.
Ha nem másoljuk vagy helyezzük át a feltöltött állományt, a fájl elvész, mivel az
a PHP kód végrehajtása után törlõdik az ideiglenes könyvtárból.
Összefoglalás
Eddig olyan dolgokat tanultunk, amelyek segítségével igazi interaktív környezetet
hozhatunk létre. Van azonban még néhány tanulnivaló. A felhasználóról képesek
vagyunk információkat szerezni, de mit tegyünk ezekkel? Például fájlba írhatjuk.
Ez lesz a következõ óra témája.
Kérdések és válaszok
Létre lehet hozni tömböt olyan elemek tárolására is, amelyek nem
választómezõvel vagy jelölõnégyzetekkel megadottak?
Igen. Minden elem, amely nevének végén üres szögletes zárójel van, tömbként tá-
rolódik, így az elemek csoportba rendezhetõk.
170 9. óra
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Melyik környezeti változó tartalmazza a felhasználó IP címét?
Feladatok
1. Készítsünk számológép-programot, amelyben a felhasználó megadhat két
számot és a rajtuk végrehajtandó mûveletet (összeadás, kivonás, szorzás vagy
osztás ezeket ismerje a program).
10. ÓRA
Fájlok használata
A programozási nyelvek egyik legfontosabb lehetõsége, hogy fájlokat lehet létre-
hozni, olvasni, írni velük. A PHP-nek szintén megvannak ezek a tulajdonságai.
Ebben a fejezetben ezeket a lehetõségeket fogjuk áttekinteni:
Eddig, ha olyan kódot írtunk, amelyet többször is fel akartunk használni, minden
egyes helyre be kellett másolnunk azt. Ha hibát találtunk benne vagy lehetõségeit
tovább akartuk bõvíteni, mindenütt át kellett írnunk. Ezekre a problémákra megol-
dás az include() függvény. Gyakran használt függvényeinket külsõ fájlba ment-
hetjük és az include() függvénnyel futási idõben tölthetjük be programunkba.
Az include() függvény paramétere a fájl elérési útja. A 10.1. példában látható,
hogyan ágyazható be egy fájl a PHP kódba az include() függvény segítségével.
$proba = false;
if ( $proba )
{
include( "egy_fajl.txt" ); //nem ágyazza be
}
10
15: </body>
16: </html>
A 10.7. programban található kód futás közben három különbözõ fájlt ágyaz be,
ezek az "incfajl1.txt", "incfajl2.txt" és "incfajl3.txt".
Mindegyik fájl tartalmazza a nevét és azt a szöveget, hogy beágyazták:
Fájlok vizsgálata
Mielõtt elkezdünk ismerkedni a fájlokkal és könyvtárakkal, fussunk át néhány
velük kapcsolatos tudnivalót. A PHP 4 igen sok lehetõséget ad arra, hogy a rend-
szerünkben található fájlokon különbözõ mûveleteket hajtsunk végre. A következõ
bekezdésekben ezeket a függvényeket tekintjük át.
if ( file_exists("proba.txt") )
print("A fájl létezik!");
if ( is_file( "proba.txt" ) )
print("a proba.txt egy fájl");
if ( is_dir( "/tmp" ) )
print "a /tmp egy könyvtár";
if ( is_readable( "proba.txt" ) )
print "a proba.txt olvasható";
if ( is_writeable( "proba.txt" ) )
print "a proba.txt írható";
if ( is_executable( "proba.txt" )
print "a proba.txt futtatható";
Különféle fájlinformációk
Szükségünk lehet rá, hogy tudjuk, mikor hozták létre a fájlt vagy mikor használták
utoljára. A PHP-vel ezeket az információkat is megszerezhetjük.
if ( is_file( $f ) )
print "$f fájl<br>";
else
print "$f nem fájl<br>";
touch("sajat_fajl.txt");
unlink("sajat_fajl.txt");
A létrehozás, törlés, írás, olvasás, módosítás csak akkor lehetséges egy fájlon,
ha a megfelelõ jogosultságokkal rendelkezünk.
Az fopen() false értékkel tér vissza, ha valamiért nem tudta megnyitni a fájlt,
ezért érdemes mindig ellenõrizni, hogy sikeres volt-e a megnyitás. Ezt például
az if vezérlési szerkezettel tehetjük meg:
Ha az fopen() true értékkel tér vissza, a die() nem hajtódik végre, különben
a kifejezés jobb oldalán a die() kiírja a paraméterében szereplõ karakterláncot és
megszakítja a program futását.
Amikor befejeztük a munkát egy fájllal, mindig be kell zárnunk azt. Ezt az fclose()
függvénnyel tehetjük meg, amelynek paraméterében azt a fájlazonosítót kell megad-
10
nunk, amelyet egy sikeres fopen() végrehajtása során kaptunk:
fclose( $fa );
Olvasás fájlból
A PHP-ben egy fájlból különbözõ függvények segítségével bájtonként, soronként
vagy karakterenként olvashatunk.
Tudnunk kell tehát, mikor érünk a fájl végére. Ezt az feof() függvény adja meg,
melynek visszatérési értéke true, ha a fájl végére értünk, egyébként false.
A függvény paraméterében egy fájlazonosítót kell megadni.
A 10.9. példában láthatjuk, hogyan kell egy fájlt sorról sorra beolvasni.
10_ora.qxd 8/3/2001 6:20 PM Page 182
4: </head>
függvénnyel</title> 10
5: <body>
6: <?php
7: $fajlnev = "proba.txt";
8: $fa = fopen( $fajlnev, "r" ) or die("$fajlnev nem
nyitható meg");
9: while ( ! feof( $fa ) )
10: {
11: $reszlet = fread( $fa, 16 );
12: print "$reszlet<br>";
13: }
14: fclose($fa);
15: ?>
16: </body>
17: </html>
Bár az fread() függvénynek megadjuk, mennyi adatot olvasson ki, azt nem tudjuk
meghatározni, hogy honnan kezdje az olvasást. Erre az fseek() ad lehetõséget,
ezzel a függvénnyel állítható be az olvasás helye. Paraméterként egy fájlazonosítót
és egy egész számot kell megadnunk, amely a fájl elejétõl bájtban mérve meghatá-
rozza az új olvasási helyet:
fseek( $fa, 64 );
Minden írási próbálkozás a fájl elején történik. Ha a fájl még nem létezne, a rend-
szer létrehozza azt. Ha a fájl létezik, tartalma felülíródik a megadott adatokkal.
Munka könyvtárakkal
Az elõzõekben áttekintettük, hogyan kezelhetjük a fájlokat, most megnézzük,
hogyan hozhatunk létre, törölhetünk és olvashatunk könyvtárakat a PHP-ben.
rmdir( "proba_konyvtar" );
10
10: {
11: if ( is_dir( "$kvtnev/$fajl" ) )
12: print "(D)";
13: print "$fajl<br>";
14: }
15: closedir( $kvt );
16: ?>
17: </body>
18: </html>
.
..
Amikor a ciklus eléri a "0" nevû fájlt, a readdir() false értéknek veszi és
a ciklus leáll. A 10.14. példában a readdir() függvény visszatérési értékének
típusát vizsgáljuk és ezzel oldjuk meg a problémát.
10_ora.qxd 8/3/2001 6:20 PM Page 190
Összefoglalás
Ebben az órában megtanultuk, hogyan ágyazhatunk be a dokumentumokba külsõ
fájlban tárolt PHP kódot. Áttekintettük a fájlok különbözõ tulajdonságainak ellen-
õrzését, megnéztünk, hogyan olvashatunk fájlokat sorról sorra, karakterenként,
vagy meghatározott részletekben. Megtanultuk, hogyan írhatunk fájlba és hogyan
fûzhetünk karakterláncokat hozzá. Végül áttekintettük, hogyan hozhatunk létre,
törölhetünk, vagy listázhatunk ki könyvtárakat.
Kérdések és válaszok
Az include() függvény lassítja a programok futását?
Mivel a beágyazott fájlt meg kell nyitni és a tartalmát be kell olvasni, ezért azt kell
mondjuk, hogy igen, a lassulás azonban nem számottevõ.
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Melyik függvénnyel adható programunkhoz külsõ kódot tartalmazó fájl?
Feladatok 10
1. Készítsünk egy oldalt, amely bekéri a felhasználó vezeték- és keresztnevét.
Készítsünk programot, amely ezen adatokat fájlba menti.
11. ÓRA
A DBM függvények használata
Ha nem is férünk hozzá valamilyen SQL adatbáziskezelõhöz (mint a MySQL vagy
az Oracle), majdnem biztos, hogy valamilyen DBM-szerû adatbázisrendszer ren-
delkezésünkre áll. Ha mégsem, a PHP akkor is képes utánozni számunkra egy
ilyen rendszer mûködését. A DBM függvények segítségével lényegében névérték
párokat tárolhatunk és kezelhetünk.
Noha ezek a függvények nem biztosítják számunkra egy SQL adatbázis erejét, ru-
galmasak és könnyen használhatók. Mivel a formátum igen elterjedt, az e függvé-
nyekre épülõ kód általában hordozható, noha maguk a DBM adatokat tartalmazó
állományok nem azok.
dbmclose ( $dbm );
11_ora.qxd 8/3/2001 6:20 PM Page 195
11.1. ábra
A DBM adatbázis
összes bejegyzésének
lekérdezése.
11_ora.qxd 8/3/2001 6:20 PM Page 199
$tomb = array( 1, 2, 3, 4 );
$dbm = dbmopen( "./adat/proba", "c" ) or
å die("Nem lehet megnyitni a DBM adatbázist.");
dbminsert( $dbm, "tombproba", $tomb );
print gettype( dbmfetch( $dbm, "tombproba" ) );
// A kimenet: "string"
$tomb = array( 1, 2, 3, 4 );
print serialize( $tomb );
// A kimenet: "a:4:{i:0;i:1;i:1;i:2;i:2;i:3;i:3;i:4;}"
11.2. ábra
Összetett adatszerke-
zetek visszaolvasása
DBM adatbázisból
11_ora.qxd 8/3/2001 6:20 PM Page 203
Egy példa
Már eleget tudunk ahhoz, hogy elkészítsünk egy mûködõképes programot
az ebben az órában tanult módszerekkel. A feladat a következõ: készítsünk egy
karbantartó oldalt, ahol a webhely szerkesztõje megváltoztathatja a 11.2. példa-
program által létrehozott adatbázis termékeinek árát. Tegyük lehetõvé a rendszer-
gazda számára, hogy új elemekkel bõvítse az adatbázist, illetve hogy a régi eleme-
ket törölje. Az oldalt nem tesszük nyilvános kiszolgálón elérhetõvé, ezért
a biztonsági kérdésekkel most nem foglalkozunk.
A táblázat elsõ mezõje minden sorban egy jelölõnégyzetet tartalmaz. Vegyük ész-
re, hogy mindegyik jelölõnégyzet neve "torles[]". Ennek hatására a PHP létre-
hozza a $torles tömböt, amely az összes bejelölt elemet tartalmazza. A jelölõ-
négyzetekhez tartozó értékek, így a $torles tömb elemei is azok az azonosítók
lesznek, amelyekkel a DBM adatbázis az adott terméket nyilvántartja (ezt az érté-
ket a $kulcs változóban tároljuk). Így, miután a rendszergazda kitöltötte és
elküldte az ûrlapot, a program $torles tömbje azon adatbázis-elemek kulcsait
fogja tárolni, amelyeket törölnünk kell.
11_ora.qxd 8/3/2001 6:20 PM Page 205
11.3. ábra
HTML ûrlap készítése
DBM adatbázis
alapján
11
Miután elkészítettük az ûrlapot, meg kell írnunk a kódot, amely a felhasználó által
megadott adatokat kezeli. A feladat nem olyan nehéz, mint amilyennek látszik.
Elõször töröljük a kijelölt elemeket az adatbázisból, majd módosítjuk az árakat,
végül felvesszük az új elemet az adatbázisba.
if ( isset ( $torles ) )
{
foreach ( $torles as $kulcs => $ertek )
{
unset( $arak[$ertek]);
dbmdelete( $dbm, $ertek );
}
}
11_ora.qxd 8/3/2001 6:20 PM Page 206
Az adatbázis elemeinek frissítése során két választási lehetõségünk van. Az elsõ vál-
tozatot akkor alkalmazzuk, ha az adatbázis karbantartását nem egyetlen szerkesztõ
fogja végezni, tehát feltételezhetõ, hogy a programot egyidõben több felhasználó is
futtatni fogja eszerint csak azokat az elemeket változtatjuk meg, amelyeket a fel-
használó kijelölt. A másik változat, amely az összes elemet megváltoztatja, akkor al-
kalmazható, ha a program csak egyetlen példányban futhat:
if ( isset ( $arak ) )
{
foreach ( $arak as $kulcs => $ertek )
dbmreplace( $dbm, $kulcs, $ertek );
}
Összefoglalás
Ebben az órában megtanultuk, hogyan használjuk a PHP hatékony DBM függvénye-
it adatok tárolására és visszaolvasására. Megtanultuk a dbmopen() használatát egy
új DBM azonosító létrehozására. Ezt az azonosítót használtuk az összes többi DBM
függvénynél is. Új adatokat adtunk az adatbázishoz a dbminsert() függvénnyel,
módosítottunk meglevõket a dbmreplace()-szel és töröltünk a dbmdelete()
használatával. Megtanultuk, hogyan használhatjuk a dbmfetch() függvényt
az adatok visszaolvasására. A serialize() és unserialize() függvényekkel
összetett adatszerkezeteket tároltunk DBM adatbázisban, végül egy gyakorlati
példán keresztül megnéztük, hogyan is használhatók fel e módszerek a valós
problémák megoldására.
11
Kérdések és válaszok
Mikor használjak DBM adatbázist SQL adatbázis helyett?
A DBM jó választás, ha kis mennyiségû és viszonylag egyszerû szerkezetû adatot sze-
retnénk tárolni (névérték párokat). A DBM adatbázist használó programok rendel-
keznek a hordozhatóság nagyon fontos elõnyével, de ha nagyobb mennyiségû ada-
tot kell tárolnunk, válasszunk inkább egy SQL adatbáziskezelõt, például a MySQL-t.
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Melyik függvényt használhatjuk egy DBM adatbázis megnyitásához?
Feladatok
1 Hozzunk létre egy DBM adatbázist a felhasználók azonosítóinak és jelszavai-
nak tárolására. Készítsünk egy programot, amellyel a felhasználók létrehoz-
hatják a rájuk vonatkozó bejegyzést. Ne feledjük, hogy két azonos nevû elem
nem kerülhet az adatbázisba.
12. ÓRA
Adatbázisok kezelése MySQL
A PHP nyelv egyik meghatározó tulajdonsága, hogy nagyon könnyen képes adat-
bázisokhoz csatlakozni és azokat kezelni. Ebben az órában elsõsorban a MySQL
adatbázisokkal foglalkozunk, de amint majd észre fogjuk venni, a PHP által támo-
gatott összes adatbázist hasonló függvények segítségével érhetjük el. Miért esett
a választás éppen a MySQL-re? Mert ingyenes, ugyanakkor nagyon hatékony
eszköz, amely képes megfelelni a valós feladatok által támasztott igényeknek is.
Az sem elhanyagolható szempont, hogy többféle rendszerhez is elérhetõ.
A MySQL adatbáziskiszolgálót a http://www.mysql.com címrõl tölthetjük le.
Ebben az órában a következõ témákkal foglalkozunk:
Tanulunk a hibakezelésrõl.
A MySQL kiszolgáló démonként fut a számítógépen, így a helyi vagy akár távoli
gépek felhasználói bármikor csatlakozhatnak hozzá. Miután a csatlakozás megtör-
tént, ki kell választanunk a megfelelõ adatbázist, ha van jogunk hozzá.
A * szokásos helyettesítõ karakter, jelentése az összes mezõ. Ha nem az összes
mezõ tartalmát akarjuk lekérdezni, írjuk be az érintett mezõk neveit a csillag helyére:
Ez az utasítás csak azokat a sorokat írja ki, amelyekben a keresztnev mezõ értéke
"Gábor".
Csatlakozás a kiszolgálóhoz
Mielõtt elkezdhetnénk dolgozni az adatbázissal, csatlakoznunk kell a kiszolgáló-
hoz. A PHP-ben erre a mysql_connect() függvény szolgál. A függvény három
karakterláncot vár paraméterként: a gazdagép nevét, a felhasználó nevét és
a jelszót. Ha ezek egyikét sem adjuk meg, a függvény feltételezi, hogy a kérés
a localhost-ra (azaz a helyi gépre) vonatkozik és felhasználóként a PHP-t futta-
tó felhasználót, jelszóként pedig egy üres karakterláncot ad át. Az alapértelmezés
12_ora.qxd 8/3/2001 6:20 PM Page 214
Az adatbázis kiválasztása
Miután kialakítottuk a kapcsolatot a MySQL démonnal, ki kell választanunk, melyik
adatbázissal szeretnénk dolgozni. Erre a célra a mysql_select_db() függvény
szolgál, amelynek meg kell adnunk a kiválasztott adatbázis nevét és szükség szerint
egy kapcsolatazonosító értéket. Ha ez utóbbit elhagyjuk, automatikusan a legutoljá-
ra létrehozott kapcsolat helyettesítõdik be. A mysql_select_db() függvény igaz
értéket ad vissza, ha az adatbázis létezik és jogunk van a használatára. A következõ
kódrészlet a pelda nevû adatbázist választja ki.
$adatbazis = "pelda";
mysql_select_db( $adatbazis ) or die ( "Nem lehet
å megnyitni a következõ adatbázist: $adatbazis" );
12_ora.qxd 8/3/2001 6:20 PM Page 215
Hibakezelés
Eddig ellenõriztük a MySQL függvények visszatérési értékét és hiba esetén a die()
függvénnyel kiléptünk a programból. A hibakezeléshez azonban hasznosabb lenne,
ha a hibaüzenetek valamivel több információt tartalmaznának. Ha valamilyen mûve-
let nem sikerül, a MySQL beállít egy hibakódot és egy hibaüzenetet. A hibakódhoz
a mysql_errno(), míg a hibaüzenethez a mysql_error() függvénnyel férhe-
tünk hozzá. A 12.1 példa az eddigi kódrészleteinket teljes programmá kapcsolja
össze, amely kapcsolódik az adatbáziskezelõhöz és kiválasztja az adatbázist. A hiba-
üzenetet a mysql_error() függvénnyel tesszük használhatóbbá.
Az adatok felviteléhez össze kell állítanunk és le kell futtatnunk egy SQL parancsot,
erre a célra a PHP-ben a mysql_query() függvény szolgál. A függvény paramé-
terként egy SQL parancsot tartalmazó karakterláncot és szükség szerint egy kapcso-
latazonosítót vár. Ha ez utóbbit elhagyjuk, a függvény automatikusan az utoljára
megnyitott kapcsolaton keresztül próbálja meg kiadni az SQL parancsot. Ha a prog-
ram sikeresen lefutott, a mysql_query()pozitív értéket ad vissza, ha azonban
formai hibát tartalmaz vagy nincs jogunk elérni a kívánt adatbázist, a visszatérési
érték hamis lesz. Meg kell jegyeznünk, hogy egy sikeresen lefutott SQL program
nem feltétlenül okoz változást az adatbázisban vagy tér vissza valamilyen ered-
ménnyel. A 12.2 példában kibõvítjük a korábbi programot és a mysql_query()
függvénnyel kiadunk egy INSERT utasítást a pelda adatbázis tartomanyok
tábláján.
12_ora.qxd 8/3/2001 6:20 PM Page 217
Vegyük észre, hogy nem adtunk értéket az azonosito mezõnek. A mezõ értéke
automatikusan növekszik az INSERT hatására.
12.3.program (folytatás)
35: return false;
36: }
37: $parancs = "INSERT INTO tartomanyok ( tartomany,
nem, email )
38: VALUES ( '$tartomany', '$nem', '$email' )";
39: if ( ! mysql_query( $parancs, $kapcsolat ) )
40: {
41: $dbhiba = mysql_error();
42: return false;
43: }
44: return true;
45: }
46:
47: function urlap_keszit()
48: {
49: global $PHP_SELF;
12
50: print "<form action=\"$PHP_SELF\"
method=\"POST\">\n";
51: print "A kívánt tartomány<p>\n";
52: print "<input type=\"text\" name=\"tartomany\"> ";
53: print "Email cím<p>\n";
54: print "<input type=\"text\" name=\"email\"> ";
55: print "<select name=\"nem\">\n";
56: print "\t<option value=\"N\"> Nõ\n";
57: print "\t<option value=\"F\"> Férfi\n";
58: print "</select>\n";
59: print "<input type=\"submit\"
value=\"Elküld\">\n</form>\n";
60: }
61: ?>
62: </body>
63: </html>
Így ha meg akarjuk mondani a felhasználónak, hogy milyen azonosító alatt rögzí-
tettük az adatait, az adatok rögzítése után közvetlenül hívjuk meg
a mysql_insert_id() függvényt.
Adatok lekérdezése
Miután adatainkat már képesek vagyunk az adatbázisban tárolni, megismerkedhe-
tünk azokkal a módszerekkel, amelyek az adatok visszanyerésére szolgálnak. Mint
bizonyára már nyilvánvaló, a mysql_query() függvény használatával ki kell 12
adnunk egy SELECT utasítást. Az azonban már korántsem ilyen egyszerû, hogyan
jutunk hozzá a lekérdezés eredményéhez. Nos, miután végrehajtottunk egy sikeres
SELECT-et, a mysql_query() visszaad egy úgynevezett eredményazonosítót,
melynek felhasználásával elérhetjük az eredménytáblát és információkat nyerhe-
tünk róla.
Az eredménytábla elérése
Miután végrehajtottuk a SELECT lekérdezést és az eredményazonosítót tároltuk,
egy ciklus segítségével férhetünk hozzá az eredménytábla soraihoz. A PHP egy
belsõ mutató segítségével tartja nyilván, hogy melyik sort olvastuk utoljára.
Ha kiolvasunk egy eredménysort, a program automatikusan a következõre ugrik.
Adatok frissítése
Az adatokat az UPDATE utasítással frissíthetjük, amelyet természetesen
a mysql_query() függvénnyel kell átadnunk az adatbázis kiszolgálójának.
Itt is igazak a korábban elmondottak, azaz egy sikeres UPDATE utasítás nem
feltétlenül jelent változást az adatokban. A megváltozott sorok számát
a mysql_affected_rows() függvénnyel kérdezhetjük le, amelynek szükség
szerint egy kapcsolatazonosítót kell átadnunk. Ennek hiányában a függvény
mint azt már megszokhattuk a legfrissebb kapcsolatra értelmezi a mûveletet.
A mysql_affected_rows() függvényt bármely olyan SQL lekérdezés után
használhatjuk, amely feltehetõen módosított egy vagy több sort az adattáblában.
A 12.6. példa egy olyan programot tartalmaz, amely lehetõvé teszi az adatbázis
karbantartója számára, hogy bármelyik sor tartomany mezõjét megváltoztassa.
Információk az adatbázisokról
Mindezidáig egyetlen adatbázisra összpontosítottunk, megtanulva, hogyan lehet
adatokkal feltölteni egy táblát és az adatokat lekérdezni. A PHP azonban számos
olyan eszközzel szolgál, amelyek segítségével megállapíthatjuk, hány adatbázis
hozzáférhetõ az adott kapcsolaton keresztül és milyen ezek szerkezete.
12.1. ábra
Az elérhetõ adatbá-
zisok listája
12_ora.qxd 8/3/2001 6:20 PM Page 229
Adatbázistáblák listázása
A mysql_list_tables() függvénnyel egy adott adatbázis tábláinak nevét sorol-
tathatjuk fel. A függvény paraméterei az adatbázis neve és szükség szerint a kapcso-
lat azonosítója. A visszatérési érték egy eredményazonosító, ha az adatbázis létezik
és jogunk van hozzáférni. Az eredményazonosítót mysql_tablename() vagy
mysql_fetch_row() hívásokhoz használhatjuk fel, a fent látott módon.
12.2. ábra
Az összes elérhetõ
adatbázis, tábla és
mezõ listája
Összefoglalás 12
Ebben az órában a MySQL adatbáziskezelés alapjait tanultuk meg: az adatok
tárolását és visszanyerését.
Kérdések és válaszok
Ez az óra szigorúan a MySQL-re vonatkozik. Hogyan ültethetjük át ezeket
a fogalmakat más adatbázissal mûködõ rendszerekre?
Az mSQL-kezelõ függvények például szinte teljesen megegyeznek a MySQL függ-
vényekkel, de más SQL kiszolgálóknak is megvannak a saját PHP függvényeik.
SQL utasításokat minden adatbáziskiszolgálónak küldhetünk. Ha szabványos ANSI
SQL-lel dolgozunk, nem lesz különösebb problémánk az adatbáziskiszolgálók kö-
zötti átálláskor.
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Hogyan kell csatlakozni a MySQL adatbáziskiszolgálóhoz?
Feladatok
1. Hozzunk létre egy adattáblát három mezõvel: email (legfeljebb 70 karakter),
uzenet (legfeljebb 250 karakter) és datum (a UNIX idõbélyegzõt tartalmazó
egész szám). Tegyük lehetõvé a felhasználóknak, hogy feltöltsék az adat-
bázist.
12
12_ora.qxd 8/3/2001 6:20 PM Page 236
13_ora.qxd 8/3/2001 6:21 PM Page 237
13. ÓRA
Kapcsolat a külvilággal
Ezen az órán olyan függvényekkel ismerkedünk meg, amelyek a külvilággal való
érintkezést teszik lehetõvé. Az óra során a következõkrõl tanulunk:
Levélküldés programból
13_ora.qxd 8/3/2001 6:21 PM Page 238
Környezeti változók
Már találkoztunk néhány környezeti változóval; ezeket a PHP a kiszolgáló segítségé-
vel bocsátotta rendelkezésünkre. Néhány ilyen változóval több dolgot is megtudha-
tunk weboldalunk látogatóiról, arra azonban gondoljunk, hogy lehet, hogy ezek
a változók a mi rendszerünkön nem elérhetõk, esetleg a kiszolgálóprogram nem
támogatja azokat, így használatuk elõtt érdemes ezt ellenõrizni. A 13.1. táblázat ezek
közül a változók közül mutat be néhányat.
A 13.1. ábrán a 13.1. kód kimenetét láthatjuk. Az ábrán látható adatokat úgy
kaptuk, hogy a programot egy másik oldal hivatkozásán keresztül hívtuk meg.
A programot meghívó hivatkozás így nézett ki:
<A HREF='13.1.program.php/tovabbi/utvonal?nev=ertek'>gyerünk</A>
13.1. ábra 13
Néhány környezeti
változó kiíratása
a böngészõben
A kérés
Az ügyfél szigorú szabályok szerint kérhet adatokat a kiszolgálótól. A kérés legfel-
jebb három részbõl állhat:
A kérés sora
13
Fejléc
Törzs
A legfontosabb a kérés sora. Itt határozzuk meg a kérés fajtáját (GET, HEAD vagy
POST), a kért dokumentum címét és az átviteli protokoll változatszámát
(HTTP/1.0 vagy HTTP/1.1). Egy jellemzõ kérés a következõképpen néz ki:
Ekkor az ügyfél egy GET kérést kezdeményez. Más szóval lekér egy dokumentumot,
de adatokat nem küld. (Valójában kisebb mennyiségû adat küldésére a GET kérés
alkalmazásakor is van lehetõség, ha azt lekérdezõ karakterlánc formájában hozzáír-
juk az URL végéhez.) A HEAD módszer akkor alkalmazandó, ha nem magára
a dokumentumra, csak annak tulajdonságaira vagyunk kíváncsiak, végül a POST
kérés arra szolgál, hogy adatokat küldjünk az ügyféltõl a kiszolgálónak. Ez legtöbb-
ször HTML ûrlapok esetében használatos.
13_ora.qxd 8/3/2001 6:21 PM Page 242
A 13.2 példában egy jellemzõ, mindennapos kérést mutatunk be, melyet egy
Netscape 4.7 kezdeményezett.
13_ora.qxd 8/3/2001 6:21 PM Page 243
A válasz
Miután a kiszolgáló fogadta az ügyfél kérését, választ küld. A válasz általában
a következõ három részbõl tevõdik össze:
Állapot
Fejléc
Törzs
Amint látjuk, a kérés és a válasz szerkezete igen hasonló. A fejléc bizonyos sorai
13
tulajdonképpen ügyfél és kiszolgáló által küldve egyaránt megállják helyüket,
nevezetesen azok, amelyek a törzsre vonatkoznak.
HTTP/1.1 200 OK
Ha megnézzük ezt az oldalt, akkor a PHP honlapját kell látnunk, azzal a kis
különbséggel, hogy a képek nem jelennek meg. Ennek oka, hogy az oldalon talál-
ható IMG hivatkozások általában relatívak, így az oldal megjelenítésekor a böngé-
szõ a mi kiszolgálónkon keresi azokat. Ezen úgy segíthetünk, hogy a HEAD HTML
elemet az alábbi sorral bõvítjük:
<base href="http://www.php.net/index.php">
Most már elegendõ tudás birtokában vagyunk ahhoz, hogy kapcsolatot létesíthes-
sünk egy webkiszolgálóval. A 13.6-os programban megnyitunk egy HTTP kapcso-
latot, lekérünk egy fájlt, majd egy változóban tároljuk azt.
Vannak esetek, amikor meg kell hamisítani a fejléceket. Szükségünk lehet például
olyan adatokra, amelyeket a kiszolgáló csak Netscape böngészõnek küld el.
Ezek elérésének egyetlen módja, ha a User-Agent fejlécsorban egy Netscape
böngészõre jellemzõ karakterláncot küldünk. Ennek a webmesterek nem igazán
örülnek, hiszen döntéseiket a kiszolgáló gyûjtötte statisztikák alapján kell meghoz-
niuk. Hogy segíthessünk ebben nekik, lehetõleg ne hamisítsuk meg adatainkat,
hacsak feltétlenül nem szükséges.
13.2. ábra
Kiszolgálók válaszát
megjelenítõ program
13
NNTP kapcsolat létrehozása az fsockopen()-nel
Az fsockopen() függvény tetszõleges internetkiszolgálóval képes kapcsolatot
teremteni. A 13.8. példában egy NNTP (Usenet) kiszolgálóhoz kapcsolódunk:
kiválasztunk egy hírcsoportot, majd megjelenítjük elsõ üzenetének fejlécét.
A 13.8. program egy kicsit többet mutat annál, hogyan nyissunk az fsockopen()-
nel NNTP kapcsolatot. Valós alkalmazás esetén a visszakapott sorok elemzését
célszerû egy függvénnyel végezni, egyrészt azért, hogy megszabaduljunk az ismét-
lésektõl, másrészt azért, hogy több adatot is kinyerhessünk a válaszból. Mielõtt
azonban újra feltalálnánk a kereket, célszerû, ha megismerkedünk a PHP IMAP
függvényeivel, amelyekkel mindez a munka automatizálható.
13.3. ábra
NNTP kapcsolat
megteremtése
$cimzett = "valaki@tartomany.hu";
$targy = "üdvözlet";
$uzenet = "ez csak egy próba üzenet! ";
mail( $cimzett, $targy, $uzenet ) or
å print "A levél elküldése sikertelen";
13_ora.qxd 8/3/2001 6:21 PM Page 255
$cimzett = "valaki@tartomany.hu";
$felado = "masvalaki@masiktartomany.hu";
$targy = "üdvözlet ";
$uzenet = "ez csak egy proba üzenet! ";
mail( $cimzett, $targy, $uzenet,
å "From: $felado\r\nX-Priority: 1 (Highest)" )
or print "A levél elküldése sikertelen";
Összefoglalás
Ezen az órán megtudhattuk, hogyan vethetjük be a környezeti változókat, ha több
adatot szeretnénk megtudni látogatóinkról. Ha nem tudjuk a látogató gépének
nevét, a gethostbyaddr() függvénnyel kideríthetjük.
13
Láthattuk miként zajlik egy HTTP kapcsolat megteremtése a kiszolgáló és
az ügyfél között, megtanultuk, hogyan töltsünk le egy dokumentumot a webrõl
az fopen() segítségével és hogyan építsük ki saját HTTP kapcsolatunkat
az fsockopen() függvény felhasználásával. Az fsockopen()-nel más hálózati
szolgáltatásokhoz is kapcsolódtunk, végül pedig elektronikus levelet küldtünk
a programból a mail() függvény egyszerû meghívásával.
Kérdések és válaszok
A HTTP meglehetõsen misztikusnak tûnik. Tényleg szükség van az ismere-
tére, ha jó PHP kódot szeretnénk írni?
Nem. Kitûnõ programok készíthetõk a kiszolgáló-ügyfél párbeszéd részletes isme-
rete nélkül is. Másfelõl azonban szükség van ilyen alapvetõ ismeretekre, ha kicsit
bonyolultabb feladatokat szeretnénk programozottan végrehajtani, például
weboldalakat letölteni.
13_ora.qxd 8/3/2001 6:21 PM Page 256
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Mely környezeti változó árulja el nekünk annak a lapnak a címét, amely
a programunkra hivatkozott?
Feladatok
1. Készítsünk egy programot, amely egy webcímet kér be (például
http://www.kiskapu.hu/) a felhasználótól, majd egy HEAD kérést
küldve felveszi a kapcsolatot azzal. Jelenítsük meg a kapott választ a böngé-
szõben. Ne feledkezzünk meg arról, hogy a kapcsolat nem mindig jön létre.
13
13_ora.qxd 8/3/2001 6:21 PM Page 258
14_ora.qxd 8/3/2001 6:21 PM Page 259
14. ÓRA
Dinamikus képek kezelése
Az ezen az órán vett függvények a GD nevû nyílt forráskódú programkönyvtáron
alapulnak.
Miután megkaptuk az azonosítót, már majdnem készen állunk arra, hogy megjele-
nítsük elsõ képünket a böngészõben. Ehhez az imagegif() függvényre van
szükségünk, amelynek paramétere a képazonosító. A 14.1. programban a kép lét-
rehozásához és megjelenítéséhez használt függvényeket láthatjuk.
Egy téglalapot hoztunk létre, de egyelõre nem tudjuk annak színét beállítani.
14_ora.qxd 8/3/2001 6:21 PM Page 261
14.1. ábra
Dinamikusan létre-
hozott alakzat
A szín beállítása
A szín beállításához egy színazonosítóra van szükségünk. Ezt
az imagecolorallocate() függvénnyel kaphatjuk meg, amelynek paramétere
a képazonosító, illetve három 0 és 255 közötti egész szám, amelyek a vörös, zöld
és kék színösszetevõket jelentik. Egy színazonosítót kapunk vissza, amellyel ké-
sõbb alakzatok, kitöltések vagy szövegek színét határozhatjuk meg.
Vonalak rajzolása
Mielõtt egy képre vonalat rajzolhatnánk, meg kell adnunk annak két végpontját.
A képet úgy képzeljük el, mint képernyõpontokból álló tömböt, melynek mindkét
tengelye 0-tól számozódik. A számozás kezdõpontja a kép bal felsõ sarka.
Két színazonosítót kapunk, egyet a piros és egyet a kék színnek. Ezután a $kek
változóban tárolt azonosítót használjuk a vonal színének megadására. Fontos meg-
jegyeznünk, hogy a vonal a (199, 199) és nem a (200, 200) koordinátákban végzõ-
dik, tekintve, hogy a képpontokat 0-tól kezdve számozzuk. A 14.2. ábrán
a 14.2. program eredményét láthatjuk.
14.2. ábra
Egyenes rajzolása
az imageline()
függvénnyel
14_ora.qxd 8/3/2001 6:21 PM Page 263
Alakzatok kitöltése
A PHP segítségével ugyanúgy kiszínezhetünk alakzatokat, mint kedvenc grafikai
programunkkal. Az imagefill() függvény bemenete egy képazonosító,
a kitöltés kezdõkoordinátái, valamint egy színazonosító. A függvény a kezdõ
képponttal megegyezõ színû szomszédos képpontokat a kijelölt színre állítja.
A 14.3. program a képet az imagefill() függvény meghívásával teszi egy kicsit
érdekesebbé.
14.3. ábra
Az imagefill() függ-
vény használata
14
14_ora.qxd 8/3/2001 6:21 PM Page 264
Körív rajzolása
Az imagearc() függvény segítségével köríveket rajzolhatunk. Bemenete
egy képazonosító, a középpont koordinátája, a szélességet meghatározó egész
szám, a magasságot meghatározó egész szám, egy kezdõ- és egy végpont
(fokban mérve), valamint egy színazonosító. A köríveket az óramutató járásának
megfelelõen, 3 órától kezdve rajzoljuk. A következõ kódrészlet egy negyed körívet
rajzol ki:
Ez egy olyan körívrészletet jelenít meg, melynek középpontja a (99, 99) koordiná-
tájú pontban van. A teljes magasság és szélesség 200-200 képpontnyi. A körív 3
óránál kezdõdik és 90 fokot rajzolunk (azaz 6 óráig).
14.4. ábra
Kör rajzolása
az imagearc() függ-
vénnyel
Téglalap rajzolása
A PHP imagerectangle() függvényével téglalapot rajzolhatunk.
Az imagerectangle() bemenete egy képazonosító, a téglalap bal felsõ és jobb
alsó sarkának koordinátája, valamint egy színazonosító. A következõ kódrészlet
olyan téglalapot rajzol, melynek bal felsõ és jobb alsó koordinátái rendre (19, 19)
és (179, 179):
14.5. ábra
Téglalap rajzolása az
imagefilledrectangle()
függvénnyel
Sokszög rajzolása
Az imagepolygon() függvény segítségével kifinomultabb alakzatokat is rajzol-
hatunk. E függvény bemenete egy képazonosító, a pontok koordinátáiból álló
tömb, az alakzat pontjainak számát jelzõ egész szám és egy színazonosító.
Az imagepolygon() bemenetét képezõ tömbnek számmal indexeltnek kell
lennie. Az elsõ két elem az elsõ pont koordinátáit adja meg, a második kettõ
a második pontét és így tovább. Az imagepolygon() függvény megrajzolja
a pontok közötti vonalakat és az utolsó pontot automatikusan összeköti
az elsõvel. Az imagefilledpolygon() függvény segítségével színnel kitöltött
sokszögek hozhatók létre.
14_ora.qxd 8/3/2001 6:21 PM Page 267
14.6. ábra
Sokszög rajzolása az
imagefilledpolygon()
függvénnyel
14
14_ora.qxd 8/3/2001 6:21 PM Page 268
14.7. ábra
A színek átlátszóvá
tétele az image-
colortransparent()
függvénnyel
Szövegek kezelése
Ha rendszerünkön vannak TrueType betûk, a képekre írhatunk is. A GD program-
könyvtár mellett szükségünk lesz a FreeType programkönyvtár telepítésére is. Ha
ezek rendelkezésünkre állnak, egy képben megjelenõ diagramokat és navigációs
elemeket is létrehozhatunk. A PHP biztosít számunkra egy olyan eszközt is, amellyel
ellenõrizhetjük, hogy a beírandó szöveg elfér-e a rendelkezésre álló helyen.
Létrehozunk egy 400 képpontnyi széles és 200 képpontnyi magas vásznat, meg-
adunk két színt és a $betukeszlet változóban tároljuk a TrueType betûtípus el-
érési útját. Ezután ráírjuk az ábrára a Üdvözöljük! szöveget. Figyelem, a betûtí-
pusok a kiszolgálón feltehetõleg más könyvtárban találhatók! Ha nem vagyunk
biztosak a helyben, keressük a .ttf kiterjesztésû fájlokat.
14.8. ábra
Szöveg írása az
imageTTFtext() függ-
vénnyel
14_ora.qxd 8/3/2001 6:21 PM Page 271
Persze most még csak találgatunk, hová tegyük a szöveget. A betûméret nem árul
el sokat a szöveg magasságáról, a szélességérõl még kevesebbet.
Az imageTTFtext() függvény persze visszaad információt a szöveg kiterjedésé-
rõl, de akkorra már minden eldõlt. Szerencsére a PHP lehetõséget nyújt arra, hogy
próbálkozzunk, mielõtt még élesben elvégeznénk a mûveletet.
az alapvonal alá. Lehetséges, hogy a 7-es elem 10 lesz, mivel a szöveg 10 kép-
ponttal van az alapvonal fölé emelve. A pontos értékek betûtípustól és betûméret-
tõl függnek.
Ezt a kódot egy másik oldal is meghívhatja, egy IMG elem részeként. A következõ
részlet egy olyan programot hoz létre, amely lehetõvé teszi az egyes felhasználóknak,
hogy saját szöveget jelenítsenek meg az ábrán:
1: <?php
2: if ( ! isset( $szoveg ) )
3: $szoveg = "Dinamikus szöveg!";
4: ?>
5: <form action="<? print $PHP_SELF ?>" method="POST">
6: <input type="text" name="szoveg">
7: </form>
8: <p>
9: <img src="14.9.program.php?<? print
"szoveg=".urlencode($szoveg) ?>">
14.9. ábra
Szöveg elhelyezése az
imageTTFbox() függ-
vény használatával
14_ora.qxd 8/3/2001 6:21 PM Page 275
Létre kell hoznunk néhány változót, így ügyfelünk egyéni igényeihez igazíthatja
az ábrát:
$teljesszelesseg = 400;
$teljesmagassag = 200;
$xmargo = 20; // jobb és bal margó
$ymargo = 20; // felsõ és alsó margó
$oszlopkoz = 5; // az oszlopok közötti hely
$alsokeret = 40; // az ábra alján kimaradó hely
å (a margót nem számolva)
$betukeszlet = "/usr/local/office52/share/fonts/
å /TrueType/arial.ttf";
14
Ügyfelünk a változók módosításával meghatározhatja az ábra magasságát és széles-
ségét. Az $xmargo és $ymargo a grafikon körüli margóvastagságot adja meg.
Az $oszlopkoz az oszlopok közötti távolságot határozza meg, az $alsokeret
változó pedig az oszlopok alatti címkéknek szánt hely nagyságát.
Most hogy megvannak ezek az értékek, a némi számolgatás árán belõlük kapott
hasznos számokat változókba tesszük:
14_ora.qxd 8/3/2001 6:21 PM Page 276
14.10. ábra
Egy dinamikus osz-
lopdiagram
Összefoglalás
A GD programkönyvtár PHP-s támogatása lehetõvé teszi, hogy dinamikus oszlop-
diagramokat és navigációs elemeket hozhassunk létre, viszonylag könnyen.
Kérdések és válaszok
Fellépnek-e teljesítménybeli problémák dinamikus képek használata
esetén?
Egy dinamikusan létrehozott kép lassabban töltõdik be a böngészõbe, mint egy
már létezõ fájl. A program hatékonyságától függõen ezt a felhasználó nem feltétle-
nül veszi észre, de azért a dinamikus képeket módjával használjuk.
14_ora.qxd 8/3/2001 6:21 PM Page 281
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Milyen fejlécsort kell a böngészõnek küldenünk a GIF kép létrehozása és
megjelenítése elõtt?
Feladatok 14
1. Írjunk egy programot, amely egy folyamatjelzõt hoz létre, amely mutatja,
mennyi pénz folyt be egy gyûjtés alkalmával az adott célra szükséges pénzbõl.
2. Írjunk egy programot, amely egy fõcímet ábrázoló képet ír ki egy bejövõ ûr-
lap vagy lekérdezés adataiból. Tegyük lehetõvé, hogy a felhasználó határoz-
za meg a rajzterületet, az elõtér és a háttér színét, valamint az árnyék meglét-
ét és annak méretét.
14_ora.qxd 8/3/2001 6:21 PM Page 282
15_ora.qxd 8/3/2001 6:21 PM Page 283
15. ÓRA
Dátumok kezelése
A dátumok annyira mindennapjaink részét képezik, hogy nem is gondolkodunk,
amikor velük dolgozunk, naptárunk fortélyainak helyes kezelése azonban a prog-
ramokat meglehetõsen bonyolulttá teheti. Szerencsére a PHP hatékony eszközöket
biztosít a dátumszámításhoz, amely megkönnyíti a feladatot.
A time() által visszaadott egész szám a greenwichi középidõ szerinti 1970. január 1.
éjfél óta eltelt másodpercek számát adja meg. Ez a dátum a UNIX kor kezdete
néven ismeretes, az azóta eltelt másodpercek számát pedig idõbélyegnek (néha idõ-
bélyegzõ, time stamp) nevezik. Az idõbélyeget a PHP eszközeivel emberi fogyasz-
tásra alkalmasabb formára hozhatjuk, de felmerül a kérdés: még ha ilyen nagyszerû
eszközök is állnak rendelkezésünkre, az idõbélyeg nem feleslegesen túlbonyolított
módja a dátum tárolásának? Nem, éppen ellenkezõleg: egyetlen számból rengeteg
információt szerezhetünk. És ami még ennél is jobb, az idõbélyeggel sokkalta
könnyebben lehet számításokat végezni, mint azt gondolnánk.
15.1. ábra
A getdate() függvény
használata
óra
perc
másodperc
hónap
hónap napja
év
15
dátumszámításokhoz lehet hasznos.
checkdate( 4, 4, 1066 )
Egy példa
Próbáljunk meg ezen függvények közül egyetlen példán belül minél többet
használni. Készítsünk naptárat, amely egy 1980 és 2010 közötti tetszõleges hónap
napjait mutatja. A felhasználó lenyíló menüvel választhatja ki a hónapot és az évet.
A program kimenetében az adott hónap dátumai a hét napjainak megfelelõen ke-
rülnek elrendezésre. Két globális változót használunk, a $honap és az $ev válto-
zókat, melyek adatait a felhasználó adja meg. A két változó segítségével elkészít-
jük a meghatározott hónap elsõ napjának idõbélyegét. Ha nem adtuk meg az évet
vagy a hónapot, vagy megadtuk, de a bevitt adat nem érvényes, a program beme-
netének alapbeállításként a folyó év aktuális hónapjának elsõ napját tekintjük.
A 15.4. program egy nagyobb program részlete, így önmagában nincs kimenete.
Az if utasításban a checkdate() függvényt használjuk a $honap és az $ev
változók ellenõrzésére. Ha ezek nem meghatározottak, a checkdate() false
(hamis) értéket ad vissza, mivel nem hozhatunk létre érvényes dátumot meghatá-
rozatlan hónap és év paraméterekbõl. E megközelítés további haszna, hogy
egyúttal a felhasználó által bevitt adat érvényességét is ellenõrizzük.
Most hogy megbizonyosodtunk, hogy a program bemenetét képezõ két változó ér-
vényes adatot tartalmaz, az mktime() függvényt használjuk a hónap elsõ napja
idõbélyegének létrehozására. A késõbbiek során még szükségünk lesz ennek
az idõbélyegnek a napjára és hónapjára, ezért létrehozunk egy $elsoNapTombje
nevû változót, amely a getdate() függvény által visszaadott és ezen az idõbélye-
gen alapuló asszociatív tömb lesz. Végül a magyar héthasználatnak megfelelõen
át kell alakítanunk a hét napjára vonatkozó értéket. A getdate() és más dátum-
függvények a hét elsõ napjának a vasárnapot tekintik. Ezért ha a hét elsõ napján
vagyunk (ez kapja a nullás számot), akkor hetedikre írjuk át, egyébként pedig
a nap számát eggyel csökkentjük. Így a vasárnap a hét végére kerül, a többi nap
pedig eggyel elõrébb, azaz a hétfõ az elsõ helyen szerepel.
Így egy olyan ûrlapot kapunk, amely saját magának elküldi a hónap és év
paramétereket, és amelynek vagy az aktuális év és hónap, vagy pedig az elõzõleg
megadott év és hónap az alapbeállítása. A kész ûrlapot a 15.2. ábrán láthatjuk.
15
15_ora.qxd 8/3/2001 6:21 PM Page 294
15.2. ábra
A naptár ûrlapja
Mivel a táblázat fejlécébe a hét napjai kell, hogy kerüljenek, a programot végiglép-
tetjük a napok neveinek tömbjén és mindegyiket saját cellájába írjuk. A lényeg
a program utolsó for ciklusában történik.
Ha látjuk, hogy még a ciklus elsõ lefutásában vagy egy cellasor végénél vagyunk,
elvégzünk még egy ellenõrzést: megvizsgáljuk, hogy a $napTomb mon (hónap-
szám) eleme nem egyenlõ-e a $honap változóval. Ha nem egyenlõ, a ciklust befe-
jezhetjük. Emlékezzünk vissza, hogy a $napTomb-ben ugyanaz az idõpont van,
mint ami a $kezdet-ben, ami viszont a hónapnak pontosan az a része, amelyet
megjelenítünk. Ha a $kezdet túljut az aktuális hónapon, a $napTomb[mon] más
számot fog tartalmazni, mint a felhasználó által megadott $honap szám. A mara-
dékosztás igazolta, hogy éppen egy sor végén állunk: ha új hónapban járunk,
elhagyhatjuk a ciklust, ha viszont a sor végére értünk és még mindig ugyanabban
a hónapban vagyunk, befejezzük a sort és újat kezdünk.
A végsõ else utasításnál jön a feladat érdekes része. Azzal már tisztában vagyunk,
hogy a kiírandó hónapban vagyunk és az aktuális nap oszlopa megegyezik
az $elsoNapTombje változóban tárolt számmal. Most kerül felhasználásra a ciklus
korábbi részében létrehozott $napTomb asszociatív tömb, valamint a hónapok
magyar neveit tartalmazó $honapok tömb, hogy kiírjuk a hónap nevét és napját
egy cellába.
15
15_ora.qxd 8/3/2001 6:21 PM Page 298
15.3. ábra
A naptárprogram
Összefoglalás
Ezen az órán megtanultuk, hogyan használjuk a time() függvényt az aktuális
idõbélyeg megszerzésére. Megtanultuk, hogyan használjuk az idõbélyegbõl
a dátum részeinek kinyerésére a getdate() függvényt és az idõbélyeget formá-
zott szöveggé alakító date() függvényt. Arról is tanultunk, hogyan hozzunk létre
idõbélyeget az mktime() függvénnyel. Megtanultuk ellenõrizni a dátum érvé-
nyességét a checkdate() függvénnyel, magyar elvárások szerint formáztunk
dátumokat, végül tanulmányoztunk egy példaprogramot, amely az említett
függvényeket alkalmazta.
Kérdések és válaszok
Vannak olyan függvények, amelyekkel a különbözõ naptárak között
váltogatni lehet?
Igen, a PHP naptárak teljes sorozatát biztosítja. Ezekrõl a hivatalos
PHP kézikönyvben olvashatunk,
a http://www.php.net/manual/ref.calendar.php címen.
15_ora.qxd 8/3/2001 6:21 PM Page 299
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Hogyan kapunk meg egy UNIX idõbélyeget, amely a pontos dátumot és
idõt jelöli?
Feladatok
1. Készítsünk egy születésnapig visszaszámláló programot. Ûrlappal lehessen
megadni az év, hó és nap értékeit, kimenete pedig egy üzenet legyen, amely
közli a felhasználóval, hogy hány nap, óra, perc, másodperc van még hátra
a nagy napig.
15
15_ora.qxd 8/3/2001 6:21 PM Page 300
16_ora.qxd 8/3/2001 6:21 PM Page 301
16. ÓRA
Az adatok kezelése
Ezen az órán az adatellenõrzésben és az adatmûveletekben fogunk egy kicsit
elmélyedni. Újra áttekintjük az adattípusokat. A PHP ugyan automatikusan kezeli
ezeket, de elengedhetetlen, hogy értsük az adatkezelést, ha nagy, megbízható
hálózati alkalmazásokat kell írnunk. Visszatérünk a tömbökhöz is és végül megis-
merkedünk a PHP fejlettebb adatkezelési, adatosztályozási eljárásaival.
Újra az adattípusokról
A negyedik órában már tanultunk néhány dolgot a PHP adattípusairól. Van azonban
még valami, ami eddig kimaradt. Ebben a részben a változók adattípusának ellenõr-
zésére használt függvények közül ismerkedünk meg néhánnyal, majd sorra vesszük
azokat a feltételeket, amelyek mellett a PHP automatikusan elvégzi helyettünk
az adattípus-átalakításokat.
$adat = 454;
print gettype( $adat );
// azt írja ki, hogy "integer", azaz egész szám
$adat = 4.333;
print ( integer ) $adat;
// "4"-et ír ki
$adat = 4.333;
settype( $adat, "integer" );
print $adat;
// "4"-et ír ki
Amikor egy egyszerû adattípust tömbbé alakítunk, olyan tömb jön létre, melynek
elsõ eleme az eredeti érték lesz:
Fordított esetben, egy objektum tömbbé alakításakor, olyan tömb jön létre, amely-
ben minden objektum tulajdonságnak megfelel egy tömbelem. A metódusokat
az átalakítás figyelmen kívül hagyja.
class Pont
{
var $x;
var $y;
function Pont( $x, $y )
{
$this->x = $x; 16
$this->y = $y;
16_ora.qxd 8/3/2001 6:21 PM Page 304
}
}
$pont = new Pont( 5, 7 );
$tomb_pont = (array) $pont;
print $tomb_pont["x"];
// azt írja ki, hogy "5"
Tegyük fel, hogy egy felhasználót megkérdezünk, hány órát tölt a hálózaton
hetente, és a választ az $orak nevû változóban tároljuk. Ez kezdetben szövegként
kerül tárolásra.
$orak = "15"
if ($orak > 15)
print "Ilyen gyakori felhasználónak akár árengedmény
is járhatna";
4 * "20mb"
Ha a karakterlánc nem számmal kezdõdik, 0-vá alakul. Így a következõ sor 0-át ad
eredményül:
4 * "körülbelül 20mb"
4 * "1.2"
16_ora.qxd 8/3/2001 6:21 PM Page 305
$szoveg = "4";
$szoveg++;
print $szoveg; // kiírja az 5-öt
print gettype( $szoveg ); // azt írja ki, hogy "string"
$szoveg = "alszol";
$szoveg++;
print $szoveg; // azt írja ki, hogy "alszom"
$szoveg = "alszol";
$szoveg += 1;
print $szoveg; // 1-et ír ki
print gettype( $szoveg ); // azt írja ki, hogy "integer",
azaz egész szám
Az elõzõ példában a $szoveg változó elõször 0-vá (egész számmá) alakul, aztán
adjuk hozzá az 1-et. Ennek a mûveletnek az eredménye 1, amelyet újra a $szoveg
változóba helyezünk. A változó most már egy egész számot fog tartalmazni.
$eredmeny = ( 1 + 20.0);
print gettype( $eredmeny );
// azt írja ki, hogy "double", azaz lebegõpontos
16
16_ora.qxd 8/3/2001 6:21 PM Page 306
Az adattípusok ellenõrzése
Már le tudunk kérdezni adattípusokat a gettype() függvénnyel, ami a hibakere-
sésnél jól jöhet, hiszen minden változóról meg tudjuk mondani, hogy milyen típusú.
Gyakran viszont csak azt szeretnénk megnézni, hogy a változó egy bizonyos adattí-
pusú értéket tartalmaz-e. A PHP ehhez az egyes adattípusoknak megfelelõ függvé-
nyeket biztosít, amelyek bemenete egy változó vagy egy érték, visszatérési értéke
pedig logikai. A függvények listáját a 16.1. táblázat tartalmazza.
megegyezik a
if ( is_array( $valtozo ) )
print "ez egy tömb";
tombKiir ( 4 );
// Warning: Non array argument supplied for foreach() in
// /home/httpd/htdocs/proba2.php on line 5
// azaz "Figyelmeztetés: a foreach() függvénynek nem tömb
å paramétert adtunk át
// a /home/httpd/htdocs/proba2.php program 5.
å sorában"
16
16_ora.qxd 8/3/2001 6:21 PM Page 308
Most már a hívó kód ellenõrizheti a függvény visszaadott értékeit, hogy megálla-
píthassa, végre tudta-e hajtani feladatát.
Erre láttunk egy példát a tizedik órában. A readdir() függvény hamis (false)
értéket ad vissza, amikor eléri a beolvasott könyvtár végét, minden más esetben
viszont a könyvtár egyik elemének nevét tartalmazó karakterláncot. Hagyományo-
san a következõhöz hasonló szerkezetet használnánk, ha egy könyvtár elemeit
szeretnénk beolvastatni:
$nincsertek;
if ( isset( $nincsertek ) )
print "a \$nincsertek változónak van értéke";
else
print "a \$nincsertek változónak nincs értéke";
// kiírja, hogy "a $nincsertek változónak nincs értéke"
Azt a változót, amelyet már bevezettünk, de amelynek még nem adtunk értéket,
a függvény nem beállítottként, érték nélküliként fogja kezelni.
Egy veszélyre azonban hadd hívjuk fel a figyelmet: ha 0-át vagy üres karakterláncot
rendelünk egy változóhoz, a függvény azt már beállítottként, értékkel rendelke-
zõnek fogja tekinteni:
$nincsertek = "";
if ( isset( $nincsertek ) )
print "a \$nincsertek változónak van értéke";
else
print " a \$nincsertek változónak nincs értéke ";
// kiírja, hogy "a $nincsertek változónak van értéke"
Azok a változók, amelyeket a bejövõ ûrlapok töltenek fel értékkel, mindig beállí-
tottként fognak szerepelni, még akkor is, ha a felhasználó egyetlen mezõt sem
töltött ki adattal. Hogy az ilyen helyzetekkel megbirkózhassunk, elõször ellenõriz- 16
nünk kell, hogy üres-e a változó. Az empty() függvény bemenete egy változó,
16_ora.qxd 8/3/2001 6:21 PM Page 310
kimenete pedig true (igaz), ha a változó nincs beállítva vagy olyan adatot tartal-
maz, mint a 0 vagy egy üres karakterlánc. Akkor is igaz értéket ad vissza,
ha a változó üres tömböt tartalmaz:
$nincsertek = "";
if ( empty( $nincsertek ) )
print "a \$nincsertek változó üres";
else
print " a \$nincsertek változó adatot tartalmaz";
// kiírja, hogy "a $nincsertek változó üres"
Tömb létrehozásakor a PHP egy belsõ mutatót alkalmaz, amely a tömb elsõ
elemére mutat. Ennek az elemnek a kulcsához és értékéhez az each()
függvénnyel férhetünk hozzá. Az each() függvény bemenete egy tömbváltozó,
kimenete pedig egy négyelemû tömb. Ezek közül az elemek közül kettõ számmal
indexelt, kettõ pedig a "key" (kulcs) és az "value" (érték) címkét viseli.
A függvény meghívása után a belsõ mutató a vizsgált tömb következõ elemére fog
mutatni, kivéve, ha elérte a tömb végét, ilyenkor false (hamis) értéket ad vissza.
Hozzunk létre egy tömböt és próbáljuk ki az each() függvényt:
A $reszletek nevû tömböt két elemmel hozzuk létre, ezután átadjuk az each()
függvénynek és a visszaadott értéket az $elem nevû tömbbe helyezzük. Az $elem
tartalmazza a $reszletek tömbváltozó elsõ elemének kulcsát és értékét.
Bár a kód mûködni fog, valójában még egy sor hiányzik. Ha tömbünkre már
használtuk a belsõ mutatót módosító függvények egyikét, az már nem a tömb
elejére mutat. A reset() függvénnyel visszaállíthatjuk a mutatót a tömb kezde-
tére. Ez a függvény paraméterként egy tömbváltozót vár.
egyenértékû a következõvel:
reset( $reszletek );
while ( list( $kulcs, $ertek ) = each( $reszletek ) )
print "$kulcs: $ertek<BR>";
16
16_ora.qxd 8/3/2001 6:21 PM Page 312
unset( $proba["cim"] );
unset( $szamok[1] );
$szamok[0]
$szamok[2]
$szamok[3]
Vegyünk egy példát. Van egy adatbázisból kinyert ártömbünk, de mielõtt munkához
kezdenénk vele, az összes árhoz hozzá kell adnunk a forgalmi adót.
Elõször azt a függvényt hozzuk létre, amely hozzáadja az adót:
Összefoglalás
Az óra során a tömbökkel és adattípusokkal kapcsolatos ismeretekben mélyedtünk
el. Megtanultuk, mi történik, ha összetett adattípust skalárissá alakítunk és fordítva.
Megtudtuk, hogyan kezeli a PHP a különbözõ adattípusokat egy kifejezésben,
hogyan határozza meg automatikusan az eredmény adattípusát helyettünk. Megis-
merkedtünk számos függvénnyel; például az is_array()-jel, amely különféle
adattípusokat ellenõriz, vagy az intval()-lal, amely az adatot egész értékûvé
alakítja át. Megtanultuk, hogyan lehet a PHP-ben hagyományos módon tömböt be-
járni, az each() és a list() függvénnyel. Az in_array() függvénnyel képe-
sek vagyunk ellenõrizni, hogy létezik-e egy adott érték egy tömbben, és el tudunk
távolítani egy elemet egy tömbbõl az unset() függvénnyel. Az array_walk()
függvénnyel már egy tömb összes elemén is végezhetünk mûveleteket, végül azt is
tudjuk, hogyan használjuk az usort(), az uasort() és az uksort() függvé-
nyeket arra, hogy a tömbök egyéni rendezését végezzük.
Kérdések és válaszok
A PHP minden tömbkezelõ függvényével megismerkedtünk?
Nem, az egész könyv sem lenne elég az összes tömbkezelõ függvény bemutatásához.
Teljes listájukat és leírásukat a http://www.php.net/manual/ref.array.php
weboldalon találhatjuk.
16
16_ora.qxd 8/3/2001 6:21 PM Page 318
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Melyik az a függvény, amellyel adattípusokat tetszõleges más adattípussá ala-
kíthatunk?
7. Hogyan ellenõrizzük, hogy egy változó üres értéket (például 0-át vagy üres
karakterláncot) tartalmaz?
Feladatok
1. Nézzük végig még egyszer a könyv során megoldott feladatokat. Alakítsunk
át minden foreach utasítást úgy, hogy az megfeleljen a PHP 3 követelményei-
nek is.
17. ÓRA
Karakterláncok kezelése
A Világháló valójában szöveges fájlokra épülõ környezet, és igazából nem számít,
mivel gazdagodik a jövõben a tartalma, a mélyén mindig szöveges állományokat
fogunk találni. Így nem meglepõ, hogy a PHP 4 sok olyan függvényt biztosít,
amellyel szövegmûveletek végezhetõk.
Karakterláncok formázása
A megjeleníteni kívánt karakterláncot eddig egyszerûen kiírattuk a böngészõbe.
A PHP két olyan függvényt tartalmaz, amely lehetõvé teszi az elõzetes formázást,
függetlenül attól, hogy tizedestörteket kell valahány tizedes pontosságra kerekíte-
ni, egy mezõn belül kell jobbra vagy balra igazítani valamit, vagy egy számot kell
különbözõ számrendszerekben megjeleníteni. Ebben a részben a printf() és
az sprintf() függvények által biztosított formázási lehetõségekkel ismerkedünk
meg.
A printf() és a típusparaméterek
Egy típusparaméterrel már találkoztunk, ez volt a d, amely az adatot decimális 17
formátumban jeleníti meg. A többi típusparamétert a 17.1. táblázatban láthatjuk.
17.1. ábra
Néhány típusparamé-
ter használatának
bemutatása
$piros = 204;
$zold = 204;
$kek = 204;
printf( "#%X%X%X", $piros, $zold, $kek );
// azt írja ki, hogy "#CCCCCC"
17_ora.qxd 8/3/2001 6:21 PM Page 323
A kitöltõ paraméter
Beállíthatjuk, hogy a kimenet bizonyos karakterekkel megfelelõ szélességûre
töltõdjön ki. A kitöltõ paraméter közvetlenül az átalakító paramétert kezdõ száza-
lékjelet követi. Ha a kimenetet bevezetõ nullákkal szeretnénk kitölteni, a kitöltõ
paraméterben a 0 karaktert az a szám követi, ahány karakteresre szeretnénk
a kimenetet bõvíteni. Ha a kimenet hossza ennél a számnál kisebb lenne, a különb-
ség nullákkal kerül kitöltésre, ha nagyobb, a kitöltõ paraméternek nincs hatása:
printf( "%04d", 36 )
// a kimenet "0036" lesz
printf( "%04d", 12345 )
// a kimenet "12345" lesz
printf( "%'x4d", 36 )
// azt írja ki "xx36"
$piros = 1;
$zold = 1;
$kek = 1;
printf( "#%02X%02X%02X", $piros, $zold, $kek );
// azt írja ki, hogy "#010101"
A mezõszélesség meghatározása
Meghatározhatjuk a kimenet által elfoglalt mezõ szélességét is. A mezõszélesség 17
paramétere egy olyan egész szám, amely a százalékjel után következik az átalakító
paraméterben (feltéve, hogy nem használunk helykitöltõ karaktereket). A követ-
kezõ kódrészlet kimenete egy négyelemû felsorolás, amelynek mezõszélessége
20 karakternyi. A szóközök láthatóvá tételéhez a kimenetet egy PRE elembe
ágyazzuk.
print "<pre>";
printf("%20s\n", "Könyvek");
printf("%20s\n", "CDk");
printf("%20s\n", "Játékok");
printf("%20s\n", "Magazinok");
print "</pre>";
17.2. ábra
Igazítás a mezõszé-
lességhez
A pontosság meghatározása
Ha az adatot lebegõpontos formában szeretnénk megjeleníteni, meghatározhatjuk
a kerekítés pontosságát. Ez fõleg a pénznem átváltásakor szokott fontos lenni.
A pontosságot meghatározó paraméter egy pontból és egy számból áll, és közvet-
lenül a típusparaméter elé kell írni. A megadott szám határozza meg, hány tize-
desre szeretnénk kerekíteni. Ez a paraméter csak akkor érvényes, ha a kimenet
f típusparaméterû:
17
17.2. program Termékárlista formázása a printf() függvénnyel
1: <html>
2: <head>
3: <title>17.2. program Termékárlista formázása
a printf() függvénnyel</title>
4: </head>
5: <body>
6: <?php
7: $termekek = Array("Zöld karosszék"=>"222.4",
8: "Gyertyatartó" => "4",
9: "Kávézóasztal" => "80.6"
10: );
11: print "<pre>";
12: printf("%-20s%23s\n", "Név", "Ár");
13: printf("%'-43s\n", "");
14: foreach ( $termekek as $kulcs=>$ertek )
15: printf( "%-20s%20.2f\n", $kulcs, $ertek );
16: print "</pre>";
17: ?>
18: </body>
19: </html>
Elõször a termékek nevét és árát tartalmazó tömböt adjuk meg. Egy PRE elemmel
jelezzük a böngészõnek, hogy a szóközöket és a soremeléseket értelmezze.
A printf() elsõ meghívása a következõ formázó karakterláncot adja meg:
"%-20s%23s\n"
Az elsõ ("%-20s") a termék nevét írja ki egy 20 karakteres mezõbe, balra igazít-
va. A másik ("%20.2f") a mezõszélesség paraméterrel azt biztosítja, hogy
az eredmény egy 20 karakteres mezõben jobbra igazítva jelenjen meg, a pontossá-
gi paraméterrel pedig azt, hogy a megjelenített kétszeres pontosságú érték két
tizedesre legyen kerekítve.
17.3. ábra
Termékárlista formá-
zása a printf() függ-
vénnyel
Részletesebben a karakterláncokról
Nem minden esetben tudunk mindent azokról az adatokról, amelyekkel dolgo- 17
zunk. A karakterláncok többféle forrásból is érkezhetnek, beviheti a felhasználó,
érkezhetnek adatbázisokból, fájlokból és weboldalakról. A PHP 4 több függvénye
segítségünkre lehet abban, hogy ezekrõl a külsõ forrásból érkezõ adatokról többet
tudjunk meg.
Szövegek indexelése
A karakterláncokkal kapcsolatban gyakran használjuk az indexelés szót, de
a tömböknél még gyakrabban találkozhatunk vele. Valójában a karakterláncok és
a tömbök nem állnak olyan messze egymástól, mint azt gondolnánk. Egy karakter-
láncot elképzelhetünk egy karakterekbõl álló tömbként is. Ennek megfelelõen
a karakterláncok egyes karaktereihez ugyanúgy férhetünk hozzá, mint egy tömb
elemeihez:
$proba = "gazfickó";
print $proba[0]; // azt írja ki, hogy "g"
print $proba[2]; // azt írja ki, hogy "z"
Ne felejtsük el, hogy amikor egy karakterláncon belüli karakter indexérõl vagy
helyérõl beszélünk, akkor a karaktereket ugyanúgy, mint a tömb elemeit 0-tól
kezdve számozzuk. A tömbökkel kapcsolatos félreértések elkerülése érdekében
a PHP 4 bevezette a $proba{0} formát is erre a célra.
if ( strlen( $tagazonosito ) == 4)
print "Köszönöm!";
else
print "Az azonosítónak négykarakteresnek kell lennie<P>";
$tagazonosito = "pAB7";
if ( strstr( $tagazonosito, "AB" ) )
print "Köszönöm. Ne feledje, hogy tagsága hamarosan
lejár!";
else
print "Köszönöm!";
$tagazonosito = "mz00xyz";
if ( strpos($tagazonosito, "mz") === 0 )
print "Üdv, mz.";
17_ora.qxd 8/3/2001 6:21 PM Page 331
$proba = "gazfickó";
print substr($proba,3); // azt írja ki "fickó"
print substr($proba,3,4); // azt írja ki "fick"
$cim = "felhasznalo@szolgaltato.hu"
if ( substr( $cim, -3 ) == ".hu" )
print "Ne felejtse el magyar vásárlóinknak járó
speciális ajánlatainkat!";
else
print "Üdvözöljük üzletünkben!";
Az strtok() függvény önmagában nem sok mindent támogat, így csak különfé-
le trükkökkel bírhatjuk igazán hasznos munkára. Elõször a $hatarolo változó-
ban tároljuk a határolójelet. Meghívjuk az strtok() függvényt, átadjuk neki
az elemzendõ URL-t és a $hatarolo karakterláncot. Az elsõ eredményt a $szo
változóba helyezzük. A while ciklus feltételében azt ellenõrizzük, hogy a $szo
karakterlánc-e. Ha nem az, tudhatjuk, hogy elértük az URL végét és a feladat
befejezõdött.
Azért ellenõrizzük a visszaadott érték típusát, mert ha egy karakterlánc egy sorá-
ban két határolójel van, az strtok() az elsõ határolójel elérésekor üres karakter-
láncot ad vissza. Így, ha a $szo egy üres karakterlánc, az alábbi példában látható
szokványosabb próbálkozás sikertelen lesz, még akkor is, ha a függvény még
nem érte el a forráslánc végét, mivel a while feltétele hamissá válik:
while ( $szo )
{
$szo = strtok( $hatarolo );
}
17_ora.qxd 8/3/2001 6:21 PM Page 333
A karakterláncok kezelése
A PHP 4 a karakterlánc paraméterek kisebb-nagyobb átalakításához számos
függvényt biztosít.
<?
$tagazonosito = "mz99xyz";
$tagazonosito = substr_replace( $tagazonosito, "00", 2, 2 );
print "Az új tagnyilvántartó azonosító: $tagazonosito<p>";
// azt írja ki, hogy "Az új tagnyilvántartó azonosító:
mz00xyz"
?>
$tagazonosito = "mz00xyz";
$tagazonosito = strtoupper( $tagazonosito );
print "$tagazonosito<P>"; // azt írja ki, hogy "MZ00XYZ"
$honlap_url = "WWW.KISKAPU.HU";
$honlap_url = strtolower( $honlap_url );
if ( ! ( strpos ( $honlap_url, http:// ) === 0 ) )
$honlap_url = "http://$honlap_url";
print $honlap_url; // azt írja ki, hogy
"http://www.kiskapu.hu"
Fel kell, hogy hívjuk a kedves olvasó figyelmét arra, hogy a magyar szövegekkel
az ékezetes betûk miatt alapbeállításban problémáink akadhatnak. A nemzeti be-
állítások testreszabására használható setlocale() függvényt kell alkalmaznunk,
hogy a kívánt eredményt elérjük.
$kezdet = "2000.12.01";
$datum_tomb = explode(".", $kezdet);
// $datum_tomb[0] == "2000"
// $datum_tomb[1] == "12"
// $datum_tomb[2] == "00"
Összefoglalás
A PHP külvilággal való kapcsolattartása és adattárolása leginkább karakterláncokon
keresztül valósul meg. Az órán a programjainkban levõ karakterláncok kezelésével
ismerkedtünk meg.
Kérdések és válaszok
Vannak még egyéb hasznos karakterlánc-függvények?
Vannak. A PHP több mint 60 ilyen függvénnyel rendelkezik! Ezekrõl a PHP 4
kézikönyvében olvashatunk, amelynek megfelelõ része
a http://php.net/manual/ref.strings.php címen található.
Header("Content-type: text/plain");
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Milyen átalakító paramétert használnánk a printf() függvényben
egy egész szám lebegõpontos számként való megformázására?
Feladatok
1. Hozzunk létre egy olyan vélemény-visszajelzõ ûrlapot, amely a felhasználó
nevét és e-mail címét kéri be. Használjuk a kis- és nagybetûket átalakító
függvényeket a nevek elsõ betûjének nagybetûsítésére, majd jelenítsük meg
az eredményt a böngészõben. Ellenõrizzük, hogy a cím tartalmaz-e @-jelet,
ha nem, figyelmeztessük a felhasználót.
18. ÓRA
A szabályos kifejezések
használata
A szövegek vizsgálatának és elemzésének nagyszerû módja a szabályos kifejezések
(regular expressions) használata. Ezek lehetõvé teszik, hogy egy karakterláncon
belül mintákat keressünk, a találatokat pedig rugalmasan és pontosan kapjuk
vissza. Mivel hatékonyabbak az elõzõ órában tanult karakterlánc-kezelõ függvé-
nyeknél, lassabbak is azoknál. Így azt tanácsoljuk, hogy ha nincs különösebb
szükségünk a szabályos kifejezések által biztosított hatékonyságra, inkább hasz-
náljuk a hagyományos karakterlánc-kezelõ függvényeket.
A PHP a szabályos kifejezések két típusát támogatja. Egyrészt támogatja a Perl által
használtakat, az azoknak megfelelõ függvényekkel, másrészt a korlátozottabb
tudású POSIX szabályos kifejezés formát. Mindkettõvel meg fogunk ismerkedni.
if ( ereg("a+","aaaa", $tomb) )
print $tomb[0];
// azt írja ki, hogy "aaaa";
Vegyünk egy példát. Egy klub tagsági azonosítóval jelöli tagjait. Egy érvényes azo-
nosítóban egy és négy közötti alkalommal fordul elõ a "t", ezt tetszõleges számú
szám vagy betû karakter követi, majd a 99-es szám zárja. A klub arra kért fel
bennünket, hogy a tennivalókat tartalmazó naplóból emeljük ki a tagazonosítókat.
Úgy tûnik, ezzel megoldottuk a feladatot, pedig még attól meglehetõsen távol
állunk. A feltételek között a 99-cel való végzõdést azzal próbáltuk biztosítani,
hogy megadtuk, hogy egy szóköz legyen az utolsó karakter. Ezt aztán találat
esetén vissza is kaptuk. Még ennél is nagyobb baj, hogy ha a forráslánc
Szép lassan alakul. Az a karakterosztály, amit hozzáadtunk, már nem fog szóköz-
ökre illeszkedni, így végre az azonosítót kapjuk meg. Viszont ha az azonosító után
a próba-karakterlánc végére vesszõt írunk, a szabályos kifejezés megint nem il-
leszkedik:
Ez azért van, mert a minta végén egy szóközt várunk el, amely alapján meggyõ-
zõdhetünk, hogy elértük az azonosító végét. Így ha egy szövegben az azonosító
zárójelek közt van, kötõjel vagy vesszõ követi, a minta nem illeszkedik rá. Köze-
lebb visz a megoldáshoz, ha úgy javítunk a szabályos kifejezésen, hogy mindenre
illeszkedjék, csak szám és betû karakterekre nem:
18_ora.qxd 8/3/2001 6:22 PM Page 344
Már majdnem kész is vagyunk, de még mindig van két probléma. Egyrészt
a vesszõt is visszakapjuk, másrészt a szabályos kifejezés nem illeszkedik, ha
az azonosító a karakterlánc legvégén van, hiszen megköveteltük, hogy utána
még egy karakter legyen. Más szóval a szóhatárt kellene megbízható módon
megtalálnunk. Erre a problémára késõbb még visszatérünk.
Az atomok kezelése
Az atom egy zárójelek közé írt minta (gyakran hivatkoznak rá részmin-
ÚJDONSÁG
taként is). Meghatározása után az atomot ugyanúgy kezelhetjük, mintha
maga is egy karakter vagy karakterosztály lenne. Más szóval ugyanazt a 18.1. táblá-
zatban bemutatott rendszer alapján felépített mintát annyiszor kereshetjük, ahány-
szor csak akarjuk.
$proba = "abbaxaabaxabbax";
if ( ereg( "([ab]+x){2}", $proba, $tomb ) )
print "$tomb[0]";
// azt írja ki, hogy "abbaxaabax"
$ipcim = "158.152.55.35";
if ( ereg( "([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)", $ipcim,
$tomb ) )
{
foreach ( $tomb as $ertek )
print "$ertek<BR>";
}
// Az eredmény:
// 158.152.55.35
18
// 158
// 152
// 55
// 35
Elágazások
A szûrõkarakter (|) segítségével mintákat összekötve a szabályos kifejezéseken
belül elágazásokat hozhatunk létre. Egy kétágú szabályos kifejezés vagy az elsõ
mintára, vagy a második mintára illeszkedõ karakterláncokat keresi meg. Ettõl lesz
a szabályos kifejezések nyelvtana még rugalmasabb. A következõ kódrészletben
a .com, a .de vagy a .hu karakterláncot keressük:
$domain = "www.egydomain.hu";
if ( ereg( "\.com|\.de|\.hu", $domain, $tomb ) )
print "ez egy $tomb[0] tartomány<BR>";
// azt írja ki, hogy "ez egy .hu tartomány"
A karakterlánc végén úgy illeszthetjük a mintát, hogy dollárjelet ($) írunk a szabályos
kifejezés végére. Az a$ illeszkedik a "róka", de nem illeszkedik a "hal" szóra.
18_ora.qxd 8/3/2001 6:22 PM Page 346
Amint láthatjuk, a szabályos kifejezések elsõre egy kicsit riasztók, de miután kisebb
egységekre bontjuk azokat, általában egész könnyen értelmezhetõk. Elértük, hogy
mintánk egy szóhatárra illeszkedjen (pontosan úgy, ahogy azt a feladat megköve-
telte). Mivel nem vagyunk kíváncsiak semmilyen, a mintát megelõzõ vagy követõ
szövegre, a minta számunkra hasznos részét zárójelek közé írjuk. Az eredményt
a $tomb tömb harmadik (2-es indexû) elemében találhatjuk meg.
Fontos megjegyezni, hogy míg az ereg() függvény csak a legelsõ megtalált min-
tára illeszkedik, az ereg_replace() a minta összes elõfordulását megtalálja és
lecseréli.
$datumt = "12/25/2000";
print ereg_replace("([0-9]+)/([0-9]+)/([0-9]+)",
"\\3.\\1.\\2.", $datum);
// azt írja ki, hogy "2000.12.25"
Vegyük észre, hogy a fenti kód csereszövegében a pontok nem különleges értel-
mûek, így nem is kell \ jelet tenni eléjük. A . az elsõ paraméterben kapja a tetszõ-
leges karakterre illeszkedés különleges jelentését.
18_ora.qxd 8/3/2001 6:22 PM Page 348
$szoveg = "üvegház";
if ( preg_match( "/h.*z/", $szoveg, $tomb ) )
print $tomb[0];
// azt írja ki, hogy "ház"
"/h.*z/"
"h.*z"
"h.*?z"
ereg ( "(^|[^a-zA-Z0-9_])(y{1,4}[a-zA-Z0-9_]*99)
å ([^a-zA-Z0-9_]|$)", $szoveg, $tomb );
preg_match( "\bt{1,4}\w*99\b", $szoveg, $tomb );
Fel kell, hogy hívjuk a kedves olvasó figyelmét arra, hogy a magyar szövegekre
az ékezetes betûk miatt alapbeállításban nem alkalmazható a fentihez hasonló
egyszerû szabályos kifejezés. A nemzeti beállítások testreszabására használható
setlocale() függvényt kell alkalmaznunk, hogy a kívánt eredményt elérjük.
6: <?php
7: $szoveg = "barackot, banánt, bort, búzát és
békákat árulok";
8: if ( preg_match_all( "/\bb\w+t\b/", $szoveg, $tomb ) )
9:
10:
{
for ( $x=0; $x< count( $tomb ); $x++ )
18
11: {
12: for ( $y=0; $y< count( $tomb[$x] ); $y++ )
13: print "\$tomb[$x][$y]:
".$tomb[$x][$y]."<br>\n";
14: }
15: }
16: // A kimenet:
17: // $tomb[0][0]: barackot
18: // $tomb[0][1]: banánt
19: // $tomb[0][2]: bort
20: // $tomb[0][3]: búzát
21: // $tomb[0][4]: békákat
22: ?>
23: </body>
24: </html>
A $tomb változónak a preg_match_all() függvénynek történõ átadáskor
csak az elsõ eleme létezik és ez karakterláncok egy tömbjébõl áll. Ez a tömb tartal-
mazza a szöveg minden olyan szavát, amely b-vel kezdõdik és t betûre végzõdik.
$tomb[1][1]: 01
$tomb[1][2]: 01
A $tomb[2] a második részminta értékeinek tömbjét tárolja:
$tomb[2][0]: 05
$tomb[2][1]: 10
$tomb[2][2]: 03
és így tovább.
Két tömböt hozunk létre. A $miket tömb két szabályos kifejezést, a $mikre tömb
pedig csere-karakterláncokat tartalmaz. A $miket tömb elsõ eleme a $mikre
tömb elsõ elemével helyettesítõdik, a második a másodikkal, és így tovább.
Módosító paraméterek
A Perl típusú szabályos kifejezések lehetõvé teszik, hogy módosító paraméterek
segítségével pontosítsuk a minta illesztési módját.
Az m paraméter akkor jöhet jól, ha egy szöveg több sorában szeretnénk hivatkozási
pontos mintára illeszteni. A ^ és $ minták alapértelmezés szerint a teljes karakter-
lánc elejét és végét jelzik. A következõ kódrészletben az m paraméterrel módosítjuk
a $^ viselkedését:
Egy olyan szabályos kifejezést hozunk létre, amely olyan mintára illeszkedik,
amelyben bármely szóalkotó karaktert vesszõ és tetszõleges számú szóköz követ.
Ezután tetszõleges számú karaktert követõ karakterlánc vége karakterre ($)
illesztünk. Az m paraméter miatt a $ az egyes sorok végére illeszkedik a teljes
karakterlánc vége helyett.
18_ora.qxd 8/3/2001 6:22 PM Page 357
<?php
function datumAtalakito( $honap, $nap, $ev )
{
$ev = ($ev < 70 )?$ev+2000:$ev;
$ido = ( mktime( 0,0,0,$honap,$nap,$ev) );
return date("Y. m. j. ", $ido);
}
$datumok = "3/18/99<br>\n7/22/00";
$datumok = preg_replace( "/([0-9]+)\/([0-9]+)\/([0-9]+)/e",
"datumAtalakito(\\1,\\2,\\3)",
$datumok);
print $datumok;
Összefoglalás
A szabályos kifejezések hatalmas témakört alkotnak, mi csak felületesen ismerked-
tünk meg velük ezen óra során. Arra viszont már biztosan képesek leszünk, hogy
bonyolult karakterláncokat találjunk meg és cseréljünk le egy szövegben.
Kérdések és válaszok
A Perl típusú szabályos kifejezések nagyon hatékonynak tûnnek.
Hol található róluk bõvebb információ?
A szabályos kifejezésekrõl a PHP weboldalán (http://www.php.net) találha-
tunk némi felvilágosítást. Emellett még a http://www.perl.com oldalain talál-
hatunk információt, a Perl típusú szabályos kifejezésekhez pedig
a http://www.perl.com/pub/doc/manual/html/pod/perlre.htm
címen és Tom Christiansen cikkében,
a http://www.perl.com/pub/doc/manual/html/pod/perlfaq6.html
címen találhatunk bevezetést.
18_ora.qxd 8/3/2001 6:22 PM Page 359
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Melyik függvényt használnánk egy karakterláncban minta illesztésére,
ha POSIX szabályos kifejezéssel szeretnénk a mintát meghatározni?
18
2. Milyen szabályos kifejezést használnánk, ha a "b" betû legalább egyszeri,
de hatnál nem többszöri elõfordulására szeretnénk keresni?
Feladatok
1. Gyûjtsük ki az e-mail címeket egy fájlból. A címeket tároljuk egy tömbben és
jelenítsük meg az eredményt a böngészõben. Nagy mennyiségû adattal fino-
mítsuk szabályos kifejezéseinket.
18_ora.qxd 8/3/2001 6:22 PM Page 360
19_ora.qxd 8/3/2001 6:22 PM Page 361
19. ÓRA
Állapotok tárolása sütikkel és
GET típusú lekérdezésekkel
A HTTP állapot nélküli protokoll. Ez azt jelenti, hogy ahány oldalt a felhasználó
letölt kiszolgálónkról, annyi önálló kapcsolat létesül, ráadásul az egyes oldalakon
belül a képek, külsõ fájlok letöltésére is külön kapcsolatok nyílnak. Másrészt
viszont a felhasználók és a weboldalak készítõi környezetként, azaz olyan térként
érzékelik a weboldalakat, amelyben egyetlen oldal is egy nagyobb egész része.
Így viszont nem meglepõ, hogy az oldalról oldalra való információátadás módsze-
rei egyidõsek magával a Világhálóval.
Hogyan írjunk olyan függvényt, amely egy asszociatív tömböt egy lekérdezõ
karakterlánccá alakít át?
Sütik
A Netscape munkatársai által kiötölt csodasüti (magic cookie) kifejezés még
a Netscape 1 aranykorából származik. A kifejezés pontos eredete mindmáig viták
tárgya, bár meglehetõsen valószínûnek tûnik, hogy a szerencsesütinek valami
köze lehetett hozzá. Azóta viszont már más böngészõk is alkalmazzák
ezt a szabványt.
Mindezekkel együtt a sütik kiválóan alkalmasak arra, hogy kis mennyiségû infor-
mációt tároljunk velük, mialatt a felhasználó oldalról-oldalra lépdel, vagy akár
hosszabb távon is, a webhely egyes látogatásai között.
A sütik felépítése
A sütik létrehozása általában a HTTP fejlécében történik (bár a JavaScript közvetle-
nül a böngészõvel is létre tudja hozni a sütiket). Egy sütibeállító PHP program
ilyesféle HTTP fejlécelemet kell, hogy létrehozzon:
Mint ahogy azt láthatjuk, a Set-Cookie fejléc egy névérték párt, egy greenwichi
középidõ szerinti lejárati idõpontot (expires), egy elérési utat (path) és egy tarto-
mányt (domain) tartalmaz. A név és az érték URL felépítésû kell, hogy legyen. A lejá-
rat mezõ (expires) arra ad utasítást a böngészõnek, hogy mikor felejtse el a sütit.
Az elérési út a weboldalon azt a helyet jelöli, amelynek elérésekor a sütit vissza kell
küldeni a kiszolgálóra. A tartomány mezõ azokat az internetes tartományokat jelöli ki,
ahová a sütit el kell küldeni. A tartomány nem különbözhet attól, ahonnan a sütit
küldték, viszont egy bizonyos szintû rugalmasságot is meghatározhat. Az elõzõ pél-
dánál a böngészõ a www.kiskapu.hu és a leeloo.kiskapu.hu kiszolgálóknak
egyaránt hajlandó elküldeni a sütit. A HTTP fejlécérõl a tizenharmadik óra anyagában
többet is olvashattunk.
Ha a böngészõ úgy van beállítva, hogy tárolja a sütiket, akkor az azokban tárolt
adatok a süti lejártáig elérhetõk maradnak. Ha a felhasználó a böngészõvel olyan
oldalra jut, amely egyezik a sütiben tárolt elérési útvonallal és tartománnyal, akkor
19
elküldi a sütit a kiszolgálónak. Ehhez általában az alábbihoz hasonló fejlécelemet
állít elõ:
Cookie: zoldseg=articsoka
Bár ez a módszer nem túl bonyolult, mégis írnunk kell egy olyan függvényt, amely
elõállítja a fejléc szövegét. Ez persze nem túl rázós feladat, hiszen csak a megfelelõ
formátumú dátumot, illetve az URL formátumú névérték párt kell elõállítanunk.
Kár azonban ezzel veszõdnünk, mert létezik egy olyan PHP függvény, amely pon-
tosan ezt végzi el helyettünk.
Bár a program elsõ lefuttatásakor már beállítjuk a sütit, a $zoldseg változó ekkor
még nem jön létre. A süti csak akkor lesz hozzáférhetõ, amikor a böngészõ elküldi
azt a kiszolgálónak. Ez csak akkor következik be, ha a felhasználó újra meglátogat-
ja tartományunkat. A példában egy "zoldseg" nevû sütit hozunk létre, melynek
értéke "articsoka". A time() függvénnyel lekérdezzük a pillanatnyi idõt, majd
ebbõl 3600-at hozzáadva számítjuk ki a lejárat idejét. (A 3600 másodpercben érten-
dõ, tehát a süti 1 óra elteltével fog elavulni.) Útvonalként a "/"-t adjuk meg,
amibõl az következik, hogy sütink a webhely összes oldaláról elérhetõ lesz.
A tartományt "kiskapu.hu"-ra állítottuk, aminek következtében ennek a tarto-
mánynak mindegyik kiszolgálója jogosult a süti fogadására (a www.kiskapu.hu
tehát ugyanúgy megkapja a sütit, mint a leeloo.kiskapu.hu). Ha azt szeret-
nénk, hogy egy sütihez csak az a kiszolgáló férjen hozzá, amelyik a sütit létrehozó
programot szolgáltatta, használjuk a $SERVER_NAME környezeti változót, ahelyett,
hogy a tartomány, illetve kiszolgálónevet beépítenénk a programba. Ez a megoldás
azzal az elõnnyel is rendelkezik, hogy a programok módosítás nélkül átvihetõk egy
19
másik kiszolgálóra és ott is az elvárásoknak megfelelõen fognak futni. Végül egy
nullát is átadunk a setcookie()-nak, jelezvén, hogy a sütit nem biztonságos
kapcsolaton keresztül is el szabad küldeni. Bár az elsõ kivételével mindegyik para-
méter elhagyható, hasznos, ha minden paramétert megadunk és csak a tartomány
és biztonság adatok meghatározásától tekintünk el. Erre azért van szükség, mert bi-
zonyos böngészõk csak az útvonal megadása esetén képesek a sütik rendeltetés-
szerû használatára. Az útvonal elhagyásával a süti használatát az aktuális, illetve az
alatta elhelyezkedõ könyvtárak oldalai számára korlátozzuk.
Süti törlése
A sütik törlésének hivatalos módja az, hogy a setcookie() függvényt egyetlen
paraméterrel, mégpedig a törlendõ süti nevével hívjuk meg:
setcookie( "zoldseg" );
Ebben a megoldásban nem bízhatunk meg teljesen, mert nem minden esetben
mûködik kifogástalanul. Ezért célszerûbb, ha egy múltbeli dátummal új értéket
adunk a sütinek:
Munkamenet-azonosító sütik
Ha olyan sütit szeretnénk létrehozni, amely csak addig létezik, amíg a felhasználó
be nem zárja a böngészõt, csak annyi a teendõnk, hogy a süti élettartamát nullára
állítjuk. Amíg ki nem lépünk a böngészõbõl, az így készített sütiket a kiszolgáló
gond nélkül megkapja, ám ha bezárjuk a programot, a sütik megszûnnek,
így hiába indítjuk újra a böngészõt, már nem érjük el azokat.
Most, hogy elkészítettük a táblát, amivel dolgozhatunk, írnunk kell egy programot,
amely megnyit egy adatbázis-kapcsolatot és képes ellenõrizni a süti jelenlétét.
Ha a süti nem létezik, új sort hoz létre a táblában és feltölti az új látogató adataival.
Ennek megvalósítása látható a 19.2. példában.
19_ora.qxd 8/3/2001 6:22 PM Page 368
Tegyük fel, hogy találtunk egy megfelelõ sort, melynek azonosítója egyezik a süti érté-
kével. Ezt a sort a mysql_fetch_array() függvénnyel emelhetjük át egy PHP
tömbbe (esetünkben a $vendeg_adatok nevûbe). A program mostani futása egy ol-
dal letöltésének következménye, tehát a $vendeg_adatok["ossz_letoltes"]
változó értékét eggyel növelnünk kell, hogy rögzítsük ezt a tényt.
Most, hogy a feladaton túl vagyunk, írhatunk egy kis programot, hogy ellen-
õrizzük, az elmélet valóban mûködik-e a gyakorlatban. Elkészítjük
az allapotMegjelenites() függvényt, amely kiszámolja a lekérõ felhasználó
átlagértékeit és megjeleníti azokat a böngészõben. A valóságban persze komo-
lyabb megjelenésû, átfogóbb képet kell adnunk a látogatókról, de a lényeg megér-
téséhez ez a példa is bõven elegendõ. A függvény megvalósítását a 19.4. példában
találjuk. A korábbi példák kódjához az include() függvény alkalmazásával
férhetünk hozzá.
19_ora.qxd 8/3/2001 6:22 PM Page 373
19.1. kép
A használati statisz-
tika megjelenítése
Ha egy ûrlapot a GET eljárással küldünk el, akkor annak mezõit és azok értékeit
URL kódolásban hozzáillesztjük ahhoz a címhez (URL-hez), ahová az ûrlapot küld-
jük. Az értékek ekkor elérhetõk lesznek a kiszolgáló, illetve az általa futtatott prog-
ramok számára. Vegyünk példaként egy olyan ûrlapot, amely egy felhasznalo
és egy nev mezõt tartalmaz. Ekkor a lekérés a következõképp fog festeni:
http://php.kiskapu.hu/proba5.php?nev=
å 344343&felhasznalo=Szy+Gyorgy
19_ora.qxd 8/3/2001 6:22 PM Page 375
Minden mezõ nevét egy egyenlõségjel (=) választja el annak értékétõl; ezeket
a névérték párokat pedig ÉS jelek (&) határolják. A PHP visszafejti a jeleket,
a talált adatokat a $HTTP_GET_VARS asszociatív tömbben teszi elérhetõvé
a program számára, és emellett a mezõk nevével azonos nevû globális változókat
is létrehoz, a megfelelõ tartalommal. A felhasznalo nevû GET változóhoz így
az alábbi két módon férhetünk hozzá:
$HTTP_GET_VARS["felhasznalo"];
$felhasznalo;
print urlencode("http://www.kiskapu.hu");
// azt írja ki, hogy http%3A%2F%2Fwww.kiskapu.hu
Az URL kódolású szövegek elõállítása így nem okoz gondot, akár saját GET leké-
réseket is összerakhatunk. A következõ kódrészlet két változóból épít fel
egy lekérdezõ karakterláncot:
<?php
$erdeklodes = "sport";
$honlap = "http://www.kiskapu.hu";
$lekerdezes = "honlap=".urlencode( $honlap );
$lekerdezes .= "&erdeklodes=".urlencode( $erdeklodes );
?>
<A HREF="masiklap.php?<?print $lekerdezes ?>">Gyerünk!</A>
masiklap.php?honlap=http%3A%2F%2Fwww.kiskapu.hu&
å erdeklodes=sport
19_ora.qxd 8/3/2001 6:22 PM Page 376
A foreach segítségével sorra vesszük a tömb elemeit, úgy, hogy azok a $kulcs és
$ertek változókon keresztül legyenek elérhetõk.
A kulcsérték párokat & jellel kell elválasztanunk, így ha nem a ciklus elsõ lefutá-
sánál tartunk azaz az $lsztring változó már nem üres , ezt a karaktert is
hozzátesszük a lekérdezõ karakterlánchoz.
Ezek után már csak vissza kell adnunk az összeállított, kódolt karakterláncot.
E függvény alkalmazásával pár sornyi PHP kód is elég, hogy adatokat adhassunk át
egyes lapjaink között.
19_ora.qxd 8/3/2001 6:22 PM Page 378
Összefoglalás
Ezen az órán a weblapok közti információátadás két módjával ismerkedhettünk
meg. Segítségükkel több oldalból álló webes alkalmazások alakíthatók ki, melyek
a felhasználók igényeit is figyelembe veszik.
Kérdések és válaszok
Van e valamiféle komoly biztonságot vagy személyiségi jogokat sértõ
velejárója a sütik használatának?
A kiszolgáló csak a saját tartományán belül levõ gépek sütijeihez férhet hozzá.
Azon túl, hogy a süti a felhasználó fájlrendszerében tárolódik, azzal semmiféle
további kapcsolatba nem kerül. Lehetõség van azonban arra, hogy sütit állítsunk be
egy kép letöltésének válaszaként. Tehát ha sok webhely jelentet meg egy külsõ
reklámszolgáltató vagy számláló programot oldalain, ezek szolgáltatója képes lehet
a látogatók követésére különbözõ webhelyek között is.
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Milyen függvénnyel vehetjük rá a weboldalunkat letöltõ felhasználó böngé-
szõjét, hogy létrehozzon egy sütit és tárolja azt?
Feladatok
1. Tegyük lehetõvé, hogy a webhelyünket meglátogató felhasználó beállíthassa
a weboldalak háttérszínét, valamint hogy megadhassa, milyen néven
köszöntsék a webhely oldalai. Oldjuk meg sütikkel, hogy minden oldal
köszönjön, illetve a megfelelõ háttérszínnel jelenjen meg.
19
19_ora.qxd 8/3/2001 6:22 PM Page 380
20_ora.qxd 8/3/2001 6:22 PM Page 381
20. ÓRA
Állapotok tárolása
munkamenet-függvényekkel
Az elõzõ órában áttekintettük, hogy hogyan lehet süti vagy lekérdezõ karaktersoro-
zat használatával menteni az oldalak állapotát. A PHP 4 ezeken kívül további lehetõ-
ségeket is nyújt, különbözõ függvényei vannak a felhasználó állapotának mentésére
is. Ezen függvények használata nagyon hasonló az elõzõ órában tanultakhoz, de
mivel közvetlenül a nyelvbe vannak építve, az állapot mentése egyszerû függvény-
hívásokkal végezhetõ el.
session.auto_start = 0
HTTP/1.1 200 OK
Date: Sun, 07 Jan 2001 13:50:36 GMT
Server: Apache/1.3.9 (Unix) PHP/4.0.3
Set-cookie: PHPSESSID=2638864e9216fee10fcb8a61db382909; path=/
Connection: close
Content-Type: text/html
Munkamenet-változók
A munkamenet-azonosító hozzárendelése a felhasználóhoz csak az elsõ lépés.
Egy munkamenet során tetszõleges számú globális változót vezethetünk be,
amelyeket késõbb bármelyik, a munkameneteket támogató oldalunkról elérhetünk.
A 20.2. példában látható kódnak nincs túl sok értelme, amíg a felhasználó be nem
tölt egy új oldalt. A 20.3. példában egy olyan PHP program látható, amely a 20.2.
példában bejegyzett változókat használja.
20_ora.qxd 8/3/2001 6:22 PM Page 385
A 20.3. program eredménye a 20.1. ábrán látható. Látjuk, hogy az oldalról hozzáfé- 20
rünk a másik programban bejegyzett $termek1 és $termek2 változókhoz.
20.1. ábra
Bejegyzett változók
használata
print session_save_path();
sess_2638864e9216fee10fcb8a61db382909
sess_76cae8ac1231b11afa2c69935c11dd95
sess_bb50771a769c605ab77424d59c784ea0
Amikor megnyitjuk azt a fájlt, melynek neve a 20.1. példában visszaadott munka-
menet-azonosítót tartalmazza, láthatjuk, hogyan tárolódnak a bejegyzett változók:
A kód végén megadunk egy hivatkozást, ahol bemutatjuk, hogy valóban hozzáfé-
rünk a bejegyzett tömbhöz. Ez a kód a 20.5. példában található.
session_start();
session_destroy();
Amikor olyan oldalt töltünk be, amely egy munkamenetet vár, az már nem látja
a korábban törölt munkamenetet, ezért létre kell hoznia egy újat. Minden koráb-
ban bejegyzett változó elvész.
session_start();
session_register( proba );
$proba = 5;
session_unset();
session_destroy();
print $proba; // nem ír ki semmit. a $proba változó
å már nem létezik.
session_start();
print session_encode()."<br>";
// minta eredmény: termekek|a:2:{i:0;s:8:
å "HAL 2000";i:1;s:8:"Targonca";}
Látható, hogy a függvény tárolási alakjukban adja vissza a bejegyzett változókat, így
ellenõrizhetjük, hogy a változó valóban be lett-e jegyezve és értéke megfelelõ-e.
A session_encode() függvény használatával bejegyzett változókat tartalmazó
adatbázisokat is készíthetünk.
20_ora.qxd 8/3/2001 6:22 PM Page 391
session_start();
session_unset(); // nem szabad, hogy létezzenek
å munkamenet-változók
session_decode( "termekek|a:2:{i:0;s:8:\HAL 2000\";
å i:1;s:8:\"Targonca\";}" );
foreach ( $termekek as $egytermek )
{
print "$egytermek<br>\n";
}
// Kimenet:
// HAL 2000
// Targonca
if ( session_is_registered ( "termekek" ) )
print "A 'termekek' változó bejegyzett!";
Ez akkor lehet hasznos, ha biztosak akarunk lenni a változó forrásában, azaz, hogy
a változó tényleg a munkamenet bejegyzett változója vagy csak egy GET kérelem
eredményeként kaptuk.
20_ora.qxd 8/3/2001 6:22 PM Page 392
Összefoglalás
Ebben és az elõzõ órában áttekintettük, hogyan menthetjük az állapotokat
egy állapot nélküli protokollban. Különféle módszereket alkalmaztunk: sütiket és
lekérdezõ karakterláncokat használtunk, néha ezeket fájlokkal és adatbázisokkal
ötvöztük. Mindegyik megközelítési módnak megvannak a maga elõnyei és
hátrányai.
A süti nem igazán megbízható és nem tárolhat sok információt. Ezzel szemben
hosszú ideig fennmaradhat.
A lekérdezõ karakterlánc a süti ellentéte. Elég csúnyán néz ki, de viszonylag nagy
mennyiségû információt hordoz magában. Használatáról a körülmények mérlege-
lése után kell dönteni.
Kérdések és válaszok
Van valamilyen veszélye a munkamenet-függvények használatának,
amirõl még nem tudunk?
A munkamenet-függvények alapvetõen megbízhatók. De emlékezzünk rá, hogy
a sütik használata nem lehetséges több tartományon keresztül. Ezért, ha több tarto-
mánynevet használunk ugyanazon a kiszolgálón (elektronikus kereskedelemi alkal-
mazásoknál ez gyakori), tiltsuk le a sütik használatát a session.use_cookies 0-
ra állításával a php.ini fájlban.
20_ora.qxd 8/3/2001 6:22 PM Page 393
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Melyik függvényt használjuk egy munkamenet elindítására?
Feladatok
1. Az elõzõ óra Feladatok részében készítettünk egy programot, amely sütit
vagy lekérdezõ karakterláncot használ, hogy oldalról oldalra vigye tovább
a felhasználó válaszait. Ezután a környezet minden oldala a beállított háttér-
színnel indult és név szerint üdvözölte a felhasználót. Készítsük el ezt a prog-
ramot a PHP 4 munkamenet-függvényeivel.
21. ÓRA
Munka kiszolgálói környezetben
A korábbi fejezetekben áttekintettük, hogyan társaloghatunk távoli számítógépek-
kel és hogyan vehetünk át adatokat a felhasználótól. Ebben a fejezetben ismét ki-
tekintünk, olyan eljárásokat tanulunk meg, amelyek külsõ programok saját gépün-
kön való futtatására használhatók. A fejezet példái Linux operációs rendszerre
készültek, de a legtöbb alapelv felhasználható Microsoft Windows rendszerben is.
A popen() használata akkor javasolt, amikor egy folyamat kimenetét sorról sorra
szeretnénk elemezni. A 21.1-es példában a GNU who parancs kimenetét elemezzük,
és a kapott felhasználóneveket mailto hivatkozásokban használjuk fel.
21.1. ábra
A who UNIX parancs
kimenetének olvasása
21
21
Parancsok végrehajtása az exec() függvénnyel
Az exec() egyike azoknak a függvényeknek, amelyekkel parancsokat adhatunk ki
a héjnak. A függvény paraméterében meg kell adni a futtatandó program elérési
útját. Ezen kívül megadható még egy tömb, mely a parancs kimenetének sorait fogja
tartalmazni és egy változó, amelybõl a parancs visszatérési értéke tudható meg.
Ha az exec() függvénynek az 'ls al .' parancsot adjuk meg, akkor az aktu-
ális könyvtár tartalmát jeleníti meg. Ez látható a 21.3. példában.
21.2. ábra
A könyvtárlista betöl-
tése a böngészõbe
az exec() függvény
segítségével
21_ora.qxd 8/3/2001 6:22 PM Page 401
<?php
print "<pre>";
system( "man man | col -b", $vissza );
print "</pre>";
?>
A PRE HTML elemet azért adtuk meg, hogy a böngészõ megtartsa a kimenet
eredeti formátumát. A system() függvényt használtuk, hogy meghívjuk a man
parancsot, ennek kimenetét hozzákapcsoltuk a col parancshoz, amely ASCII-ként
újraformázza a megjelenõ szöveget. A visszatérési értéket a $vissza változóba
mentjük. A system() közvetlenül a böngészõbe írja a kimenetet.
print "<pre>";
print `man man | col -b`;
print "</pre>";
21.3. ábra
A man program
meghívása
21_ora.qxd 8/3/2001 6:22 PM Page 403
Vagyis meg kell jelenítenie az xxx parancshoz tartozó súgóoldalt, ami természe-
tesen nem létezik. Ebben az esetben a col parancs bemenete a teljes könyvtárlista
lesz. Ezzel a támadó kiírathatja a rendszer bármelyik olvasható könyvtárának tartal-
mát. A következõ utasítással például a /etc/passwd tartalmát kapja meg:
<img src="21.6.program.php?kep=<?php
å print urlencode("/utvonal/kep.gif") ?>">
Írjunk egy Perl CGI programot! Ne aggódjunk, ha nem ismerjük a Perlt. Ez a prog-
ram egyszerûen egy HTTP fejlécet ír ki és minden rendelkezésre álló környezeti
változót felsorol:
#!/usr/bin/perl -w
print "Content-type: text/html\n\n";
foreach ( keys %ENV ){
print "$_: $ENV{$_}<br>\n";
}
<?php
virtual("/cgi-bin/proba.pl");
?>
Összefoglalás
Ebben a fejezetben áttekintettük, hogyan mûködhetünk együtt a héjjal és rajta
keresztül a külsõ alkalmazásokkal. A PHP sok mindenre használható, de lehet,
hogy külsõ programok használatával az adott probléma elegánsabb megoldá-
sához jutunk.
Kérdések és válaszok
Sokat emlegettük a biztonságot ebben a fejezetben. Honnan tudhatunk
meg többet a szükséges biztonsági óvintézkedésekrõl?
A legbõvebb számítógépes biztonsággal foglalkozó forrás Lincoln Stein (a híres
Perl modul, a CGI.pm szerzõje) által fenntartott FAQ. Megtalálható
a http://www.w3.org/Security/Faq/ címen. Érdemes a PHP kézikönyv
biztonságról szóló részét is tanulmányozni.
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
21
Kvíz
1. Melyik függvényt használjuk alkalmazások összekapcsolására?
Feladatok
1. Írjunk programot, amely a UNIX ps parancsának segítségével megjeleníti
a böngészõben a futó folyamatokat! (Megjegyezzük, hogy nem biztonságos,
ha a felhasználók futtathatják a programot!).
22. ÓRA
Hibakeresés
E könyv írásakor a PHP 4 semmilyen hibakeresõ eszközt nem tartalmazott.
A fejlesztõk ígéretet tettek hibakeresõ szolgáltatások beépítésére, például hogy
a verem tartalmát nyomon követhessük, ezért elképzelhetõ, hogy mire e könyv az
Olvasó kezébe kerül, a legfrissebb kiadás már tartalmaz valamilyen fejlettebb hiba-
keresõ eszközt. Ebben a fejezetben a kódban rejlõ hibák felderítésének néhány
egyszerû módját mutatjuk be.
A phpinfo()
A phpinfo() függvény az egyik leghasznosabb hibakeresõ eszköz: részletes
információkkal szolgál magáról a PHP-rõl, a kiszolgálói környezetrõl és a futó
program változóiról. A függvénynek nem kell átadnunk semmilyen paramétert és
csak egy logikai értéket ad vissza, viszont egy csinos HTML oldalt küld a böngé-
szõnek. A phpinfo() kimenetét a 22.1. ábrán láthatjuk.
22.1. ábra
PHP információk
megjelenítése
track_vars On
register_globals Off
22_ora.qxd 8/3/2001 6:22 PM Page 411
Hibakeresés 411
session.cookie_lifetime 0
session.use_cookies 0
Hibakeresés 413
22.2. ábra
Globális változók
elérése
22.3. ábra
Színkiemelés
használata
Hibakeresés 415
Egy másik gyakori probléma, hogy elég nehéz nyomon követni egy félig nyitott
idézõjel-párt. Mivel a PHP az idézõjel utáni szöveget karakterláncként értelmezi,
gyakran rossz helyen jelzi a hibát. Az idézõjelben lévõ karakterláncok szintén más
színnel jelöltek, így ez a típusú hiba nagyon könnyen észrevehetõ.
PHP hibaüzenetek 22
Miközben e könyv segítségével elsajátítottuk a PHP programozás alapjait, bizonyára
elõfordult, hogy hibaüzeneteket kaptunk a várt eredmény helyett. Például elfelejtet-
tünk zárójelbe tenni egy kifejezést vagy elgépeltük egy függvény nevét. A hibaüze-
netek nagyon fontosak a hibakeresés során. Állítsuk a php.ini fájlban
a display_errors bejegyzést "On"-ra, ezzel biztosíthatjuk, hogy a PHP elküldje
a hibaüzeneteket a böngészõnek. Ne feledjük, hogy a phpinfo() függvény segít-
ségével megnézhetjük, hogy be van-e kapcsolva ez a lehetõség.
error_reporting = E_ERROR|E_WARNING
22_ora.qxd 8/3/2001 6:22 PM Page 417
Hibakeresés 417
Mint látható, a $flag változó értékét akarjuk vizsgálni, de elgépeltük. Nincs végze-
tes hiba a programban, így minden további nélkül lefut és
az E_ERROR|E_WARNING|E_PARSE hibakezelési beállítás mellett még csak üze-
netet sem küld a böngészõnek. A kód bekerül a programba és a lehetõ legrosszabb
pillanatban mûködésbe lép. Ha azonban az error_reporting() függvénynek
az E_ERROR|E_WARNING|E_PARSE|E_NOTICE értéket adnánk át (ez magában
foglalja a megjegyzések elküldését is), a program a következõ kimenetet küldené:
22_ora.qxd 8/3/2001 6:22 PM Page 418
Azaz:
Itt azt használjuk ki, hogy ha egy nem meghatározott változó értékét íratjuk ki,
akkor annak hasonló a hatása ahhoz, mintha egy üres karakterláncot jelenítenénk
meg (tulajdonképpen semmilyen hatása nincs). A "felhasznalo" mezõ
egy elõzõleg elküldött értéket vagy semmit sem tartalmaz. Ha a megjegyzések
elküldését is engedélyeztük, hibaüzenetet kapunk.
Hibakeresés 419
error_log = /home/httpd/logs/php_errors
/home/httpd/htdocs/proba5.php, 4. sor:
å Nem lehet megnyitni a következõ fájlt: ./fontos.txt
Ha 3-as típusú hibaüzenetet hozunk létre, egy harmadik paraméterben azt is meg
kell adnunk az error_log() függvénynek, hogy hová kerüljön a hibaüzenet.
if ( ! file_exists( "kritikus.txt" ) )
or error_log( "Ó, nem! kritikus.txt-nek vége van!",
å 1, "veszeset@kritikus.hu" );
A hibaüzenet elfogása
Ha hibaüzeneteket írunk egy fájlba vagy elektronikus levélben küldjük el azokat,
hasznos lehet, ha hozzáférünk a PHP által elõállított hibaüzenethez.
Ehhez a php.ini fájlban a track_errors bejegyzést "On"-ra kell állítanunk
ennek hatására a legutolsó PHP hibaüzenet bekerül a $php_errormsg változóba
(hasonlóan a Perl $! változójához).
Hibakeresés 421
Kézi hibakeresés
Mindig nagyon nehéz azonban az olyan hibák kijavítása, amelyek nem váltanak ki
hibaüzenetet.
22.4. ábra
A debug() függvény
használata
22_ora.qxd 8/3/2001 6:22 PM Page 423
Hibakeresés 423
Gyakori hibák
Mindannyian követünk el hibákat, különösen akkor, ha vészesen közeledik
a leadási határidõ. Vannak olyan csapdák, amelyekbe elõbb-utóbb minden progra-
mozó beleesik.
$valtozo=0;
while ( $valtozo < 42 );
{
print "$valtozo<BR>";
$valtozo++;
}
$ertek = 1;
while ( $ertek != 50 )
{
print $ertek;
$ertek+=2;
}
if ( $proba = 4 )
{
print "<P>A \$proba értéke 4</P>\n";
}
22_ora.qxd 8/3/2001 6:22 PM Page 424
Ha idézõjelet akarunk kiíratni, jeleznünk kell az értelmezõnek, hogy itt nem külön-
leges karakterként kell kezelnie. Az elõbbi kódrészlet a következõképpen fest
helyesen:
Hibakeresés 425
Összefoglalás
A fejlesztés talán egyik leghálátlanabb része a hibakeresés. A megfelelõ módsze-
rekkel azonban megkönnyíthetjük az életünket.
Kérdések és válaszok
Létezik módszer, amellyel csökkenthetjük a kódba kerülõ hibákat?
Legyünk szemfülesek! Tulajdonképpen szinte lehetetlen egy olyan nagyobb léleg-
zetû programot létrehozni, amely elsõre tökéletesen mûködik. Használjunk modu-
láris tervezést, hogy gyorsan elkülöníthessük a hibát tartalmazó kódrészletet. Olyan
gyakran ellenõrizzük a kódot, amilyen gyakran csak lehetséges. Rossz megközelí-
tés, ha megírjuk a programot, elindítjuk, azután várjuk, mi történik. Oldjunk meg
egy részfeladatot (lehetõleg függvények formájában), majd próbáljuk ki az elké-
szült kódot. Ha tökéletesen mûködik, mehetünk a következõ részfeladatra. Próbál-
junk bolondbiztos kódot készíteni és ellenõrizzük mûködését szélsõséges körül-
mények között. Ha az egyik leglényegesebb lépés például az adatok kiírása egy
megadott fájlba, nézzük meg, mi történik, ha a fájl hiányzik.
Mûhely 22
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Melyik függvénnyel kaphatunk hasznos információkat a PHP-rõl és a rend-
szerünkrõl?
Feladatok
1. Vizsgáljuk meg eddig elkészült programjaink kódját és felépítését az ebben
az órában tanult módszerek segítségével.
23_ora.qxd 8/3/2001 6:23 PM Page 427
IV. RÉSZ
Összefoglaló példa
23. óra Teljes példa (elsõ rész)
24. óra Teljes példa (második rész)
23_ora.qxd 8/3/2001 6:23 PM Page 428
23_ora.qxd 8/3/2001 6:23 PM Page 429
23. ÓRA
Teljes példa (elsõ rész)
Ha figyelmesen követtük az egyes órák anyagát, jó alapokkal rendelkezünk a PHP
programozáshoz. Ebben és a következõ órában egy teljes, mûködõ programot
készítünk, amely az elõzõ órákban tárgyalt eljárásokból építkezik.
Az oldalak felépítése
Mielõtt akár egy sor kódot is írnánk, el kell döntenünk, hogyan fog mûködni
programunk. Milyen módon fogják elérni a felhasználók a rendszer különbözõ
elemeit? Milyen oldalakra van szükségünk?
23.1. ábra
Az alkalmazás
felépítése
23_ora.qxd 8/3/2001 6:23 PM Page 431
Az adatbázis kialakítása
Az alkalmazás adatainak tárolásához létre kell hoznunk a szervezo adatbázist és
ebben négy táblát: klubok, esemenyek, teruletek, tipusok. Nyilvánvaló,
hogy a klubok és rendezvények adatait külön táblákban kell tárolnunk, hiszen
egy klubhoz több rendezvény is tartozhat. A területek és típusok számára kiala-
kított táblák jelentõsen megkönnyítik a listázáshoz és adatbevitelhez szükséges
lenyíló menük kialakítását. A táblákat SQL parancsokkal hozzuk létre, kézi úton.
A klubok tábla a következõképpen hozható létre:
23
azonosito INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
klubnev VARCHAR(50),
tipus CHAR(3),
terulet CHAR(3),
email VARCHAR(50),
ismerteto BLOB,
nev VARCHAR(8),
jelszo VARCHAR(8)
);
23_ora.qxd 8/3/2001 6:23 PM Page 432
A tagok számára nem adunk lehetõséget ezen táblák módosítására, inkább elõre
meghatározott csoportokat alakítunk ki, melyeket INSERT SQL parancsokkal
adunk a táblákhoz. A tagok ezekbõl a listákból választhatnak majd.
Tervezési döntésünk
Az elõzõ bekezdésekben már láttuk, milyen szerkezetû alkalmazást készítünk.
Úgy döntöttünk, hogy a különbözõ szolgáltatásokhoz különbözõ PHP programokat
készítünk, ahelyett, hogy egyetlen hatalmas programot építenénk fel, amely a körül-
ményeknek megfelelõen más-más oldalakat szolgáltat. Ennek a döntésnek termé-
szetesen vannak elõnyei és hátrányai is.
Ha egy ilyen dinamikus környezetet több oldalból építünk fel, a kódok ismétlésének
hibájába eshetünk és a program növekedésével megnehezíthetjük a fejlesztõk dolgát.
Másrészt viszont a befejezett prototípust átadhatjuk grafikusainknak, akik majdnem
úgy kezelhetik azt, mintha pusztán HTML kódot tartalmazna.
csatlakozas.php és adatbazis.inc
A csatlakozas.php tartalmazza azt az ûrlapot, amelyen keresztül az új tagok
egy név és jelszó segítségével bejegyeztethetik klubjukat a rendszerbe. Ahhoz, hogy
felvehessük az adatokat és kiszûrhessük az ismétlõdéseket, elõször meg kell
nyitnunk egy kapcsolatot az adatbázis felé. Ez az ilyen alkalmazásoknak annyira
jellemzõ eleme, hogy célszerû külön függvényt készíteni erre a célra, melyet jelen
esetben egy külsõ állományban fogunk tárolni. Ezt a külsõ fájlt késõbb minden
oldalon az include() nyelvi elemmel illesztjük a kódba. Tulajdonképpen minden
adatbázissal kapcsolatos függvényt ebben tárolunk majd, ezért az adatbazis.inc
nevet kapja, szerepe és a beillesztés módja után. Ezzel a fájllal a további PHP olda-
lakat mindennemû SQL parancstól mentesítjük.
Emlékezzünk rá, hogy minden PHP kód, amit ezen külsõ fájlokba írunk, PHP blokk
kezdõ (<?php) és záró (?>) elemek között kell, hogy legyen. Értelmetlen bonyolí-
tásnak tûnhet, hogy a különbözõ szolgáltatásokat külsõ állományokba helyezzük,
de ez rengeteg kódismétléstõl kímél majd meg bennünket, amikor oldalainkat elké-
szítjük. Most már készen állunk a csatlakozas.php oldal megírására.
13:
mezõt!<br>\n";
23
14: if ( $urlap["jelszo"] != $urlap["jelszo2"] )
15: $uzenet .= "A jelszavak nem
egyeznek!<br>\n";
16:
23_ora.qxd 8/3/2001 6:23 PM Page 436
számos más oldalon találkozni fogunk. Az $uzenet célja egyrészt, hogy tartal-
mazza a hibaüzenetet, amit késõbb kiírhatunk a böngészõ számára, másrészt hasz-
nálhatjuk feltételes kifejezésekben, hogy ellenõrizzük, volt-e hibaüzenet vagy sem.
Ha a változó üres marad, feltételezhetjük, hogy minden ellenõrzés sikeresen
végrehajtódott.
Egyelõre ugorjunk a HTML rész tárgyalására. A body HTML elemen belül elõször
egy újabb külsõ fájlt illesztünk be, amely a különbözõ oldalakra mutató hivatkozá-
sokat tartalmazza. Célszerû már a kezdetektõl beilleszteni a navigációs sávot, mivel
ez megkönnyíti az alkalmazás ellenõrzését, ahogy folyamatosan fejlesztjük azt.
A navigációs elemeket a kozosnav.inc nevû állományban helyezzük el.
Egyelõre ez a fájl csak a látogatók számára is elérhetõ oldalakra mutató hivatko-
zásokat tartalmazza.
A HTML ûrlap elemei között három látható mezõt hoztunk létre, az urlap[nev],
urlap[jelszo] és urlap[jelszo2] mezõket. Azért használjuk ezeket
az elsõre esetleg furcsának látszó elnevezéseket, mert a PHP az így megadott
nevekkel érkezõ értékeket egy asszociatív tömbbe rendezi, amit $urlap néven
érhetünk majd el. Ez megóv bennünket attól, hogy a globális változók környezetét
beszennyezzük, azaz feleslegesen sok globális változót hozzunk létre. Program-
jainkban így minden munkamenet-érték a $munkamenet asszociatív tömbben,
az ûrlapértékek pedig az $urlap asszociatív tömbben érhetõk el. Ez megvéd
bennünket a változók ütközésétõl. Célszerû a lehetõ legkevesebbre csökkenteni
a globális változók számát egy ilyen méretû programban, hogy megelõzzük
a kavarodást. A továbbiakban minden ûrlapot tartalmazó oldalon az $urlap
tömbbel fogunk találkozni.
Most, hogy megnéztük a HTML ûrlapot, rátérhetünk arra a kódra, amely a bemenõ
adatok ellenõrzését végzi. Elõször meg kell bizonyosodnunk róla, hogy a leendõ
23
tag valóban kitöltötte-e az összes mezõt és hogy egyik mezõ hossza sem haladja
meg a nyolc karaktert. Ezután meghívjuk az új sorLekeres() függvényt.
Ez azon függvények egyike, amelyek az adatbazis.inc fájlban találhatók.
Elsõ paramétere egy táblanév, a második egy mezõnév, a harmadik egy érték.
Ezen adatok alapján a függvény egy illeszkedõ sort keres az adatbázisban,
visszaadva azt egy tömbben.
23_ora.qxd 8/3/2001 6:23 PM Page 440
A függvény egy név és egy jelszó paramétert vár, majd ezeket új sorként felveszi
a klubok táblájába. A függvény a mysql_insert_id()-t használja, hogy
megkapja a felvett új tag azonosítóját.
23_ora.qxd 8/3/2001 6:23 PM Page 441
23.2. ábra
A csatlakozas.php
kimenete
23
23_ora.qxd 8/3/2001 6:23 PM Page 442
klubfrissites.php
Ez az oldal kettõs célt szolgál. Egyrészt az új tagoknak itt kell megadniuk a klub
részletes adatait, a bejegyzett tagok pedig itt módosíthatják ezeket.
munkamenet%5Bbelepett%5D=1&munkamenet%5Bazonosito%5D=1
így átvéve az 1-es azonosítóval rendelkezõ tag fölött az irányítást, a PHP ugyanis
ezt a $munkamenet tömbbé alakítja, amely egy felületesebb ellenõrzésen túljut-
hatna. A rosszindulatú látogató most is alkalmazhat egy hasonló trükköt, hogy
belépést nyerjen, de mivel az adatbázisban lévõ névvel és jelszóval történõ egye-
zést vizsgáljuk, a hamisított $munkamenet változónak helyes tartalommal kell
rendelkeznie, így pedig felesleges a csalás.
23
egy e-mail címet és egy ismertetõt vár a klubok tábla számára.
23_ora.qxd 8/3/2001 6:23 PM Page 448
23.3. ábra
A klubfrissites.php
kimenete
23_ora.qxd 8/3/2001 6:23 PM Page 449
tagmenu.php
A tagmenu.php a tagok területének központja. Alapvetõen hivatkozások listájából
áll, de a tagok számára fontos hírek és ajánlatok is helyet foglalhatnak az oldalon.
23
25: </body>
26: </html>
belepes.php
Mielõtt továbblépünk a rendezvényeket kezelõ oldalakra, el kell készítenünk
a belepes.php programot. Ez az oldal ad lehetõséget a bejegyzett tagoknak,
hogy a késõbbiekben belépjenek a rendszerbe.
48:
value="belepes">
<input type="hidden" name="<?php
23
print session_name() ?>"
49: value="<?php print session_id() ?>">
50: </p><p>
51: Tagsági név: <br>
52: <input type="text" name="urlap[nev]"
53: value="<?php print $urlap["nev"] ?>">
23_ora.qxd 8/3/2001 6:23 PM Page 452
esemenyfrissites.php
Most, hogy a tagok már képesek csatlakozni és belépni a rendszerbe, valamint
módosítani is tudják az adataikat, lehetõséget kell adnunk a rendezvények bevitelére
és módosítására. A teljes esemenyfrissites.php oldal a 23.17. programban
látható.
A HTML ûrlapon az egyetlen említésre méltó kód a dátum és idõ számára készített 23
lenyíló menüket állítja elõ. Ezeket a menüket elég egyszerûen beépíthettük volna
a PHP kódba, de szükségünk van arra, hogy alapbeállításban az aktuális idõt,
a tag által korábban választott idõt, vagy az esemenyek táblában tárolt idõt jelez-
zék. Az alapbeállításban kiválasztandó értéket már elhelyeztük az $edatum válto-
zóban. Ezt a program elején az aktuális idõre állítottuk be. Ha beérkezõ adatokat
észlelünk, annak megfelelõen állítjuk be ezt az értéket. Egyéb esetben, ha már
meglévõ eseményt módosítunk, az esemenyek tábla edatum mezõjének értékét
adjuk az $edatum változónak.
23_ora.qxd 8/3/2001 6:23 PM Page 460
Minden függvény egy idõbélyeget vár és HTML OPTION elemek listáját írja ki.
A getDate() PHP függvényt használják arra, hogy az idõbélyeg megfelelõ
23
elemének indexét megállapítsák (év, hónap, hónap napja, óra, perc). Ezután
a kapott számot összehasonlítják az alkalmazott tartomány értékeivel (a tartomány
a hónap napjainál 1-tõl 31-ig, a perceknél 0-tól 59-ig terjed). Ha egyezést észlel-
nek, a SELECTED jelzõt adják az OPTION elemhez, így választják ki a megfelelõ
sort.
23.4. ábra
Az esemenyfrissites.php
kimenete
esemenylista.php
Végül biztosítanunk kell a tagoknak egy oldalt, ahol minden általuk bevitt ese-
ményt végigtekinthetnek. Ennek az oldalnak lehetõséget kell adnia arra is, hogy
a tagok az eseményeket szerkeszthessék vagy törölhessenek egyet.
Az esemenylista.php az eddigiek ismeretében egyszerû program.
40: }
megtörtént!<br>";
23
41:
42: ?>
43: <html>
44: <head>
45: <title>Események listája</title>
46: </head>
23_ora.qxd 8/3/2001 6:23 PM Page 464
A date() PHP függvénynek átadva minden tömb edatum elemét, formázott dátu-
mokat írunk ki. A dátum mellett minden esemény számára egy hivatkozást hozunk
létre, felhasználva az esemény azonosítóját és az enev értéket. Az átadandó
eazonosito változó mellett szerepeltetjük a SID állandót, így biztosítva, hogy
a munkamenet érvényes marad az új oldalon is. A hivatkozás
az esemenyfrissites.php oldalra mutat, amely így meg tudja jeleníteni az ese-
mény adatait a szerkesztés számára. Végül minden rendezvény sorában egy erre
az oldalra visszamutató hivatkozást is szerepeltetünk. Ehhez az eazonosito mellett
egy esemenyTorles értékû mitkelltenni paramétert is meghatározunk.
Ez az adott esemény törlésére szolgál majd, ezért egy JavaScript eseménykezelõt is
adunk a hivatkozáshoz, hogy ne lehessen véletlenül törölni egy rendezvényt sem.
23
23_ora.qxd 8/3/2001 6:23 PM Page 466
23.5. ábra
Az esemenylista.php
kimenete
Összefoglalás
Az óra végére elkészültünk a teljesen mûködõ, tagok számára készült környezettel
a rendezvényeket nyilvántartó rendszerhez. Lehetõséget teremtettünk grafikusa-
inknak az oldalak jó kialakítására, azzal, hogy a lehetõ legtöbb kódot külsõ állo-
mányokban helyeztük el. Gyakran használtuk a header() függvényt, hogy
új oldalra irányítsuk a tagot, ha adatokat várunk tõle. A belépési információk táro-
lásához munkamenet-kezelõ függvényeket, a tagok azonosításához adatbázis-
lekérdezéseket használtunk minden oldalon.
Kérdések és válaszok
A több oldalból álló alkalmazások megtervezése és karbantartása bonyo-
lultnak tûnik. Van valami titok emögött?
A példaalkalmazás elkészítése során majdnem minden oldalon egyszerû mintát
követtünk. Ahogy alkalmazásaink nagyobbá válnak, a teljes környezetrõl egyetlen
programként kell gondolkodnunk. A különálló oldalak csak a látogató csatlakozá-
si pontjai az egész alkalmazáshoz. Tartsuk az összes egynél több oldalon ismétlõ-
dõ kódot külön állományban!
23_ora.qxd 8/3/2001 6:23 PM Page 467
Ha esetleg úgy döntünk, hogy egyetlen központi programot készítünk a teljes alkal-
mazás számára, egy egyszerû, alapvetõ HTML elemeket tartalmazó oldalt kell készí-
tenünk. Minden más tartalom dinamikusan áll majd elõ a program futása során.
Szükségünk lesz egy mitkelltenni típusú változóra, amely mindig a megfelelõ
szolgáltatást választja ki a teljes alkalmazásból. Ez sokkal formásabbá teheti a kódot
és segít elkerülni a nem túl elegáns Location fejléctrükköt. Másrészt ez azzal jár,
hogy sokkal több HTML-t kell beépítenünk a PHP kódok közé.
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Melyik PHP függvényt használjuk arra, hogy MySQL adatbázishoz
csatlakozzunk?
Feladatok
1. Tekintsünk végig az órában tárgyalt forráskódokon. Találunk olyan megoldá- 23
sokat, amelyeket saját programjainkban is tudunk majd hasznosítani?
23_ora.qxd 8/3/2001 6:23 PM Page 468
24_ora.qxd 8/3/2001 6:23 PM Page 469
24. ÓRA
Teljes példa (második rész)
Az elõzõ órában felépítettük a klubok számára a bejegyzõ és karbantartó felületet,
amivel új klubok és rendezvények kerülhetnek a rendszerbe. Most az átlagos
felhasználók számára elérhetõ programokat kell elkészítenünk, melyek lehetõvé
teszik a listák böngészését.
Ebben az órában négy oldalt készítünk el, amelyek lehetõséget adnak a felhaszná-
lónak, hogy kiírassa egy adott terület vagy téma rendezvényeit, bármilyen idõpont
szerinti szûréssel párosítva.
esemenyekinfo.php
Az esemenyekinfo.php oldal lehetõséget ad a rendszerben lévõ rendezvények
böngészésére. Bizonyos szempontból hasonlít az esemenylista.php oldalra,
amit az elõzõ órában tárgyaltunk, de nagyobb rugalmasságot és több információt
nyújt a felhasználónak.
session_start();
session_register( "munkamenet" );
A függvény lényegében egy SQL kérést állít össze a paraméterek alapján. A lekérés
alapvetõen összekapcsolja az adatbázisban lévõ táblákat, ezzel biztosítva, hogy
a klubnév, területnév és típusnév mezõk is elérhetõk legyenek az eredménytáb-
lában.
Talán feltûnt az elõzõ órában, hogy egy html() nevû függvényt használtunk arra,
hogy szöveges adatokat írjunk ki a böngészõbe. Az esemenyLista() függvény-
ben, ahogy az események információin végiglépkedünk, ismét a html() függ-
vényt hívjuk meg. Ez az általunk írt függvény a kozosfv.inc állományban talál-
ható. Egy karakterláncot vár és annak böngészõbe íráshoz alkalmassá tett,
átalakított változatával tér vissza. A különleges karakterek HTML elemekké alakul-
nak, az újsor karakterek például <br>-é.
Látható, hogy ez valójában nem egy, hanem két függvény. A html() egy karak-
terláncot vagy egy tömböt vár paraméterül. Ha tömböt kap, végiglépked rajta,
átalakítva minden elemet, egyéb esetben magát a kapott karakterláncot alakítja át.
A tényleges átalakítás egy másik függvényben, a htmlszoveg()-ben valósul
meg, amely két beépített függvényt alkalmaz a kapott karakterláncra.
A htmlspecialchars() minden karaktert, ami nem jelenne meg helyesen
a HTML kódban, a hozzá tartozó HTML elemre cserél. Az nl2br() minden újsor
karaktert <br> sortöréssel helyettesít.
24.1. ábra
Az esemenyekinfo.php
kimenete
24
24_ora.qxd 8/3/2001 6:23 PM Page 478
klubokinfo.php
A felhasználó jogos igénnyel nem csak rendezvények, hanem klubok szerint is
ki szeretné íratni az adatbázis adatait, típus vagy terület szerint szûkítve azokat.
A klubokinfo.php oldal ezt az igényt elégíti ki.
klubinfo.php
A klubinfo.php oldal lehetõséget ad egyetlen klub minden adatának megte-
kintésére. Hivatkozások segítségével juthat ide a felhasználó, akár
az esemenyekinfo.php, az esemenyinfo.php vagy a klubokinfo.php
oldalakról is. Az oldalt az eddig megismert megoldások és függvények segítsé-
gével építhetjük fel, amint az alábbi kód mutatja.
24
10: $klub["email"] = "<A HREF=\"mailto:$klub[email]\
">".$klub["email"]."</A>";
24_ora.qxd 8/3/2001 6:23 PM Page 482
A program egy $azonosito paramétert vár, amely egy klub azonosítószámát kell,
hogy tartalmazza. Ha az oldal nem kapott ilyen paramétert, a felhasználót
a klubokinfo.php oldalra küldjük. A klub adatainak kiderítésére egy új
adatbazis.inc függvényt, a klubLekeres()-t alkalmazzuk. Ez a függvény
egy klubazonosítót vár és egy tömböt ad vissza:
24.2. ábra
A klubinfo.php kime-
nete
esemenyinfo.php
Az esemenyinfo.php az utolsó oldal, amit az alkalmazáshoz el kell készíte-
nünk. Erre az oldalra bármely eseményinformációkat adó lapról el lehet jutni
egy hivatkozás segítségével. Az oldal minden információt megad
az $eazonosito segítségével kiválasztott eseményrõl.
24_ora.qxd 8/3/2001 6:23 PM Page 485
A jövõ
Mostanra elkészültünk a teljes rendezvénynaptárral. Remélem sikerült érzékeltetni
ezzel a valós életbeli kisalkalmazások dinamikus kialakításának lehetõségeit és
a PHP szerteágazó képességeit.
Valószínûleg feltûnt már, hogy programjaink kimenete eléggé spártai. Végül át kell
adnunk a munkát egy grafikus tervezõnek, aki ügyes vezérlõsávot, komoly grafi-
kát és más elemeket ad az oldalhoz. Szerencsére a legtöbb PHP kód külsõ állomá-
nyokban található, a HTML-tõl függetlenül, de elképzelhetõ, hogy szükség lesz
ránk is a ciklusok újraírásánál.
Összefoglalás
Ebben és az elõzõ órában elkészítettünk egy teljesen mûködõ többoldalas PHP
alkalmazást. Gyakoroltuk az állapot mentésének, a felhasználói azonosításnak,
az adatbázis-adatok módosításának és megjelenítésének módjait és sok más
kérdést is érintettünk.
24
24_ora.qxd 8/3/2001 6:23 PM Page 488
Kérdések és válaszok
Ennyi volt. Hogyan tovább?
Ez már nem a könyvön múlik. Elég információt találhatunk ebben a könyvben
ahhoz, hogy saját kifinomult alkalmazásainkat el tudjuk készíteni. Ezzel és
a Világhálón elérhetõ rengeteg információval nincs, ami megállíthatna bárkit is
a fejlõdésben!
Mûhely
A mûhelyben kvízkérdések találhatók, melyek segítenek megszilárdítani az órában
szerzett tudást. A válaszokat az A függelékben helyeztük el.
Kvíz
1. Melyik függvény használható új elem tömb végére való beszúrásához?
2. Lehetséges egy új elem felvétele a tömb végére függvény használata nélkül is?
Feladatok
1. Tekintsünk végig az órában tárgyalt forráskódokon. Találunk olyan megoldá-
sokat, amiket fel tudunk használni saját programjainkban?