You are on page 1of 514

Matt Zandstra

PHP4 hasznlatt

A kiadvny a kvetkez angol eredeti alapjn kszlt: Matt Zandstra: Teach Yourself PHP4 in 24 Hours Copyright 2000 by Sams Publishing. All rights reserved. No part of this book, including interior desing, cover design, and icons, may be reproduced or transmitted in any form, by any means (electronic, photocopying, recording, or otherwise) without the prior written permission of the publisher. Acquisitions Editor: Jeff Schultz Project Editor: Paul Schneider Development Editor: Scott D. Meyers Copy Editor: Geneil Breeze Managing Editor: Charlotte Clapp Trademarked names appear throughout this book. Rather than list the names and entities that own the trademarks or insert a trademark symbol with each mention of the trademarked name, the publisher states that it is using the names for editorial purposes only and to the benefit of the trademark owner, with no intention of infringing upon that trademark. A szerzk s a kiad a lehet legnagyobb krltekintssel jrt el e kiadvny elksztsekor. Sem a szerz, sem a kiad nem vllal semminem felelssget vagy garancit a knyv tartalmval, teljessgvel kapcsolatban. Sem a szerz, sem a kiad nem vonhat felelssgre brmilyen baleset vagy kresemny miatt, mely kzvetve vagy kzvetlenl kapcsolatba hozhat e kiadvnnyal. Fordts s magyar vltozat 2001 Szy Gyrgy, Kiskapu Kft. Minden jog fenntartva! Translation and Hungarian edition 2001 Gyrgy Szy, Kiskapu Kft. All rights reserved! Sorozatszerkeszt: Szy Gyrgy Nyelvi lektor: Rzmves Lszl Szakmai lektor: Hojtsy Gbor Mszaki szerkeszt: Csutak Hoffmann Levente

Felels kiad a Kiskapu Kft. gyvezet igazgatja 2001 Kiskapu Kft. 1081 Budapest Npsznhz u. 29. Tel: (+36-1) 477-0443 Fax: (+36-1) 303-1619 http://www.kiskapu.hu/ e-mail: kiskapu@kiskapu.hu ISBN: 963 9301 30 2 Kszlt a debreceni Kinizsi nyomdban Felels vezet: Brds Jnos

Apmnak, akinek ez a knyv biztosan tetszett volna...

A szerzrl
Matt Zandstra (matt@corrosive.co.uk) a Corrosive Web Design cget vezeti (http://www.corrosive.co.uk/) zleti partnervel, Max Guglielminval. Mint a parancsnyelvekrt rajong programoz, PHP, Java, JavaScript, Perl, Lingo s AppleScript nyelveken fejlesztett klnbz programokat. Elszr blcsszdiplomt szerzett, majd gy tanulta ki mestersgt, hogy jra feltallta a kereket s kielemezte, mirt nem halad egyenesen. HTML, JavaScript, Perl s PHP tanfolyamokon oktatott, majd szerzknt kzremkdtt a Dynamic HTML Unleashed cm knyvben. Amikor nem kdot r, Matt elktelezett vrosi biciklista, Guinness-iv, megszllott olvas s novellista, aki kiadhatatlan trtneteket alkot. Azt lltja, egyszer taln mg regnyt is fog rni.

Ksznetnyilvnts
A nylt forrskd programoknak ksznhetem karrieremet s e knyv ltrejttt is. Szeretnm megksznni mindazoknak, akiknek nzetlen segtkszsge mindig fellmlja a kapott elismerst. Klnsen ksznm a PHP kzssgnek, legfkppen a PHP levelezlistk rsztvevinek, akik leveleikkel feltrtk a buktatkat, programozsi mdszereket ajnlottak s mindig mulatba ejtettek. A Macmillantl szeretnm megksznni Randi Rogernek, hogy engem ajnlott e knyv szerzjl, valamint Jeff Schultznak, Paul Schneidernek s Scott Meyersnek, tmogatsukrt s megrtskrt, ahogy a hatrid kzeledett s kitrt a pnik. Ksznet illet mindenkit a Corrosive-nl, hogy eltrtk folyamatos hinyzsomat s nagyfok hatrozatlansgomat a nem PHP-vel kapcsolatos krdsekben. Legfkppen zlettrsamnak, Massimo Guglieminnak vagyok hls, hogy mkdtette a Corrosive cget a megterhel krlmnyek kztt. Ksznet Dave Urmsonnak is, aki tvette a formzst, amikor a munka megkvnta. A Corrosive tovbbi munkatrsai: Anisa Swaffield, Jeff Coburn, Mai Chokelumlerd s Moira Govern. Meg kell ksznnm a Small Planetnek (http://www.smallpla.net/), hogy tovbbi fejlesztsi teret adtak nekem s engedlyeztk a btaprogramok kiprblst. Kifejezetten hls vagyok Mohamed Abbnak s Clive Hillsnek, hogy oly sokszor jrafordtottk a PHP-t a Small Planet kiszolgln. Az oktatsi anyagok kiprblsnak egyik legjobb mdja a tanfolyamon val felhasznls. Ksznet tanulimnak, akik kegyesen beleegyeztek, hogy ksrleti nyulak legyenek. Ksznm kedvesemnek, Louise-nek, s lnyunknak, Hollynak, hogy jelen voltak s elviseltk a knyv rsa alatt kialakult zsrtld, visszahzd s megszllott jellememet. Amint magnletem a PHP utn msodik helyre kerlt, menedkemm a trzshelyem vlt, ahol sszekapcsoltam a srzst a munkval. Ksznet Alannek s Dornak a kifogstalan Prince Arthur iv fenntartsrt. Vgl ksznet a halaknak, akik mindig felvidtanak, ha bmulom ket.

ttekints
Bevezet

I. rsz Az els lpsek


1. ra PHP: szemlyes honlaptl a portlig . . . . . . . . 3 2. ra A PHP teleptse . . . . . . . . . . . . . . . . . . . . . . 11 3. ra Els PHP oldalunk . . . . . . . . . . . . . . . . . . . . . 23

II. rsz A PHP nyelv


4. 5. 6. 7. 8. ra ra ra ra ra Az alkotelemek . . . . . . . . . . . . . . . . . . . . . . 35 Vezrlsi szerkezetek . . . . . . . . . . . . . . . . . . 57 Fggvnyek . . . . . . . . . . . . . . . . . . . . . . . . . 75 Tmbk . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 Objektumok . . . . . . . . . . . . . . . . . . . . . . . . 119

III. rsz Munka a PHP-vel


9. ra 10. ra 11. ra 12. ra 13. ra 14. ra 15. ra 16. ra 17. ra 18. ra 19. ra rlapok . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 Fjlok hasznlata . . . . . . . . . . . . . . . . . . . . . 171 A DBM fggvnyek hasznlata . . . . . . . . . . 193 Adatbzisok kezelse MySQL . . . . . . . . . . 211 Kapcsolat a klvilggal . . . . . . . . . . . . . . . . 237 Dinamikus kpek kezelse . . . . . . . . . . . . . 259 Dtumok kezelse . . . . . . . . . . . . . . . . . . . . 283 Az adatok kezelse . . . . . . . . . . . . . . . . . . . 301 Karakterlncok kezelse . . . . . . . . . . . . . . . 319 A szablyos kifejezsek hasznlata . . . . . . . 339 llapotok trolsa stikkel s GET tpus lekrdezsekkel . . . . . . . . . . 361 20. ra llapotok trolsa munkamenet-fggvnyekkel . . . . . . . . . . . . 381 21. ra Munka kiszolgli krnyezetben . . . . . . . . . 395 22. ra Hibakeress . . . . . . . . . . . . . . . . . . . . . . . . 409

IV. rsz sszefoglal plda


23. ra Teljes plda (els rsz) . . . . . . . . . . . . . . . . 429 24. ra Teljes plda (msodik rsz) . . . . . . . . . . . . . 469 A fggellk Vlaszok a kvzkrdsekre . . . . . . . . . . . 489 Trgymutat

Tartalomjegyzk

Bevezet

I. rsz Az els lpsek


1. ra PHP: szemlyes honlaptl a portlig . . . . . 3
Mi a PHP? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 A PHP fejldse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 A PHP 4 jdonsgai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 A Zend Engine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Mirt a PHP? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 A fejleszts sebessge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 A PHP nylt forrskd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Teljestmny . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Hordozhatsg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 sszefoglals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2. ra A PHP teleptse . . . . . . . . . . . . . . . . . . . . 11

Opercis rendszerek, kiszolglk, adatbzisok . . . . . . . . . . . . . . 12 A PHP beszerzse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 A PHP 4 teleptse Apache webkiszolglt hasznl Linuxra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 A configure nhny paramtere . . . . . . . . . . . . . . . . . . . . . . . . . . 14 --enable-track-vars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 --with-gd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 --with-mysql . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Az Apache belltsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 php.ini . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

xiv short_open_tag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 Hibajelentsek belltsai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 Vltozkra vonatkoz belltsok . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Segtsg! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 sszefoglals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

3. ra Els PHP oldalunk . . . . . . . . . . . . . . . . . . 23

Els programunk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 PHP blokkok kezdse s befejezse . . . . . . . . . . . . . . . . . . . . . . . . . 26 A print() fggvny . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 HTML s PHP kd egy oldalon . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 Megjegyzsek a PHP kdokban . . . . . . . . . . . . . . . . . . . . . . . . . . 30 sszefoglals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

II. rsz A PHP nyelv


4. ra Az alkotelemek . . . . . . . . . . . . . . . . . . . . 35
Vltozk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 Dinamikus vltozk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 Hivatkozsok a vltozkra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 Adattpusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 Tpus mdostsa a settype() segtsgvel . . . . . . . . . . . . . . . . . . . . . 43 Tpus mdostsa tpustalaktssal . . . . . . . . . . . . . . . . . . . . . . . . . . 44 Mveletjelek s kifejezsek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 Hozzrendels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 Aritmetikai mveletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 sszefzs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 Tovbbi hozzrendel mveletek . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 sszehasonlts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 Bonyolultabb sszehasonlt kifejezsek ltrehozsa logikai mveletek segtsgvel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

xv Egsz tpus vltozk rtknek nvelse s cskkentse . . . . . . . . 51 A mveletek kirtkelsi sorrendje . . . . . . . . . . . . . . . . . . . . . . . . . . 52 llandk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 Minden programban hasznlhat llandk . . . . . . . . . . . . . . . . . . . . 54 sszegzs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

5. ra Vezrlsi szerkezetek . . . . . . . . . . . . . . . . 57

Elgazsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 Az if utasts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 Az if utasts else ga . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 Az if utasts elseif ga . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 A switch utasts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 Ciklusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 A while ciklus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 A do..while ciklus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 A for ciklus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 Ciklus elhagysa a break utasts segtsgvel . . . . . . . . . . . . . . . . . . 69 Kvetkez ismtls azonnali elkezdse a continue utasts segtsgvel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 Egymsba gyazott ciklusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 sszegzs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

6. ra Fggvnyek . . . . . . . . . . . . . . . . . . . . . . . 75

Mit neveznk fggvnynek? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 Fggvnyek hvsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 Fggvnyek ltrehozsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 Fggvnyek visszatrsi rtke . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 Dinamikus fggvnyhvsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 Vltozk hatkre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 Hozzfrs vltozkhoz a global kulcssz segtsgvel . . . . . . . . . . . 84 llapot megrzse a fggvnyhvsok kztt a static kulcssz segtsgvel . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 Paramterek tovbbi tulajdonsgai . . . . . . . . . . . . . . . . . . . . . . . . 89 Paramterek alaprtelmezett rtke . . . . . . . . . . . . . . . . . . . . . . . . . . 89

xvi Hivatkozs tpus paramterek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 sszegzs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95

7. ra Tmbk . . . . . . . . . . . . . . . . . . . . . . . . . . 97

Mit neveznk tmbnek? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 Tmbk ltrehozsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 Tmbk ltrehozsa az array() fggvny segtsgvel . . . . . . . . . . . . 99 Tmb ltrehozsa vagy elem hozzadsa a tmbhz szgletes zrjel segtsgvel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 Asszociatv tmbk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 Asszociatv tmbk ltrehozsa az array() fggvny segtsgvel . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 Asszociatv tmbk ltrehozsa s elrse kzvetlen rtkadssal . . . . . . . . . . . . . . . . . . . . . . . . . . 101 Tbbdimenzis tmbk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 Tmbk elrse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 Tmb mretnek lekrdezse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 Tmb bejrsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 Asszociatv tmb bejrsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 Tbbdimenzis tmb bejrsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 Mveletek tmbkkel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 Kt tmb egyestse az array_merge() fggvny segtsgvel . . . . . 110 Egyszerre tbb elem hozzadsa egy tmbhz az array_push() fggvny segtsgvel . . . . . . . . . . . . . . . . . . . . . . 110 Az els elem eltvoltsa az array_shift() fggvny segtsgvel . . . . . . . . . . . . . . . . . . . . . . . 112 Tmb rsznek kinyerse az array_slice() fggvny segtsgvel . . . . . . . . . . . . . . . . . . . . . . . 113 Tmbk rendezse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 Szmmal indexelt tmb rendezse a sort() fggvny segtsgvel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 Asszociatv tmb rendezse rtk szerint az asort() fggvny segtsgvel . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 Asszociatv tmb rendezse kulcs szerint a ksort() fggvny segtsgvel . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 sszegzs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118

xvii

8. ra Objektumok . . . . . . . . . . . . . . . . . . . . . . 119

Mit neveznk objektumnak? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 Objektum ltrehozsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 Objektumtulajdonsgok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 Az objektumok tagfggvnyei . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 Egy bonyolultabb plda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 Az osztly tulajdonsgai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 A konstruktor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 Az ujSor() tagfggvny . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 Az ujNevesSor() tagfggvny . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 A kiir() tagfggvny . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 sszell a kp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 Ami mg hinyzik... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 Mirt hasznljunk osztlyt? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 rkls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 A szl tagfggvnyeinek fellrsa . . . . . . . . . . . . . . . . . . . . . . . . . 134 A fellrt tagfggvny meghvsa . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 Egy plda az rklsre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 A HTMLTablazat sajt tulajdonsgai . . . . . . . . . . . . . . . . . . . . . . . . . 137 A konstruktor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 A cellaMargoAllit() tagfggvny . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 A kiir() tagfggvny . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 A Tablazat s a HTMLTablazat osztlyok a maguk teljessgben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 Mirt alkalmazzunk rklst? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 sszegzs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145

III. rsz Munka a PHP-vel


9. ra rlapok . . . . . . . . . . . . . . . . . . . . . . . . . . 149
Globlis s krnyezeti vltozk . . . . . . . . . . . . . . . . . . . . . . . . . . 150 Adatok bekrse a felhasznltl . . . . . . . . . . . . . . . . . . . . . . . . 152 Tbb elem kivlasztsa a SELECT elemmel . . . . . . . . . . . . . . . . 153 Az rlap minden mezjnek hozzrendelse egy tmbhz . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 Klnbsgek a GET s a POST tovbbts kztt . . . . . . . . . . . . 157

xviii PHP s HTML kd sszekapcsolsa egy oldalon . . . . . . . . . . . . 159 llapot mentse rejtett mezkkel . . . . . . . . . . . . . . . . . . . . . . . . 161 A felhasznl tirnytsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 Fjlfeltlt rlapok s programok . . . . . . . . . . . . . . . . . . . . . . . . 165 sszegzs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170

10. ra Fjlok hasznlata . . . . . . . . . . . . . . . . . 171

Fjlok begyazsa az include() fggvnnyel . . . . . . . . . . . . . . . . . 172 Fjlok vizsglata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 Fjl ltezsnek ellenrzse a file_exists() fggvnnyel . . . . . . . . . 175 Fjl vagy knyvtr? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 Fjl llapotnak lekrdezse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 Fjl mretnek lekrdezse a filesize() fggvnnyel . . . . . . . . . . . . 177 Klnfle fjlinformcik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 Tbb fjltulajdonsgot egyszerre megad fggvny . . . . . . . . . . . . 178 Fjlok ltrehozsa s trlse . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 Fjl megnyitsa rsra, olvassra, hozzfzsre . . . . . . . . . . . . . . 180 Olvass fjlbl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 Sorok olvassa fjlbl az fgets() s feof() fggvnyekkel . . . . . . . . . 181 Tetszleges mennyisg adat olvassa fjlbl . . . . . . . . . . . . . . . . . 182 Fjl karakterenknti olvassa az fgetc() fggvnnyel . . . . . . . . . . . . 184 Fjlba rs s hozzfzs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 Fjlok zrolsa az flock() fggvnnyel . . . . . . . . . . . . . . . . . . . . . . . 186 Munka knyvtrakkal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 Knyvtr ltrehozsa az mkdir() fggvnnyel . . . . . . . . . . . . . . . . . 187 Knyvtr trlse az rmdir() fggvnnyel . . . . . . . . . . . . . . . . . . . . . 188 Knyvtr megnyitsa olvassra . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 Knyvtr tartalmnak olvassa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 sszegzs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191

11. ra A DBM fggvnyek hasznlata . . . . . . . 193

DBM adatbzis megnyitsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 Adatok felvtele az adatbzisba . . . . . . . . . . . . . . . . . . . . . . . . . 195 Adatok mdostsa az adatbzisban . . . . . . . . . . . . . . . . . . . . . . 196

xix Adatok kiolvassa DBM adatbzisbl . . . . . . . . . . . . . . . . . . . . . 197 Elemek megltnek lekrdezse . . . . . . . . . . . . . . . . . . . . . . . . . 199 Elem trlse az adatbzisbl . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 sszetett adatszerkezetek trolsa DBM adatbzisban . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 Egy plda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 sszefoglals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210

12. ra Adatbzisok kezelse MySQL . . . . . . 211

(Nagyon) rvid bevezets az SQL nyelvbe . . . . . . . . . . . . . . . . . . 212 Csatlakozs a kiszolglhoz . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 Az adatbzis kivlasztsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 Hibakeress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 Adatok hozzadsa tblhoz . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 Automatikusan nvekv mez rtknek lekrdezse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 Adatok lekrdezse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 Az eredmnytbla sorainak szma . . . . . . . . . . . . . . . . . . . . . . . . . . 221 Az eredmnytbla elrse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 Adatok frisstse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 Informcik az adatbzisokrl . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 Az elrhet adatbzisok kiratsa . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 Adatbzistblk listzsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 Informcik a mezkrl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 Az adatbzis szerkezete sszell a kp . . . . . . . . . . . . . . . . . . . 230 sszefoglals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235

13. ra Kapcsolat a klvilggal . . . . . . . . . . . . . 237

Krnyezeti vltozk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238 A HTTP gyfl-kiszolgl kapcsolat rvid ismertetse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 A krs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 A vlasz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 Dokumentum letltse tvoli cmrl . . . . . . . . . . . . . . . . . . . . . . 245

xx talakts IP cmek s gpnevek kztt . . . . . . . . . . . . . . . . . . . 246 Hlzati kapcsolat ltestse . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 NNTP kapcsolat ltrehozsa az fsockopen()-nel . . . . . . . . . . . . . . . 251 Levl kldse a mail() fggvnnyel . . . . . . . . . . . . . . . . . . . . . . . 254 sszefoglals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257

14. ra Dinamikus kpek kezelse . . . . . . . . . . 259

Kpek ltrehozsa s megjelentse . . . . . . . . . . . . . . . . . . . . . . 260 A szn belltsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 Vonalak rajzolsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 Alakzatok kitltse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 Krv rajzolsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264 Tglalap rajzolsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 Sokszg rajzolsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266 A sznek tltszv ttele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268 Szvegek kezelse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 Szvegrs az imageTTFtext() fggvnnyel . . . . . . . . . . . . . . . . . . . 269 Szveg kiterjedsnek ellenrzse . . . . . . . . . . . . . . . . . . . . . . . . . . 271 az imageTTFbox() fggvnnyel . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271 A fenti elemek sszegyrsa . . . . . . . . . . . . . . . . . . . . . . . . . . . 275 sszefoglals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281

15. ra Dtumok kezelse . . . . . . . . . . . . . . . . . 283


A dtum kidertse a time() fggvnnyel . . . . . . . . . . . . . . . . . . . 284 Az idblyeg talaktsa a getdate() fggvnnyel . . . . . . . . . . . . 284 Az idblyeg talaktsa a date() fggvnnyel . . . . . . . . . . . . . . . 286 Idblyeg ksztse az mktime() fggvnnyel . . . . . . . . . . . . . . . 288 A dtum ellenrzse a checkdate() fggvnnyel . . . . . . . . . . . . . . . 289 Egy plda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290 A felhasznl ltal bevitt adatok ellenrzse . . . . . . . . . . . . . . . . . . 290 A HTML rlap ltrehozsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291 A naptr tblzatnak ltrehozsa . . . . . . . . . . . . . . . . . . . . . . . . . . 294 sszefoglals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298

xxi Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299

16. ra Az adatok kezelse . . . . . . . . . . . . . . . . 301

jra az adattpusokrl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 Egy kis ismtls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 sszetett adattpusok talaktsa . . . . . . . . . . . . . . . . . . . . . . . . . . . 303 Az adattpusok automatikus talaktsa . . . . . . . . . . . . . . . . . . . . . . 304 Az adattpusok ellenrzse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306 Az adattpus-vlts tovbbi mdjai . . . . . . . . . . . . . . . . . . . . . . . . . 306 Mirt olyan fontosak az adattpusok? . . . . . . . . . . . . . . . . . . . . . . . . 307 A vltozk megltnek s ressgnek ellenrzse . . . . . . . . . . 309 Tovbbi tudnivalk a tmbkrl . . . . . . . . . . . . . . . . . . . . . . . . . . 310 Tmbk bejrsa ms megkzeltsben . . . . . . . . . . . . . . . . . . . . . 310 Elem keresse tmbben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312 Elemek eltvoltsa a tmbbl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312 Fggvnyek alkalmazsa a tmb sszes elemre . . . . . . . . . . . . . . . 312 Tmbk egyni rendezse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314 sszefoglals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318

17. ra Karakterlncok kezelse . . . . . . . . . . . . 319

Karakterlncok formzsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320 A printf() fggvny hasznlata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320 A printf() s a tpusparamterek . . . . . . . . . . . . . . . . . . . . . . . . . . . 321 A kitlt paramter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323 A mezszlessg meghatrozsa . . . . . . . . . . . . . . . . . . . . . . . . . . . 325 A pontossg meghatrozsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 talakt paramterek (Ismtls) . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 Formzott karakterlnc trolsa . . . . . . . . . . . . . . . . . . . . . . . . . . 328 Rszletesebben a karakterlncokrl . . . . . . . . . . . . . . . . . . . . . . 329 Szvegek indexelse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329 Szveg hossznak megllaptsa az strlen() fggvnnyel . . . . . . . . 329 Szvegrsz megkeresse az strstr() fggvnnyel . . . . . . . . . . . . . . . 330 Rszlnc elhelyezkedsnek meghatrozsa az strpos() fggvnnyel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330

xxii Szvegrszlet kinyerse a substr() fggvnnyel . . . . . . . . . . . . . . . . 331 Karakterlnc elemekre bontsa az strtok() fggvnnyel . . . . . . . . . 331 A karakterlncok kezelse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333 Szveg tisztogatsa a trim() tpus fggvnyekkel . . . . . . . . . . . . . . 333 Karakterlnc rsznek lecserlse a substr_replace() fggvnnyel . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334 Az sszes rszlnc lecserlse az str_replace() fggvnnyel . . . . . . 334 Kis- s nagybetk kzti vlts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335 Karakterlncok tmbb alaktsa az explode() fggvnnyel . . . . . . 336 sszefoglals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338

18. ra A szablyos kifejezsek hasznlata . . . . 339

A POSIX szablyos kifejezsek fggvnyei . . . . . . . . . . . . . . . . . 340 Minta keresse karakterlncokban az ereg() fggvnnyel . . . . . . . . 340 Egynl tbbszr elfordul karakter keresse mennyisgjelzvel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341 Karakterlnc keresse karakterosztlyokkal . . . . . . . . . . . . . . . . . . . 343 Az atomok kezelse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344 Elgazsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345 A szablyos kifejezs helye . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345 A tagazonostt keres plda jragondolsa . . . . . . . . . . . . . . . . . . 346 Mintk lecserlse karakterlncokban az ereg_replace() fggvnnyel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347 Visszautals hasznlata az ereg_replace() fggvnnyel . . . . . . . . . . 347 Karakterlncok felbontsa a split() fggvnnyel . . . . . . . . . . . . . . . 348 Perl tpus szablyos kifejezsek . . . . . . . . . . . . . . . . . . . . . . . . 348 Mintk keresse a preg_match() fggvnnyel . . . . . . . . . . . . . . . . . 349 A Perl tpus szablyos kifejezsek s a mohsg . . . . . . . . . . . . . . 349 A Perl tpus szablyos kifejezsek s . . . . . . . . . . . . . . . . . . . . . . 350 a fordtott perjeles karakterek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350 Teljeskr keress a preg_match_all() fggvnnyel . . . . . . . . . . . . 351 Mintk lecserlse a preg_replace() fggvnnyel . . . . . . . . . . . . . . 354 Mdost paramterek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355 sszefoglals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359

xxiii

19. ra llapotok trolsa stikkel s GET tpus lekrdezsekkel . . . . . . . 361

Stik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362 A stik felptse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362 Stik belltsa a PHP-vel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363 Sti trlse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365 Munkamenet-azonost stik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366 Plda: Webhelyhasznlat nyomon kvetse . . . . . . . . . . . . . . . . . . 366 Lekrdez karakterlncok hasznlata . . . . . . . . . . . . . . . . . . . . . . 374 Lekrdez karakterlnc ksztse . . . . . . . . . . . . . . . . . . . . . . . . 375 sszefoglals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379

20. ra llapotok trolsa munkamenet-fggvnyekkel . . . . . . . . . 381

Mik azok a munkamenet-fggvnyek? . . . . . . . . . . . . . . . . . . . . . 382 Munkamenet indtsa a session_start() fggvnnyel . . . . . . . . . . . . . . . . . . . . . . . . . . . 382 Munkamenet-vltozk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384 A munkamenet s a vltozk bejegyzsnek trlse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389 Munkamenet-azonostk a lekrdez karakterlncban . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390 Munkamenet-vltozk kdolsa s visszafejtse . . . . . . . . . . . . . 390 Munkamenet-vltoz bejegyzsnek ellenrzse . . . . . . . . . . . . 391 sszefoglals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393

21. ra Munka kiszolgli krnyezetben . . . . . . 395

Folyamatok sszektse a popen() fggvnnyel . . . . . . . . . . . . . 396 Parancsok vgrehajtsa az exec() fggvnnyel . . . . . . . . . . . . . . 399 Kls programok futtatsa a system() fggvnnyel vagy a ' mveletjel segtsgvel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401 Biztonsgi rsek megszntetse az escapeshellcmd() fggvny hasznlatval . . . . . . . . . . . . . . . . 401

xxiv Kls programok futtatsa a passthru() fggvnnyel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404 Kls CGI program meghvsa a virtual() fggvnnyel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405 sszefoglals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408

22. ra Hibakeress . . . . . . . . . . . . . . . . . . . . . 409

A phpinfo() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410 A forrskd megjelentse sznkiemelssel . . . . . . . . . . . . . . . . . 413 PHP hibazenetek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415 Hibazenetek kirsa naplfjlba . . . . . . . . . . . . . . . . . . . . . . . . . 418 A hibazenet elfogsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420 Kzi hibakeress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421 Gyakori hibk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423 sszefoglals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426

IV. rsz sszefoglal plda


23. ra Teljes plda (els rsz) . . . . . . . . . . . . . 429
A feladat rvid lersa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430 Az oldalak felptse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430 Az adatbzis kialaktsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431 Tervezsi dntsnk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433 A tagoknak sznt oldalak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433 csatlakozas.php s adatbazis.inc . . . . . . . . . . . . . . . . . . . . . . . . . . . 434 klubfrissites.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442 tagmenu.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449 belepes.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450 esemenyfrissites.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453 esemenylista.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462 sszefoglals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466

xxv Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467

24. ra Teljes plda (msodik rsz) . . . . . . . . . . 469

Az esemnynaptr nyilvnos oldalai . . . . . . . . . . . . . . . . . . . . . . 470 esemenyekinfo.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470 klubokinfo.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478 klubinfo.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481 esemenyinfo.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484 A jv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 486 sszefoglals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487 Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488

A fggellk Vlaszok a kvzkrdsekre. . . . . . . . 489 Trgymutat

Bevezet
Ez a knyv egy nylt forrskd webes parancsnyelvrl (szkriptrl), a PHP-rl szl, amely csatlakozott a Perl-hz, az ASP-hez s a Javhoz a dinamikus webes alkalmazsok ksztshez rendelkezsre ll nyelvek palettjn. A ktet programozsi ismeretekkel is foglalkozik. A rendelkezsre ll lapokon nem jut elg hely egy teljes PHP programozsi tmutat kzlsre vagy a PHP sszes lehetsgnek s eljrsnak ismertetsre, mindazonltal a knyvben tallhat lpsek elg informcit adnak ahhoz, hogy hasznlni kezdhessk a PHP-t, akr rendelkeznk programozi tapasztalttal, akr jak vagyunk a parancsnyelvek vilgban.

Kiknek szl ez a knyv?


A knyv az alapoktl indulva hasznos gyakorlati tudst ad a PHP 4-es programozsi nyelv hasznlathoz. Semmilyen korbbi programozsi tapasztalatra nincs szksg, de ha a C vagy a Perl nyelvekkel mr dolgoztunk korbban, az egyes rkon knnyebb lesz haladni. A PHP 4 webes programozsi nyelv. Ahhoz, hogy a lehet legtbb hasznt vegyk a knyvnek, clszer nmi ismerettel rendelkezni a Vilghlval s a HTMLlel kapcsolatban. Ha nem rendelkeznk ilyen ismeretekkel, akkor is hasznos lehet e knyv, m meggondoland egy HTML ismertet beszerzse. Ha knyelmesen ltre tudunk hozni egyszer HTML dokumentumokat tblzatokkal, akkor elegend tudssal rendelkeznk. A PHP 4-esben az adatbzisok kezelse igen egyszer. A knyv nhny pldjban a MySQL ingyenes adatbzisrendszert hasznltuk. Az SQL nyelvet rviden ismertetjk, de ha komolyabban kvnjuk hasznlni az adatbziskezel szolgltatsokat, clszer elmlyednnk nhny kapcsold anyagban. Az Interneten szmos bevezet szint SQL ismertet rhet el. Ha mgsem a MySQL adatbzisrendszerrel kvnunk dolgozni, a knyv pldit knnyen ms adatbzisokhoz igazthatjuk.

Knyvnk szerkezete
Ktetnk ngy f rszbl ll: Az els rsz bevezet a PHP alapjaihoz. A msodik rsz az alapvet szolgltatsokat mutatja be. Ha mg nincs programozsi tapasztalatunk, ezt a rszt klns figyelemmel olvassuk!

xxviii

Tanuljuk meg a PHP4 hasznlatt 24 ra alatt A harmadik rsz rszletesebben ismerteti a PHP 4-es vltozatnak lehetsgeit, felsorakoztatva a fggvnyeket s megoldsokat, melyekre szksgnk van, ha gyakorlott PHP programozk szeretnnk lenni. A negyedik rsz egy teljesen nllan mkd pldaprogramot mutat be. Az els rsz az elstl a harmadik rig tart s egy egyszer parancsfjl futtatsig vezeti el az olvast: Az els ra PHP: szemlyes honlaptl a portlig cmmel bemutatja a PHP trtnett s kpessgeit, valamint a PHP tanulsa mellett nhny rvet sorol fel. A msodik ra A PHP teleptse cmmel vgigvezeti az olvast a PHP teleptsn UNIX rendszeren, valamint azon fordtsi s belltsi lehetsgekkel foglakozik, amelyek a krnyezet kialaktsa szempontjbl fontosak lehetnek. A harmadik ra Els PHP oldalunk cmmel bemutatja, hogyan pthetnk PHP kdot HTML oldalainkba s hogyan kszthetnk a bngsz szmra kimenetet ad programot. A msodik rszben a negyediktl a nyolcadik rig megismerjk a PHP alapvet elemeit: A negyedik ra Az alkotelemek cmmel a PHP alapjait mutatja be. Az ra anyagt vltozk, adattpusok, mveletjelek (opertorok) s kifejezsek kpezik. Az tdik ra Vezrlsi szerkezetek cmmel a programok futst vezrl elemek utastsformjval (nyelvtanval) foglalkozik. Az if s switch szerkezetek utn megtanuljuk a for s while ciklusvezrl elemek hasznlatt is. A hatodik ra Fggvnyek cmmel a fggvnyek ksztst s hasznlatt trgyalja. A hetedik ra Tmbk cmmel a lista jelleg adatok trolsra hasznlhat tmb adattpussal foglalkozik, valamint a tmbk hasznlathoz nhny PHP 4 fggvnyt is ismertetet. A nyolcadik ra Objektumok cmmel bemutatja a PHP 4 osztly- s objektumtmogatst. Ebben az rban egy mkd pldn keresztl vesszk grcs al az objektumok hasznlatt. A harmadik rszben a kilencediktl a huszonkettedik rig alaposan megismerjk a nyelv szolgltatsait s megoldsi mdszereit: A kilencedik ra rlapok cmmel a HTML rlapok hasznlatt, vagyis a felhasznltl rkez adatok feldolgozst vezeti be. Megtanuljuk, miknt rjk el a berkez informcikat. A tizedik ra Fjlok hasznlata cmmel bemutatja a fjlok s knyvtrak kezelsnek lehetsgeit.

Bevezet A tizenegyedik ra A DBM fggvnyek hasznlata cmmel a PHP DBMtmogatsval foglalkozik, amely a legtbb opercis rendszeren elrhet. A tizenkettedik ra Adatbzisok kezelse MySQL cmmel az SQL alapjait trgyalja, valamint bemutatja a PHP 4 MySQL adatbzisok kezelsre szolgl fggvnyeit. A tizenharmadik ra Kapcsolat a klvilggal cmmel a HTTP krseket veszi szemgyre, illetve a PHP hlzati fggvnyeit ismerteti. A tizennegyedik ra Dinamikus kpek kezelse cmmel a GIF, PNG s JPEG kpek ksztst lehetv tev fggvnyeket mutatja be. A tizentdik ra Dtumok kezelse cmmel a dtummveletekhez hasznlatos fggvnyeket s eljrsokat ismerteti. Ebben az rban egy naptr pldt is elksztnk. A tizenhatodik ra Az adatok kezelse cmmel visszatr az adattpusokhoz s az addig nem emltett, de a hatkony hasznlathoz elengedhetetlen tovbbi fggvnyeket mutatja be. A tmbkkel kapcsolatban is jabb fggvnyeket emltnk. A tizenhetedik ra Karakterlncok kezelse cmmel a karakterlncok kezelshez jl hasznlhat PHP fggvnyekkel foglalkozik. A tizennyolcadik ra A szablyos kifejezsek hasznlata cmmel bemutatja a bonyolultabb mintk keressre s cserjre szolgl szablyos kifejezseket. A tizenkilencedik ra llapotok trolsa stikkel s GET tpus lekrdezsekkel cmmel a klnbz programok s HTTP krsek kztti informcitads nhny mdjt mutatja be. A huszadik ra llapotok trolsa munkamenet-fggvnyekkel cmmel az elz rban tanultakat a PHP 4-es beptett munkamenet-kezel fggvnyeivel bvti ki. A huszonegyedik ra Munka kiszolgli krnyezetben cmmel a kls programok futtatst s kimenetk felhasznlsnak lehetsgeit mutatja be. A huszonkettedik ra Hibakeress cmmel a kdok hibakeressre ad tleteket, valamint bemutat nhny szoksos hibt. A negyedik rszben a huszonharmadik s huszonnegyedik rkon a knyvben tanult mdszerek felhasznlsval egy mkd pldt ksztnk. A huszonharmadik ra egy tervet mutat be helyi klubok szmra kszl programunkhoz. Megrjuk a felhasznlk bejegyzshez s a klubok programjnak bevitelhez szksges elemeket. A huszonnegyedik ra befejezsknt a ltogatk szmra kszlt fellet megvalstshoz szksges kdot tartalmazza, amely lehetv teszi a klubok programjainak bngszst. A knyvel kapcsolatos szrevteleiket a http://www.kiskapu.hu/konyvek/PHP4/ cmen tehetik meg, ugyancsak ezen az oldalon tallhat a hibajegyzk is.

xxix

I. RSZ
Az els lpsek
1. ra PHP: szemlyes honlaptl a portlig 2. ra A PHP teleptse 3. ra Els PHP oldalunk

1. RA
PHP: szemlyes honlaptl a portlig
dvzlet a PHP vilgban! Ebben a knyvben vgigtekintjk a PHP nyelv majdnem minden elemt. Mieltt azonban rszletesebben megnznnk, mire lehetnk kpesek segtsgvel, trjuk fel mltjt, fbb tulajdonsgait s jvjt. Ebben az rban a kvetkezket tanuljuk meg: Mi a PHP? Hogyan fejldtt a nyelv? Mik a PHP 4 jdonsgai? Hogyan tehetjk optimliss a PHP-t? Mirt pont a PHP-t vlasszuk?

1. ra

Mi a PHP?
A PHP nyelv tlntt eredeti jelentsgn. Szletsekor csupn egy makrkszlet volt, amely szemlyes honlapok karbantartsra kszlt. Innen ered neve is: Personal Home Page Tools. Ksbb a PHP kpessgei kibvltek, gy egy nllan hasznlhat programozsi nyelv alakult ki, amely kpes nagymret webes adatbzis-alap alkalmazsok mkdtetsre is. A PHP nyelv npszersge kpessgeinek bvlsvel folyamatosan ntt. A NetCraft elemz cg (http://www.netcraft.com/) felmrsei szerint a PHP-t 2000 februrjban 1,4 milli kiszolgln hasznltk s oktberre ez a szm 3,3 millira ugrott. Ezzel megkzeltette a Microsoft IIS kiszolglk szmt, ami 3,8 milli. Az E-Soft szerint a PHP a legnpszerbb Apache modul, a ModPerlt is maga mg utastva. A PHP jelenleg hivatalosan a PHP: Hypertext Preprocessor elnevezst hasznlja. Tulajdonkppen kiszolgloldali programozsi nyelv, amit jellemzen HTML oldalakon hasznlnak. A hagyomnyos HTML lapokkal ellenttben azonban a kiszolgl a PHP parancsokat nem kldi el az gyflnek, azokat a kiszolgl oldaln a PHP-rtelmez dolgozza fel. A programjainkban lv HTML elemek rintetlenl maradnak, de a PHP kdok lefutnak. A kdok vgezhetnek adatbzis-lekrdezseket, dinamikusan ltrehozhatnak kpeket, fjlokat olvashatnak s rhatnak, kapcsolatot ltesthetnek tvoli kiszolglkkal a lehetsgek szma vgtelen. A PHP kdok kimenete a megadott HTML elemekkel egytt kerl az gyflhez.

A PHP fejldse
A PHP els vltozatt amely nhny webalkalmazs-ksztst segt makrt tartalmazott Rasmus Lerdorf ksztette 1994-ben. Ezen eszkzket egyttesen a Personal Home Page Tools nvvel azonostottk. Ksbb, a kd jrarsa utn, egy friss elem kerlt a csomagba, a Form Interpreter (rlapfeldolgoz), gy PHP/FI nven vlt ismertebb. A felhasznlk szemszgbl a PHP/FI nagyon hasznos segdeszkz volt, gy npszersge tretlenl ntt. Tbb fejleszt is felfigyelt r, gy 1997-re mr szmos programoz dolgozott rajta. A kvetkez kiads, a PHP 3-as, mr egy csapat egyttmkdsbl szletett. Ehhez a vltozathoz Zeev Zuraski s Andi Gutmans jjalkotta a teljes feldolgozegysget, valamint jabb elemeket s szablyokat adott a nyelvhez. Ez a vltozat megalapozott tette a PHP helyt a legjobb kiszolgloldali nyelvek kztt, gy felhasznli tbora rendkvli mrtkben ntt. Az Apache- s MySQL-tmogats megerstette a PHP pozcijt. Az Apache jelenleg a legnpszerbb kiszolgl a vilgon s a PHP 3-as mr modulknt illeszthet hozz. A MySQL igen hatkony, radsul ingyenes SQL adatbzisrendszer, amelyhez a PHP tfog tmogatst nyjt. Az Apache-MySQL-PHP egyttes egyszeren verhetetlen.

PHP: szemlyes honlaptl a portlig Ez termszetesen nem jelenti azt, hogy a PHP nem hasznlhat ms krnyezetben, ms eszkzkkel. A PHP szmos adatbzis-alkalmazssal s webkiszolglval kpes egyttmkdni. A PHP npszersgnek nvekedsre hatssal volt a webes alkalmazsok fejlesztsben trtnt vlts is. Az 1990-es vek kzepn termszetesnek szmtott, hogy akr egy nagyobb webhelyet is tbb szz, egyenknt kzzel kdolt HTML lap felhasznlsval ksztsenek el. Mra azonban a fejlesztk egyre inkbb kihasznljk az adatbzisok nyjtotta knyelmi szolgltatsokat, hogy a megjelentend tartalmat hatkonyan kezeljk s az egyes felhasznlknak lehetsget adjanak a webhelyek testreszabsra. Egyre gyakoribb adatbzisok hasznlata a tartalom trolsra s az informcik visszakeressre klnbz felleteken. Az adatok egy kzpontbl tbb krnyezetbe is rkezhetnek, belertve a mobiltelefonokat, a digitlis szemlyi titkrokat (PDA), digitlis televzikat s szlessv internetes rendszereket is. Ebben a krnyezetben mr nem meglep, hogy egy ilyen kifinomult s rugalmas nyelv, mint a PHP, ekkora npszersgre tett szert.

A PHP 4 jdonsgai
A PHP 4-es vltozata szmos a programozk lett megknnyt j szolgltatssal rendelkezik. Nzzk ezek kzl a legfontosabbakat: A Perl nyelvben tallhathoz hasonl j foreach vezrlsi szerkezet, ami leegyszersti a tmbkn vgrehajtand ciklusok ksztst. Ezt fogjuk hasznlni a knyv legtbb tmbbel kapcsolatos pldjban. Ezen tl szmos j tmbkezel fggvny kerlt a nyelvbe, amelyek megknnytik a tmbkkel vgzett mveleteket. A nyelv tartalmazza a boolean (logikai) adattpust. A PHP 3 felettbb hasznos szolgltatsa volt, hogy a HTML rlap elemeit tmbnevekkel lthattuk el, gy ezek neve s rtke a program szmra egy tmbknt kerlt tadsra. Ez a szolgltats a tbbdimenzis tmbk tmogatsval bvlt. A PHP 3 csak kezdetleges szinten tmogatta az objektumkzpont programozst. Ezen a tren is jelents fejleszts trtnt, a PHP 4-esben pldul mr lehetsges egy fellrt metdus meghvsa egy leszrmazott osztlybl.

1. ra A PHP 4-be beptettk a felhasznli munkamenetek (session) tmogatst is. Ezek kezelse stik (cookie) vagy GET metdus lekrdezsek (query string) formjban trtnhet. Lehetsgnk van vltozkat rendelni egy munkamenethez s ms oldalakon jra elrni ezeket. Kt j sszehasonlt mveletet vezettek be (=== s !==), melyekkel egyidben rtkek s tpusok egyezst, illetleg nem egyezst is ellenrizhetjk. A kiszolgli s krnyezeti adatok trolsra j beptett asszociatv tmbket hoztak ltre, valamint egy j vltozt, amelybl informcikat kaphatunk a feltlttt fjl(ok)rl. A PHP 4-es beptett tmogatssal rendelkezik a Java s XML nyelvekhez. Ezek s ms j szolgltatsok ugyan jelentsen bvtettk a nyelvet, de a legfontosabb vltozs a felszn alatt kvetkezett be.

A Zend Engine
A PHP 3 ksztsekor az alapoktl indulva teljesen j feldolgozegysget rtak a nyelvhez. A PHP 4-esben hasonl vltozs figyelhet meg a programokat futtat magban, ez azonban jelentsebb. A Zend Engine a PHP modulok mgtt tallhat, a programokat futtat mag elnevezse. Kifejezetten a teljestmny jelents nvelsre fejlesztettk ki. A hatkonysgi vltozsok minden bizonnyal biztostani fogjk a PHP tovbbi sikert. A PHP 3-as vltozata szmra kszlt kdok legnagyobb rsze minden mdosts nlkl tovbb mkdik, st, akr 200-szoros sebessggel futhat. A Zend Technologies Ltd. (http://www.zend.com/) egyik kereskedelmi fejlesztse a PHP kdok fordtst teszi lehetv. Ez tovbbi teljestmnynvekedst jelent, amivel a mrsek szerint a PHP messze maga mgtt hagyja legtbb versenytrst. A Zend Engine a teljestmny s a rugalmassg nvelsre rdott. A kiszolglkapcsolatok tovbbfejlesztsvel lehetv vlt, hogy olyan PHP modulok kszljenek, amelyek a kiszolglk szles krvel kpesek egyttmkdni. Mg CGI-feldolgozknt minden lekrshez j PHP-rtelmezt kell elindtani, addig modulknt a PHP folyamatosan a memriban van. Ez gyorsabb futst jelent, hiszen nem kell mindig elindtani egy jabb feldolgozprogramot, ha krs rkezik.

PHP: szemlyes honlaptl a portlig

Mirt a PHP?

Van nhny megcfolhatatlan rv, amirt a PHP 4-est rdemes vlasztani. Ha ms programnyelveket is ismernk, szmos alkalmazs fejlesztse sorn szlelni fogjuk, hogy a programozsi szakasz rezheten gyorsabb, mint vrnnk. A PHP, mint nylt forrskd termk j tmogatssal rendelkezik, amit a kpzett fejleszti grda s az elktelezett kzssg nyjt szmunkra. Radsul a PHP a legfontosabb opercis rendszerek brmelyikn kpes futni, a legtbb kiszolglprogrammal egyttmkdve.

A fejleszts sebessge
Mivel a PHP lehetsget ad a HTML elemek s a programkdok elklntsre, az alkalmazsok fejlesztsekor lehetsg van elvlasztani a kdolsi, tervezsi, s sszelltsi szakaszt. Ez jelentsen megknnyti a programozk lett, azzal, hogy elmozdtja az akadlyokat a hatkony s rugalmas alkalmazsok kialaktsnak tjbl.

A PHP nylt forrskd


Szmos felhasznl szemben a nylt forrskd egyet jelent azzal, hogy ingyenes, ami termszetesen mr nmagban is elnys. Egy idzet a PHP hivatalos webhelyrl (http://www.php.net/): JDONSG Taln idegennek hangozhat azok szmra, akik nem UNIX-httrrel olvassk-e sorokat, hogy a PHP nem kerl semmibe. Hasznlhat kereskedelmi s/vagy nem kereskedelmi clra, ahogy tetszik. Odaadhatjuk bartainknak, kinyomtathatjuk s felakaszthatjuk a falra vagy akr elfogyaszthatjuk ebdre. Lgy dvzlve a nylt forrskd programok vilgban! Mosolyogj, lgy boldog, a vilg j! Tovbbi informcikrt lsd a hivatalos licenszet. A jl szervezett nylt forrskd projektek jabb elnykkel szolglnak a felhasznlknak. Felvehetjk a kapcsolatot a knnyen elrhet s elktelezett felhasznli kzssggel, ahol szmos nagy tapasztalattal rendelkez embert tallunk. Nagy az esly r, hogy brmilyen problmval is kerljnk szembe, nmi kutatssal gyorsan s knnyen vlaszt tallunk r. Ha mgsem, egy levelezlistra kldtt zenetre ltalban hamar rkezik intelligens s hiteles vlasz. gyszintn bizonyos, hogy a feldolgozprogram hibinak javtsa nem sokkal felfedezsk utn megtrtnik s a felmerlt j ignyeket kielgt szolgltatsok is hamar beplnek a nyelvbe. Nem kell vrni a kvetkez hivatalos kiadsra, hogy a fejlesztsek elnyeit lvezzk.

1. ra Nincs a PHP mkdtetshez egyedileg kivlasztott kiszolgl vagy opercis rendszer. Szabadon vlaszthatunk olyan rendszert, amely kielgti sajt vagy gyfeleink ignyeit. Biztos, hogy kdunk tovbbra is futtathat lesz, brmi mellett is dntnk.

Teljestmny
A hatkony Zend Engine-nek ksznheten a PHP 4-es jl vizsgzik az ASP-vel szemben vgzett mrseken, nhnyban megelzve azt. A lefordtott PHP messze maga mgtt hagyja az ASP-t.

Hordozhatsg
A PHP-t alapveten gy terveztk, hogy alkalmas legyen szmos opercis rendszeren val hasznlatra, egyttmkdve klnbz kiszolglkkal s adatbziskezelkkel. Fejleszthetnk UNIX rendszerre s ttrhetnk NT alapokra minden problma nlkl. A PHP alkalmazsokat kiprblhatjuk Personal Web Serverrel s ksbb telepthetjk azokat egy UNIX rendszerre, ahol a PHP-t Apache modulknt hasznljuk.

sszefoglals
Ebben az rban bemutattuk a PHP-t. Lttuk, hogyan alakult t a nyelv egyszer makrkszletbl hatkony programnyelvv. Megismertk a Zend Engine-t, s megnztk, milyen j lehetsgeket teremt a PHP 4-es vltozatban. Vgl ttekintettnk nhny tulajdonsgot, amelyek ellenllhatatlann teszik a PHP-t.

Krdsek s vlaszok
Knny megtanulni a PHP nyelvet? Rviden: igen! Valban meg lehet tanulni a PHP alapjait 24 rban! A PHP megszmllhatatlanul sok fggvnyt bocst rendelkezsnkre, melyek megvalstshoz ms nyelvekben sajt kdot kellene rni. A PHP automatikusan kezeli a klnbz adattpusokat s memriafoglalsokat (hasonlan a Perl-hz). Egy programozsi nyelv nyelvtannak s szerkezeteinek megrtse azonban csak az t kezdett jelenti. Vgssoron a sajt programok ksztsbl s a hibk kijavtsbl lehet igazn sokat tanulni. Ezt a knyvet kiindulpontknt rdemes tekinteni.

PHP: szemlyes honlaptl a portlig

Mhely
Kvz

A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

1. Mit jelentett eredetileg a PHP betsz? 2. Ki ksztette a PHP els vltozatt? 3. Mi az j mag neve a PHP 4-es vltozatban? 4. Soroljuk fel a PHP 4 nhny j szolgltatst!

Feladatok
1. A knyvet tlapozva annak felptse alaposabban szemgyre vehet. Gondolkozzunk el a tmkon, s azon, hogyan segthetnek jvbeni alkalmazsaink elksztsben.

2.RA
A PHP teleptse
Mieltt megkezdennk az ismerkedst a PHP nyelvvel, be kell szereznnk, teleptennk s belltanunk a PHP-rtelmezt. A feldolgozprogram szmos opercis rendszerre elrhet s tbb kiszolglval is kpes egyttmkdni. Ebben az rban a kvetkezket tanuljuk meg: Milyen platformokat, kiszolglkat s adatbzisokat tmogat a PHP? Honnan szerezhetjk be a PHP-t s ms nylt forrskd programokat? Hogyan telepthet a PHP Linux rendszerre? Hogyan llthatk be a fontosabb paramterek? Hol tallhat segtsg, ha nem sikerl a telepts?

12

2. ra

Opercis rendszerek, kiszolglk, adatbzisok


A PHP teljesen platformfggetlen, ami azt jelenti, hogy fut Windows opercis rendszeren, a legtbb UNIX rendszeren belertve a Linuxot , st mg Macintosh gpeken is. A tmogatott kiszolglk kre igen szles. A legnpszerbbek: Apache (szintn nylt forrskd s platformfggetlen), Microsoft Internet Information Server, WebSite Pro, iPlanet Web Server, OmniHTTPD s Microsoft Personal Web Server. Az utbbi kett akkor tehet nagy szolglatot, ha internetkapcsolat nlkl szeretnnk fejleszteni, br az Apache is alkalmas erre Windows krnyezetben. A PHP fordthat nll alkalmazss is, gy az rtelmez parancssorbl is hvhat. Ebben a knyvben webalkalmazsok fejlesztshez fogjuk hasznlni a PHP-t, de nem szabad albecslni a szerept ltalnos programozi eszkzknt sem. A PHP-t alapveten gy terveztk, hogy knnyen sszhangba hozhat legyen a klnbz adatbzisokkal. Ez az egyik oka a PHP npszersgnek a webalkalmazsok ksztse tern. Szmos adatbzis Adabas D, InterBase, Solid, dBASE, mSQL, Sybase, Empress, Microsoft SQL, MySQL, Velocis, FilePro, Oracle, UNIX dbm, Informix s PostgreSQL kzvetlenl csatlakoztathat a PHP-hez. A kzvetlenl nem tmogatott adatbzisok mellett a PHP-ben kapcsolatot ltesthetnk az ODBC szabvnyt hasznl programokkal is. A knyv pldiban Linux opercis rendszer alatt Apache s MySQL programokat hasznlunk. Ezek ingyenesen letlthetk az Internetrl, valamint knnyen telepthetk s hasznlhatk majdnem minden PC-n. A Linux rendszer teleptsrl tovbbi informci a http://www.linux.org/help/beginner/distributions.html cmen tallhat. A Linux PowerPC gpen is hasznlhat, a LinuxPPC rendszerrel: http://www.linuxppc.org/. Magyarorszgon a Linux kzssg honlapja a http://www.linux.hu/. A MySQL adatbzisrendszer, amit ebben a knyvben hasznlni fogunk, a http://www.mysql.com/ cmrl tlthet le. Szmos opercis rendszerre elrhet, belertve a UNIX, Windows s OS/2 rendszereket. A MySQL magyar tkrkiszolglja a http://mysql.sote.hu/. Termszetesen nyugodtan dolgozhatnnk Windows NT vagy MacOS rendszer alatt is, mivel a PHP platformfggetlen nyelv.

A PHP teleptse

13

A PHP beszerzse
A PHP 4-es vltozata a http://www.php.net/ cmrl tlthet le. Mivel a PHP nylt forrskd, nem kell a bankkrtynkat kznl tartanunk, amikor letltjk az rtelmezt. Magyarorszgon a http://hu.php.net/ tkrkiszolglt rdemes megltogatni. A PHP webhelye kivl informciforrs PHP programozknak. A http://www.php.net/manual/ cmen a teljes kziknyv elolvashat, kiegsztve ms programozk ltal rt hasznos megjegyzsekkel. Ezen a cmen olvashat a magyar PHP kziknyv is. A PHP honlaprl a dokumentci is letlthet klnbz formtumokban. A Zend Engine s ms Zend termkek honlapja a http://www.zend.com/. Itt hreket, illetve cikkeket olvashatunk a PHP s a Zend vilgbl.

A PHP 4 teleptse Apache webkiszolglt hasznl Linuxra


Ebben a rszben vgigvezetnk egy PHP teleptst egy Apache webkiszolglt hasznl Linux rendszeren. A folyamat tbb-kevsb ugyanez ms UNIX platformokon is. Elkpzelhet, hogy az ltalunk hasznlt rendszerre kszlt elre fordtott vltozat is, gy mg egyszerbben telepthetnnk az rtelmezt, a PHP fordtsa azonban nagyobb szabadsgot ad a feldolgozba kerl szolgltatsokat illeten. Mieltt megkezdjk a teleptst, ellenrizzk, hogy rendszergazdaknt (root) jelentkeztnk-e be a rendszerbe. Ha a kiszolglt nem rhetjk el root felhasznlknt, forduljunk a rendszergazdhoz a PHP teleptsvel kapcsolatos krseinkkel. A PHP-t ktflekppen lehet Apache modulknt ellltani. Egyrszt jrafordthatjuk a webkiszolglt s bepthetjk a PHP-rtelmezt, msrszt a PHP-t dinamikusan megosztott objektumknt (DSO, Dynamic Shared Object) is fordthatjuk. Ha Apache kiszolglnk DSO-tmogatssal elltott, kpes lesz az j modul hasznlatra anlkl, hogy jrafordtannk a programot. Ez a legegyszerbb mdja annak, hogy bezemeljk a PHP-t, ezrt ezt az eljrst fogjuk trgyalni. Ha ellenrizni kvnjuk, hogy az Apache rendelkezik-e DSO-tmogatssal, el kell indtanunk az Apache futtathat llomnyt (httpd) az -l paramterrel. /www/bin/httpd -l

14

2. ra A program ekkor egy listt ad a rendelkezsre ll beptett modulokrl. Ha a mod_so.c elem szerepel a listban, akkor az Apache alkalmas az albb bemutatott mdszerrel trtn bvtsre. Egyb esetben jra kell fordtani, amihez a dokumentci tartalmazza az sszes szksges informcit. Ha mg nem tettk meg, le kell tltennk a PHP legfrissebb vltozatt. A tar fjl gzip-pel tmrtett, gy els lpsben ki kell csomagolnunk: tar -xvzf php-4.x.x.tar.gz Ha sikeresen kibontottuk a csomagot, lpjnk t a keletkezett knyvtrba: cd ../php-4.x.x Ebben a knyvtrban tallhat a configure program, melynek a megfelel paramterekkel megadhatjuk, milyen szolgltatsokat ptsen be a PHP-be. Ebben a pldban csak nhny hasznos parancssori paramtert adunk meg, de termszetesen szmos ms lehetsg is rendelkezsre ll. Ksbb megnznk nhny tovbbi elemet a configure paramterei kzl. ./configure --enable-track-vars \ --with-gd \ --with-mysql \ --with-apxs=/www/bin/apxs Lehetsges, hogy a --with-apxs paramternek tadott elrsi tnak a rendszernkn msnak kell lennie, mivel teleptskor az apxs esetleg ppen az Apache futtathat llomnnyal megegyez knyvtrba kerlt. Amikor a configure lefutott, elindthat a make program. Ennek futtatshoz a rendszernek tartalmaznia kell egy C fordtt. make make install Ezekkel a parancsokkal a PHP fordtsa s teleptse befejezdtt, mr csak az Apache belltsra s futtatsra van szksg.

A configure nhny paramtere


Amikor lefuttattuk a configure-t, megadtunk nhny parancssori paramtert, melyek meghatroztk, milyen lehetsgekkel ruhzzuk fel a PHP-t. Ha a kibontott PHP csomag knyvtrban a kvetkez parancsot adjuk ki, a configure megadja a lehetsges paramtereket:

A PHP teleptse ./configure --help Mivel a lista rendkvl hossz, clszer elbb egy szvegfjlba irnytani, gy knyelmesebben elolvashat: ./configure --help > lehetosegek.txt Annak ellenre, hogy a fenti parancs kimenete elgg rthet, nhny fontos lehetsget meg kell emltennk mgpedig azokat, amelyek a knyv szempontjbl szmunkra rdekesek.

15

--enable-track-vars
Ez a szolgltats automatikusan ellltja szmunkra a PHP oldalakon kvlrl rkez adatokhoz tartoz asszociatv tmbket. Ezek a GET vagy POST krssel rkezett adatok, a visszarkez sti-rtkek, a kiszolgli s krnyezeti vltozk. A tmbkkel a hetedik rban foglalkozunk bvebben, a HTTP kapcsolatokat a tizenharmadik rban rszletezzk. A fenti rendkvl gyakran hasznlt configure paramter, mivel nagyon kellemes lehetsg a berkez adatok kvetsre. A PHP 4.0.2-es vltozattl kezdve mindig be van kapcsolva, gy nem kell kln megadni.

--with-gd
A --with-gd paramter engedlyezi a GD knyvtr tmogatst. Amennyiben a GD knyvtr teleptve van a rendszeren, ez a paramter lehetsget ad dinamikus GIF, JPEG vagy PNG kpek ksztsre a PHP programokbl. A dinamikus kpek ellltsrl a tizennegyedik rban runk. Ha a GD-t korbban nem az alapbellts knyvtrba teleptettk, megadhat a szoksostl eltr elrsi t is: --with-gd=/eleresi/ut/a/megfelelo/konyvtarhoz

--with-mysql
A --with-mysql engedlyezi a MySQL adatbzisok tmogatst. Ha a rendszeren a MySQL nem az alapbellts knyvtrban tallhat, megadhat a szoksostl eltr elrsi t is: --with-mysql=/eleresi/ut/a/megfelelo/konyvtarhoz Mint mr tudjuk, a PHP tmogat szmos ms adatbzisrendszert is. Az 1.2-es tblzatban ezek kzl lthatunk nhnyat, a hozzjuk tartoz configure paramterekkel.

16

2. ra

2.1. tblzat Nhny adatbzis s a hozz tartoz configure paramter


Adatbzis Adabas D
FilePro mSQL Informix iODBC OpenLink ODBC Oracle PostgreSQL Solid Sybase Sybase-CT Velocis LDAP

configure paramter --with-adabas


--with-filepro --with-msql --with-informix --with-iodbc --with-openlink --with-oracle --with-pgsql --with-solid --with-sybase --with-sybase-ct --with-velocis --with-ldap

Az Apache belltsa
Miutn sikeresen lefordtottuk az Apache-t s a PHP-t, mdostanunk kell az Apache belltsait tartalmaz httpd.conf fjlt. Ez az Apache knyvtrnak conf alknyvtrban tallhat. A kvetkez sorok hozzadsa szksges: AddType application/x-httpd-php .php .php3 AddType application/x-httpd-php-source .phps Keressnk r ezekre a sorokra a httpd.conf fjlban! Az jabb Apache kiadsokban ez mr szerepel, csak egy megjegyzsjelet kell kitrlnnk a sorok elejrl. Ezzel biztostjuk, hogy a PHP-elemz fel fogja dolgozni a .php s .php3 kiterjesztssel rendelkez fjlokat. A .php3 kiterjesztsre azrt lehet szksg, mert szmos rgebbi program ezt hasznlja, gy mdosts nlkl tovbb alkalmazhatjuk ezeket is. A .phps kiterjesztssel rendelkez fjlok PHP forrsknt kerlnek a bngszhz, ami azt jelenti, hogy a forrskd HTML formtumv alakul s a nyelvtani elemek sznkiemelssel jelennek meg, ami hasznos segtsg lehet a programok hibinak feldertsben. Ha gyfeleink miatt esetleg a hagyomnyos oldalaknl megszokott .html kiterjesztst vlasztjuk a PHP szmra, a kvetkez belltst kell alkalmaznunk: AddType application/x-httpd-php .html

A PHP teleptse Tulajdonkppen brmilyen kiterjesztshez kthetjk a PHP-feldolgozt. Az ajnlott a .php, a .html kiterjeszts azonban nem felttlenl j vlaszts, ugyanis ilyen bellts esetn minden kikldtt HTML lap thalad a PHP-elemzn, ezltal jelentsen cskkenhet a kiszolgls sebessge. Ha a PHP elreteleptve tallhat meg a kiszolgln s nincs elrsnk az Apache belltsait tartalmaz fjlhoz, ltrehozhatunk egy .htaccess nev llomnyt a sajt knyvtrunkban s abban is megadhatjuk a fenti sorokat. A .htaccess fjlok hatsa kiterjed az adott knyvtrra s annak minden alknyvtrra is. Ez a megolds azonban csak akkor mkdkpes, ha az Apache AllowOverride belltsa az adott knyvtrra a FileInfo vagy az All rtket tartalmazza. A .htaccess az alapbellts fjlnv, amit a knyvtr specilis belltsaihoz hasznlhatunk, de az adott rendszeren ms is lehet. Ezt a httpd.conf llomny AccessFileName belltsa hatrozza meg. Ez a fjl ltalban akkor is olvashat, ha nem rendelkeznk rendszergazdai jogokkal a kiszolgln. A .htaccess fjl tkletes mdja annak, hogy testreszabjuk a trhelynket, ha a kiszolgl belltfjljban nem mdosthatjuk a paramtereket. A PHP mkdst kzvetlenl azonban a php.ini szablyozza.

17

php.ini
A PHP mkdst a fordts vagy telepts utn is befolysolhatjuk, a php.ini hasznlatval. UNIX rendszereken az alapbellts knyvtr a php.ini fjl szmra a /usr/local/lib, Windows rendszereken a Windows knyvtra. Emellett a feldolgozsra kerl PHP oldal knyvtrban a munkaknyvtrban elhelyezett php.ini fjlban fellbrlhatjuk a korbban belltott rtkeket, gy akr knyvtranknt klnbz belltsokat adhatunk meg. A letlttt PHP csomag knyvtrban tallhat egy minta php.ini fjl, amely a gyri belltsokat tartalmazza. Ezek az rtkek lpnek rvnybe akkor, ha a PHP nem tall egy php.ini fjlt sem. Az alaprtkek elegendek lehetnek ahhoz, hogy a knyv pldit futtassuk, m clszer nhny mdostst elvgezni; ezeket a huszonkettedik rban trgyaljuk. A php.ini fjl belltsai egy nvbl, egy egyenlsgjelbl s egy rtkbl llnak. A szkzket a feldolgoz figyelmen kvl hagyja. Ha a PHP elreteleptve llt rendelkezsre a rendszernkn, ellenrizzk a php.ini fjlban tallhat belltsokat. Ha esetleg nem lenne jogosultsgunk a fjl mdostsra, a PHP programjaink knyvtrba helyezett sajt php.ini fjllal fellrhatjuk

18

2. ra az alapbelltst. Msik lehetsgnk, hogy ltrehozunk egy PHPRC nev krnyezeti vltozt, amely kijelli php.ini fjlunkat. A php.ini belltsait brmikor mdosthatjuk, de ha feldolgoznk Apache modulknt fut, a vltoztatsok rvnybe lptetshez jra kell indtani a webkiszolglt.

short_open_tag
A short_open_tag bellts hatrozza meg, hogy hasznlhatjuk-e a rvid <? kd ?> formt a PHP kdblokkok rsra. Ha ez ki van kapcsolva, az albbi sorok valamelyikt lthatjuk: short_open_tag = Off short_open_tag = False short_open_tag = No Ahhoz, hogy engedlyezzk ezt a belltst, a kvetkez sorok egyikt kell hasznlnunk: short_open_tag = On short_open_tag = True short_open_tag = Yes A PHP blokkok kezd- s zrelemeirl a kvetkez rban lesz sz.

Hibajelentsek belltsai
Ha hibkat keresnk programjainkban, hasznos a hibazenetek kirsa a HTML oldalba a bngsz szmra. Ez alapbelltsban bekapcsolt: display_errors = On Bellthatjuk a hibajelentsi szintet is. Ez azt jelenti, hogy mivel tbbfle hibazenettpus is rendelkezsre ll, letilthatjuk egyik vagy msik tpust, amennyiben nem szeretnnk PHP oldalaink kimenetben ltni az abba a csoportba tartoz hibkat. A hibakezels belltsval alaposabban a huszonkettedik rban foglalkozunk, addig az albbi rtkads tkletesen megfelel: error_reporting = E_ALL & ~ E_NOTICE Ezzel a PHP minden hibt jelezni fog a lehetsges problmkat jell figyelmeztetsek kivtelvel. Ezek a figyelmeztetsek megakadlyoznk nhny szoksos PHP mdszer alkalmazst, ezrt ez az alapbellts.

A PHP teleptse

19

Vltozkra vonatkoz belltsok


A PHP a GET s POST krsekbl, stikbl, kiszolgli s krnyezeti rtkekbl ltrehoz bizonyos vltozkat. Ennek mkdst is a php.ini fjlban szablyozhatjuk. A track_vars bellts azt adja meg, hogy ltrejjjenek-e asszociatv tmbk egy HTTP lekrs eredmnyeknt. Ez alapbelltsban engedlyezett, a PHP 4.0.2es vltozat ta nem is lehet kikapcsolni: track_vars = On A register_globals bellts azt hatrozza meg, hogy a HTTP lekrskor ezek a vltozk globlis vltozkknt jjjenek-e ltre. A PHP fejldsvel egyre inkbb azt javasoljk a programozknak, hogy mellzzk ennek a szolgltatsnak a hasznlatt, mivel gy rendkvl sok vltoz jhet ltre s ez tkzseket okozhat, ha nem jl vlasztjuk meg a vltozk neveit. Ennek ellenre ma a PHP programok legnagyobb rsze tbbek kztt a knyv szmos pldja is arra pt, hogy ez a bellts be van kapcsolva: register_globals = On

Segtsg!
A segtsg mindig kznl van az Interneten, klnsen a nylt forrskd programokkal kapcsolatos problmk esetn. Ezrt mieltt a levelezprogramunk Klds gombjt megnyomnnk, gondolkozzunk el egy kicsit. Akrmennyire is mkdskptelennek tnhet a teleptett rtelmeznk, belltsunk vagy programozsi megoldsunk, j eslynk van r, hogy nem vagyunk ezzel egyedl. Valaki taln mr megvlaszolta krdsnket. Ha falba tkznk, az els hely, ahol segtsget kereshetnk, a PHP hivatalos honlapja a http://www.php.net/ cmen, klnsen az ott tallhat, olvasi kiegsztsekkel elltott kziknyv: http://www.php.net/manual/. Sok segtsget s informcit tallhatunk a Zend webhelyn is: http://www.zend.com/. A magyar PHP fejlesztk a weblabor.hu webmester honlapon tallhatnak rengeteg informcit: http://weblabor.hu/php/. Itt ksztjk a magyar PHP dokumentcit is. Ha nem sikerlt megtallni a megoldst, hasznos segtsg lehet, hogy a PHP hivatalos webhelyn keresst is vgezhetnk. A tancs, ami utn kutatunk, taln egy sajtkzlemnyben, vagy egy FAQ-fjlban rejtzik. Egy msik kitn forrs a PHP Knowledge Base: http://www.faqts.com/knowledge-base/index.phtml. Keress itt is vgezhet.

20

2. ra Mg mindig sikertelenek prblkozsaink? A PHP levelezlistk kereshet archvumaira mutat hivatkozsok megtallhatak a http://www.php.net/support.php oldalon, szmos ms hivatkozssal egytt. Ezek az archvumok risi mennyisg informcit tartalmaznak a PHP kzssg legjobbjaitl. Eltlthetnk nmi idt pr kulcssz kiprblsval. Amennyiben ezek utn is meg vagyunk gyzdve arrl, hogy problmnk mg nem merlt fel korbban, j szolglatot tehetnk a PHP kzssgnek, ha felhvjuk r a figyelmet. A PHP levelezlistkra val jelentkezshez az archvumokat felsorol oldalon tallunk hivatkozsokat. A listk gyakran nagy forgalmak, de ezt ellenslyozza, hogy rendkvl sokat lehet bellk tanulni. Ha rdekldnk a PHP programozs irnt, legalbb egy ktegelt kzbests (digest) listra iratkozzunk fel. A ktegeltsg azt jelenti, hogy a listra rkez leveleket nem egyenknt, hanem naponta egy-kt levlben sszefzve kapjuk meg. Ha sikerl megtallni az rdekldsi krnknek megfelel levelezlistt a szmos lehetsg kzl, bekldhetjk oda a problmnkat. A PHP honlapjn nemzetkzi levelezlistk oldalaira mutat hivatkozsokat is tallunk. A magyar PHP levelezlista s annak archvuma a http://weblabor.hu/wl-phplista/ cmen rhet el. Mieltt elkldennk egy krdst, gyjtsk ssze a problma szempontjbl fontos informcikat, de ne rjunk tl sokat! A kvetkez elemek gyakran szksgesek: A hasznlt opercis rendszer A telepts alatt ll vagy fut PHP-vltozat szma A belltskor hasznlt configure paramterek Brmilyen configure vagy make kimenet, ami eljelezhette a teleptsi hibt Egy sszeren teljes rszlet a kdbl, ami a problmt okozza Mirt kell ilyen sok szempontot figyelembe vennnk, mieltt egy levelezlistra postznnk krdsnket? Elszr is a fejlesztsi problmk megoldsban szerzett tapasztalat elnys lehet a ksbbi munka sorn. Egy tapasztalt programoz ltalban gyorsan s hatkonyan tud problmkat megoldani. Egy alapvet krds feltevse technikai jelleg listn tbbnyire egy-kt olyan vlaszt eredmnyez, amelyben felhvjk figyelmnket, hogy erre a krdsre az archvumban megtallhat a vlasz.

A PHP teleptse Msodszor, egy levelezlista nem hasonlthat ssze egy kereskedelmi termk tmogatsi kzpontjval. Senki sem kap fizetst, hogy megvlaszolja krdseinket. Ennek ellenre lenygz szellemi erforrshoz nyjt elrst, belertve a PHP nhny fejlesztjt is. A krdsek a vlasszal egytt az archvumba kerlnek, hogy ksbb ms programozk segtsgre lehessenek. Ezrt felesleges olyan krdsek feltevse, amelyek mr tbbszr szerepeltek a listn. Ezek megfontolsa utn ne vonakodjunk krdseket kldeni a levelezlistkra. A PHP fejlesztk civilizlt, segtksz emberek s a problma felvetsvel esetleg msoknak is segthetnk egy hasonl krds megoldsban. Vgl, ha gy tnik, hogy a problma nem a mi kdunkban, hanem a PHPrtelmezprogramban tallhat, kldjnk egy hibajelentst a fejlesztknek a http://bugs.php.net/ cmen. Ha a gubanc valban j, a hibt a PHP kvetkez kiadsban tbbnyire kijavtjk.

21

sszefoglals
A PHP 4 nylt forrskd. Nylt abban az rtelemben is, hogy nem szksges egy meghatrozott kiszolglt, opercis rendszert vagy adatbzist hasznlnunk a fejlesztshez. Ebben az rban lttuk, honnan szerezhet be a PHP s ms a webhelyek szolgltatsaiban segt nylt forrskd programok. Megnztk, hogyan fordthat le a PHP Apache modulknt Linux rendszeren. Ha nem a forrskdot tltjk le a hlzatrl, hanem egy lefordtott vltozatot, akkor a csomagban rszletes informcikat tallunk a teleptssel kapcsolatban. ttekintettnk nhny configure paramtert, melyekkel a feldolgoz kpessgeit befolysolhatjuk. Tanultunk a php.ini fjlrl s nhny belltsi lehetsgrl, amit megadhatunk benne. Vgl megnztk, hol tallhatunk segtsget, ha problmink akadnak. Ezzel kszen llunk arra, hogy megbirkzzunk a PHP nyelvvel.

Krdsek s vlaszok
A teleptst Apache webkiszolglt hasznl Linux opercis rendszeren vezettk vgig. Ez azt jelenti, hogy a knyv nem megfelel ms rendszer vagy kiszolglprogram hasznlata esetn? A PHP egyik nagy erssge, hogy tbb rendszeren is kpes futni. Ha problmk addnak az adott rendszeren a PHP teleptsvel, olvassuk el a csomagban tallhat dokumentcit s a PHP kziknyv megfelel fejezett. ltalban szles kr lpsrl-lpsre lert utastsokat kapunk a teleptshez. Ha tovbbra sem sikerl megoldani a problmt, a Segtsg! cm rszben ismertetett mdszerek clravezetk lehetnek.

22

2. ra Hogyan rhetk el bngszbl a PHP llomnyok, ha a gpre teleptettk a webkiszolglt? A PHP alkalmazsok fejlesztshez s tesztelshez nem szksges, hogy szmtgpnk az Internetre legyen kapcsolva, br az les krnyezetben val ellenrzs hasznosabb lehet. Brmilyen opercis rendszert is hasznlunk, akr hlzatba kttt gpen dolgozunk, akr nem, a sajt gpnk IP-cme 127.0.0.1, neve akkor is localhost lesz. Ezrt ha a sajt gpnkn lv webkiszolgl gykrknyvtrban lv elso.php fjlt szeretnnk megnyitni, a http://localhost/elso.php cmen rhetjk el. Windows opercis rendszeren felttlenl telepteni kell a TCP/IP tmogatst, hogy ez a lehetsg rendelkezsre lljon.

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Hol rhet el a PHP kziknyv? 2. UNIX rendszeren hogyan kaphatunk bvebb informcikat a belltsi lehetsgekrl (milyen paramtereket kell tadni a configure-nak)? 3. Hogy hvjk ltalban az Apache belltsait tartalmaz fjlt? 4. Milyen sort kell az Apache belltfjlhoz adni, hogy a kiszolgl felismerje a .php kiterjesztst? 5. Mi a PHP belltsait tartalmaz fjl neve?

Feladatok
1. Teleptsk a PHP-t. Ha sikerlt, nzzk t a PHP belltfjlt s ellenrizzk a telepts helyessgt.

3.RA
Els PHP oldalunk
A PHP teleptse s belltsa utn eljtt az ideje, hogy elkezdjnk vele dolgozni. Ebben az rban elksztjk az els programunkat s elemezzk a kdot. Az ra vgre kpesek lesznk olyan oldalak ksztsre, amelyek HTML s PHP kdot is tartalmaznak. Ebben az rban a kvetkezket tanuljuk meg: Hogyan hozzunk ltre, tltsnk fel s futtassunk egy PHP programot? Hogyan vegytsnk HTML s PHP kdot egy dokumentumon bell? Hogyan tehetjk a kdunkat olvashatbb megjegyzsek hasznlatval?

24

3. ra

Els programunk
Vgjunk a kzepbe s kezdjk egy ksz PHP oldallal! A kezdshez nyissuk meg kedvenc szvegfjl-szerkesztnket! A HTML dokumentumokhoz hasonlan a PHP llomnyok is formzs nlkliek, tisztn szvegfjlok. Ez azt jelenti, hogy brmilyen szvegfjl szerkesztsre rdott programmal kszthetnk PHP llomnyokat. Ilyenek pldul a Windows Jegyzettmbje, a Simple Text vagy a BBEdit MacOS alatt, vagy a VI s az Emacs UNIX esetben. A legnpszerbb HTML-szerkesztk ltalban nyjtanak valamilyen klnleges tmogatst PHP-szerkesztshez is. Ilyenek pldul a kdsznezs, a kifejezsszerkeszt vagy a tesztel. Gpeljk be a 3.1. programot, s mentsk elso.php nven.

3.1. program Az els PHP program


1: <?php 2: print ("Hello Web!"); 3: ?> A 3.1. bra a 3.1. program kdjt mutatja a KEdit programban.

3.1. bra
Els PHP oldalunk begpelve a KEdit programban

A kiterjeszts igen fontos, mivel ez jelzi a kiszolgl szmra, hogy a fjl PHP kdot tartalmaz s futtatshoz meg kell hvni a feldolgozt. Az alapbellts PHP kiterjeszts a .php, ez azonban a kiszolgl belltsainak mdostsval megvltoztathat. Ezzel az elz rban rszletesen foglalkoztunk. Ha nem kzvetlenl a kiszolglprogramot futtat gpen dolgozunk, felteheten az FTP nev szolgltatst kell hasznlnunk arra, hogy PHP oldalunkat a kiszolglra juttassuk. A Windowsban tbbek kztt a WS-FTP hasznlhat erre a clra, MacOS hasznlata esetn a Fetch lehet hasznos.

Els PHP oldalunk Ha sikerlt elhelyeznnk a dokumentumot a kiszolgln, elrhetjk egy webbngsz segtsgvel. Ha minden rendben ment, az ablakban a program kimenett lthatjuk. A 3.2. bra az elso.php kimenett mutatja.

25

3.2. bra
Siker: a 3.1. program kimenete

3
Ha a PHP-t nem sikerlt telepteni a kiszolglra vagy nem a megfelel kiterjesztst hasznltuk, felteheten nem az elz brn lthat kimenetet kapjuk. Ebben az esetben ltalban a PHP program forrskdjt ltjuk viszont. Ezt mutatja a 3.3. bra.

3.3. bra
Kudarc: a kiterjeszts nem azonosthat

Ha ez trtnik, elszr ellenrizzk a mentett fjl kiterjesztst. A 3.3. brn lthat lapot vletlenl elso.nphp nvvel mentettk. Ha a kiterjesztssel nincs problma, ellenriznnk kell, hogy a PHP sikeresen felkerlt-e a rendszerre s hogy a kiszolglt belltottuk-e a megfelel kiterjeszts felismersre. Ezekkel a krdsekkel az elz rban foglalkoztunk rszletesen. Miutn sikerlt feltlteni s kiprblni els programunkat, kielemezhetjk az imnt begpelt kdot.

26

3. ra

PHP blokkok kezdse s befejezse


Amikor PHP oldalakat runk, tudatnunk kell a feldolgozval, mely rszeket hajtsa vgre. Ha nem adjuk meg, hogy a fjl mely rszei tartalmaznak PHP kdot, az rtelmez mindent HTML-nek tekint s vltoztats nlkl tovbbkldi a bngsz szmra. A 3.1. tblzat a PHP kd blokkjainak kijellsre szolgl elemeket sorolja fel:

3.1. tblzat PHP blokkok kezd- s zrelemei


Elnevezs Hagyomnyos
Rvid ASP stlus Script elem

Kezdelem <?php
<? <% <SCRIPT LANGUAGE="PHP">

Zrelem ?>
?> %> </SCRIPT>

A 3.1. tblzatban lthat lehetsgek kzl csak az els s az utols ll minden bellts esetn rendelkezsre. A rvid s ASP stlus elemeket engedlyezni kell a php.ini fjlban. Az elz rban trgyaltuk a bellts mdszert. A rvid kezdelemek felismerst a short_open_tag belltssal engedlyezhetjk, ha On llapotba tesszk: short_open_tag = On A rvid kezdelemek alapbelltsban engedlyezettek, ezrt nem kell szerkesztennk a php.ini fjlt, hacsak valaki elzleg ki nem kapcsolta. Az ASP stlus elemek engedlyezshez az asp_tags belltst kell bekapcsolni: asp_tags = On Ez akkor lehet hasznos, ha olyan termkkel ksztnk PHP oldalakat, amely trli a PHP blokkokat, de az ASP rszeket rintetlenl hagyja. A php.ini fjl mdostsa utn lehetsgnk van vlasztani a bekapcsolt tpusok kzl. Rajtunk mlik, hogy melyik elemet vlasztjuk, de ha XML-lel is szeretnnk dolgozni, mindenkppen a hagyomnyos formt kell alkalmaznunk s le kell tiltanunk a rvid stlust. Mivel a hagyomnyos forma minden rendszeren rendelkezsre ll, a fejlesztk programjaikban ltalban ezt alkalmazzk, gy a knyvben is ezzel fogunk tallkozni.

Els PHP oldalunk Nzzk meg, hogyan fest egy PHP fjl, amely a fent emltett formkat hasznlja az elz program kibvtseknt. Ha engedlyeztk, brmely ngy kezd- s zrelemet hasznlhatjuk a programban: <? print ("Hello Web!"); ?> <?php print ("Hello Web!"); ?> <% print ("Hello Web!"); %> <SCRIPT LANGUAGE="PHP"> print ("Hello Web!"); </SCRIPT> Ha PHP-ben egysoros kdot runk, nem kell kln sorba tennnk a kezd- s zrelemeket, illetve a programsort: <?php print("Hello Web!"); ?> Miutn megtanultuk, hogyan hatrozhatunk meg egy PHP kdblokkot, nzzk meg mg kzelebbrl a 3.1. programot.

27

A print() fggvny
A print() fggvny kirja a kapott adatokat. A legtbb esetben minden, ami a print() fggvny kimenetn megjelenik, a bngszhz kerl. A fggvnyek olyan parancsok, amelyek valamilyen mveletet vgeznek, tbbnyire attl fggen, hogy milyen adatokat kapnak. A fggvnyeknek tadott adatokat majdnem mindig zrjelbe kell tennnk a fggvny neve utn. Ebben az esetben a print() fggvnynek egy karakterlncot adtunk t. A karakterlncokat mindig (egyes vagy ketts) idzjelbe kell tenni. A fggvnyek ltalban megkvetelik, hogy zrjeleket helyezznk a nevk utn, akr kldnk adatokat szmukra, akr nem. A print() ebbl a szempontbl kivteles, mivel hvsa esetn a zrjelek elhagyhatk. Ez a print() fggvny megszokott formja, ezrt a tovbbiakban ezt alkalmazzuk.

28

3. ra A 3.1. program egyetlen sort pontosvesszvel fejeztk be. A pontosvessz tudatja a feldolgozval, hogy az utasts vget rt. JDONSG Az utasts a feldolgoznak adott parancs. ltalnossgban a PHP szmra azt jelenti, mint az rott vagy beszlt nyelvben a mondat. Az utastsokat a legtbb esetben pontosvesszvel kell lezrni, a mondatokat rsjellel. Ez all kivtelt kpeznek azok az utastsok, amelyeket ms utastsok vesznek krl, illetve azok, amelyek blokk vgn llnak. A legtbb esetben azonban az utasts vgrl lefelejtett pontosvessz megzavarja az elemzt s hibt okoz. Mivel a 3.1. programban az egyetlen megadott utasts a blokk vgn ll, a pontosvessz elhagyhat.

HTML s PHP kd egy oldalon


3.2. program PHP program HTML tartalommal
1: <html> 2: <head> 3: <title>3.2. program PHP program HTML tartalommal</title> 4: </head> 5: <body> 6: <b> 7: <?php 8: print ("Hello Web!"); 9: ?> 10: </b> 11: </body> 12: </html>

Lthat, hogy HTML kd beptse a PHP oldalakba egyszeren a HTML tartalom begpelsbl ll. A PHP feldolgoz figyelmen kvl hagy mindent a PHP nyits zrelemeken kvl. Ha a 3.2. programot megnzzk bngszvel, a Hello Web! szveget ltjuk vastagon, mint ahogy ez a 3.4. brn megfigyelhet. Ha a dokumentum forrst is megnzzk, ahogy a 3.5. bra mutatja, a kd hagyomnyos HTML dokumentumnak tnik.

Els PHP oldalunk Egy dokumentumban a HTML elemek kz tetszleges szm PHP kdblokk rhat. Br tbb kdblokkot helyezhetnk el egy dokumentumon bell, ezek egyttesen alkotnak egy programot. Brmi, amit egy megelz blokkban hatroztunk meg, (vltozk, fggvnyek vagy osztlyok) a dokumentumon bell elrhet lesz a ksbbi blokkokban is. A tbb egyttmkd, sszessgben egy nagyobb programot megvalst PHP fjlt nevezzk PHP alkalmazsnak.

29

3.4. bra
Ha a 3.2 programot megnzzk bngszvel, a Hello Web! szveget ltjuk vastagon

3.5. bra
Ha a dokumentum forrst nzzk, a kd hagyomnyos HTML dokumentumnak tnik

30

3. ra

Megjegyzsek a PHP kdokban


Az rskor tlthat programkd hat hnappal ksbb remnytelenl kusznak tnhet. Ha azonban megjegyzseket fznk a kdhoz, mikzben rjuk, a ksbbiekben sok idt takarthatunk meg magunknak s ms programozknak, akik az adott kddal fognak dolgozni. JDONSG A megjegyzsek a kdban tallhat olyan szvegrszek, amelyeket a feldolgoz figyelmen kvl hagy. Segtsgkkel olvashatbb tehetjk a programot s jegyzeteket fzhetnk hozz. A PHP egysoros megjegyzsei kt perjellel (//) vagy egy kettskereszt karakterrel (#) kezddhetnek. Az ezen jelzsek utn tallhat szveget a PHP-rtelmez mindig figyelmen kvl hagyja, a sor vagy a PHP blokk vgig. // Ez megjegyzs # Ez is megjegyzs A tbbsoros megjegyzsek egy perjelet kvet csillag karakterrel kezddnek (/*) s egy csillagot kvet perjellel (*/) fejezdnek be. /* Ez egy megjegyzs. A PHP-rtelmez ezen sorok egyikt sem fogja feldolgozni. */

sszefoglals
Mostanra rendelkezsnkre llnak azok az eszkzk, melyekkel kpesek vagyunk egy egyszer PHP program futtatsra egy megfelelen belltott kiszolgln. Ebben az rban elksztettk els PHP programunkat. Lttuk, hogyan hasznlhat egy szveges szerkeszt, hogy ltrehozzunk s mentsnk egy PHP dokumentumot. Elemeztk a ngy rendelkezsre ll blokk kezd- s zrelemet. Megtanultuk, miknt kell hasznlnunk a print() fggvnyt, hogy a bngsz szmra kimenetet kldjnk, majd sszelltottunk egy HTML s PHP kdot is tartalmaz llomnyt. Vgl tanultunk a megjegyzsekrl s arrl, hogyan pthetjk be ezeket a PHP dokumentumokba.

Els PHP oldalunk

31

Krdsek s vlaszok
Melyik a legjobb kezd- s zrelem? Ez nagyrszt sajt dntsnkn mlik. A hordozhatsg szem eltt tartsval a hagyomnyos <?php ?> megolds a legjobb dnts. A rvid kezdelemek alapesetben engedlyezettek s rendelkeznek a tmrsg elnys tulajdonsgval. Milyen szerkesztprogramokat kell elkerlni a PHP kdok ksztsekor? Ne hasznljunk olyan szvegszerkesztket, amelyek sajt formtummal rendelkeznek, mint a Microsoft Word. Ha ilyen tpus szerkesztvel mentjk szveges fjlknt az elkszlt dokumentumot, a kdban megbj rejtett karakterek biztos gondot fognak okozni. Mikor kell megjegyzseket fzni a kdokhoz? Ez is nagyrszt a programoz dntsn mlik. A rvid programokhoz nem rdemes magyarzatot fzni, mivel ezek mg hossz id utn is rthetek maradnak. Ha a program azonban akr csak egy kicsit is bonyolult, mr javasolt megjegyzsekkel bvteni. Ez hossz tvon idt takart meg szmunkra s kmli idegeinket.

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. A felhasznl bngszjvel elolvashatja-e a PHP kdot? 2. Adjuk meg a PHP hagyomnyos kezd- s zrelemeit! 3. Adjuk meg az ASP stlus kezd- s zrelemeket! 4. Adjuk meg a Script kezd- s zrelemeket! 5. Mely fggvny hasznlatos a bngsz szmra kldtt adatok kirshoz?

Feladatok
1. Gyakoroljuk a PHP oldalak elksztst, feltltst s futtatst!

II. RSZ
A PHP nyelv
4. 5. 6. 7. 8. ra Az alkotelemek ra Vezrlsi szerkezetek ra Fggvnyek ra Tmbk ra Objektumok

4. RA
Az alkotelemek
Ebben az rban mr mlyebben elmerlnk a nyelv rejtelmeiben. Az alapokkal kezdnk, gy a kezd programoznak rengeteg j informcit kell majd feldolgoznia. Aggodalomra azonban semmi ok, brmikor vissza lehet lapozni a knyvben. A lnyeg, hogy a fejezetben lertak megrtsre trekedjnk, ne csupn a memorizlsra. A gyakorlott programozknak is ajnlatos legalbbis tlapozniuk ezen ra anyagt. Az rban a kvetkezket tanuljuk meg: Mik a vltozk s hogyan hasznljuk azokat? Hogyan hozhatunk ltre vltozkat s hogyan rhetjk el azokat? Mik azok az adattpusok? Melyek a leggyakrabban hasznlt mveletek? Hogyan hozhatunk ltre kifejezseket mveletjelek hasznlatval? Hogyan hatrozhatunk meg llandkat s hogyan hasznlhatjuk azokat?

36

4. ra

Vltozk
A vltozk klnleges trolk, amiket abbl a clbl hozunk ltre, hogy rtket helyezznk el bennk. A vltozk egy dollrjelbl ($) s egy tetszlegesen vlasztott nvbl tevdnek ssze. A nv betket, szmokat s alhzs karaktereket (_) tartalmazhat (szmmal azonban nem kezddhet!), szkzket s ms olyan karaktereket, amelyek nem szmok vagy betk, nem. me nhny rvnyes vltoznv: $a; $egy_hosszabb_valtozonev; $elalszom_zzzzzzzzzzzzzz; Ne feledjk, hogy a pontosvessz (;) a PHP utasts vgt jelzi, gy az elzekben a pontosvessz nem rsze a vltozk nevnek. JDONSG A vltozk adatokat szmokat, karakterlncokat, objektumokat, tmbket vagy logikai rtkeket trolnak, tartalmuk brmikor mdosthat.

Amint ltjuk, rengeteg fle nevet adhatunk vltozinknak, br a csak szmokbl ll vltoznevek nem szokvnyosak. Vltoz ltrehozshoz (deklarlshoz, vagyis bevezetshez) egyszeren csak bele kell rni azt a programunkba. Ltrehozskor ltalban rgtn rtket is szoktunk adni a vltoznak. $szam1 = 8; $szam2 = 23; Itt kt vltozt hoztunk ltre s a hozzrendel mveletjellel (=) rtket is adtunk azoknak. Az rtkadsrl bvebben a Mveletjelek s kifejezsek cm rszben tanulunk, az ra ksbbi rszben. Miutn rtket adtunk vltozinknak, gy kezelhetjk azokat, mintha maguk lennnek az rtkek. Vagyis a fenti pldnl maradva a ltrehozs utn rt print $szam1; hatsa megegyezik a print 8; hatsval, feltve, hogy a $szam1 vltoz rtke 8 maradt.

Az alkotelemek

37

Dinamikus vltozk
Vltozt teht gy hozunk ltre, hogy egy dollrjel utn rjuk a vltoz nevt. Szokatlan, m hasznos, hogy a vltoz nevt is trolhatjuk vltozban. Teht ha az albbi mdon rtket rendelnk egy vltozhoz $felhasznalo = "Anna"; az megegyezik azzal, mintha ezt rnnk: $tarolo = "felhasznalo"; $$tarolo = "Anna"; A $tarolo vltoz a "felhasznalo" szveget tartalmazza, ezrt a $$tarolo-t gy tekinthetjk, mint egy dollrjelet, melyet egy vltoz neve kvet ($tarolo), a $tarolo viszont ismt csak egy vltoz, amit a PHP a vltoz rtkvel helyettest, vagyis "felhasznalo"-val. Teht a fenti kifejezs a $felhasznalo-val egyenrtk. Dinamikus vltozkat karakterlnc-konstanssal (llandknt meghatrozott karakterlnccal) is ltrehozhatunk. Ekkor a vltoz nevl szolgl karakterlncot kapcsos zrjelbe tesszk: ${"felhasznalonev"} = "Anna"; Ez els rnzsre nem tnik tl hasznosnak. Ha azonban a karakterlnc-sszefz mveletjellel ciklusban hasznljuk (lsd a Vezrlsi szerkezetek cm tdik rt), e mdszerrel dinamikus vltozk tucatjait hozhatjuk ltre.

A dinamikus vltozk elrse ugyangy trtnik, mint a hagyomnyos vltozk, teht a $felhasznalo = "Anna"; print $felhasznalo; azonos a $felhasznalo = "Anna"; $tarolo = "felhasznalo"; print $$tarolo; kddal, eltekintve termszetesen attl, hogy itt ltrehoztunk egy $tarolo nev vltozt, melynek rtke "felhasznalo".

38

4. ra Ha egy dinamikus vltozt egy karakterlncon bell szeretnnk kirni, az rtelmeznek nmi segtsget kell adnunk. Az albbi print utasts hatsra $felhasznalo = "Anna"; $tarolo = "felhasznalo"; print "$$tarolo"; a bngsz nem az "Anna" szveget jelenti meg, mint ahogy vrnnk, hanem kirja a dollrjelet, majd a "felhasznalo" szveget, vagyis sszessgben azt, hogy "$felhasznalo". JDONSG Ha egy vltozt ketts idzjelek kz tesznk, a PHP szolglatkszen beilleszti annak rtkt.

A mi esetnkben a PHP a $tarolo karaktersorozatot a "felhasznalo" szvegre cserlte, az els dollrjelet pedig a helyn hagyta. Annak rdekben, hogy egyrtelmv tegyk a PHP szmra, hogy a karakterlncon belli vltoz egy dinamikus vltoz rsze, kapcsos zrjelbe kell tennnk. Az albbi kdrszlet print utastsa $felhasznalo = "Anna"; $tarolo = "felhasznalo"; print "${$tarolo}"; mr az "Anna" szveget rja ki, ami a $felhasznalo nev vltoz rtke. A 4.1. pldaprogram egy PHP oldalon bell tartalmazza a korbbi programrszleteket s vltozban trolt karakterlncokat hasznl a $felhasznalo kezdeti rtknek belltsra s elrsre.

4.1. program Dinamikusan belltott s elrt vltozk


1: <html> 2: <head> 3: <title>4.1. program Dinamikusan belltott s elrt vltozk</title> 4: </head> 5: <body> 6: <?php 7: $tarolo = "felhasznalo"; 8: $$tarolo = "Anna"; 9: // lehetne egyszeren csak: 10: // $felhasznalo = "Anna"; 11: // vagy

Az alkotelemek

39

4.1. program (folytats)


12: 13: 14: 15: 16: 17: 18: 19: 20: 21: // ${"felhasznalo"} = "Anna" // persze ekkor nem kellenek dinamikus vltozk print "$felhasznalo<br>"; print $$tarolo; print "<br>"; print "${$tarolo}<br>"; print "${'felhasznalo'}<br>"; ?> </body> </html>

Hivatkozsok a vltozkra
A PHP alaprtelmezs szerint rtkadskor a vltozk rtkeit hasznlja. Ez azt jelenti, hogy ha az $egyikValtozo-t hozzrendeljk egy $masikValtozo-hoz, akkor a $masikValtozo-ba az $egyikValtozo rtknek msolata kerl. Az $egyikValtozo tartalmnak ksbbi mdostsa nincs semmifle hatssal a $masikValtozo-ra. A 4.2. pldaprogram ezt mutatja be.

4.2. program Vltozk rtk szerinti hozzrendelse


1: <html> 2: <head> 3: <title>4.2. program Vltozk rtk szerinti hozzrendelse</title> 4: </head> 5: <body> 6: <?php 7: $egyikValtozo = 42; 8: $masikValtozo = $egyikValtozo; 9: // $masikValtozo-ba $egyikValtozo tartalmnak msolata kerl 10: $egyikValtozo = 325; 11: print $masikValtozo; // kirja, hogy 42 12: ?> 13: </body> 14: </html>

40

4. ra Itt a 42 rtket adjuk az $egyikVatozo-nak, majd a $masikValtozo-hoz hozzrendeljk az $egyikValtozo-t. Ekkor a $masikValtozo-ba az $egyikValtozo rtknek msolata kerl. A print utasts igazolja ezt, mivel a bngszben a 42 jelenik meg. A PHP 4-es kiadsban ezt a viselkedsmdot megvltoztathatjuk. Kiknyszerthetjk, hogy a $masikValtozo-ba ne az $egyikValtozo rtke kerljn, hanem egy hivatkozs, amely az $egyikValtozo-ra mutat. Ezt illusztrlja a 4.3. pldaprogram.

4.3. program Vltozra mutat hivatkozs


1: <html> 2: <head> 3: <title>4.3. program Vltozra mutat hivatkozs</title> 4: </head> 5: <body> 6: <?php 7: $egyikValtozo = 42; 8: $masikValtozo = &$egyikValtozo; 9: // $masikValtozo-ba $egyikValtozo-ra mutat hivatkozs kerl 10: $egyikValtozo = 325; 11: print $masikValtozo; // kirja, hogy 325 12: ?> 13: </body> 14: </html> A 4.2. pldaprogramhoz kpest a vltozs mindssze egy karakter. Az $egyikValtozo el tett & jel gondoskodik rla, hogy az rtk msolata helyett a $masikValtozo-ba a vltozra mutat hivatkozs kerl. Ezutn a $masikValtozo elrsekor az $egyikValtozo-ra vonatkoz mveletek eredmnyt lthatjuk. Ms szavakkal: mind az $egyikValtozo, mind a $masikValtozo ugyanazt a troldobozt hasznlja, gy rtkeik mindig egyenlk. Mivel ez az eljrs kikszbli az egyik vltozbl a msikba trtn rtkmsols szksgessgt, csekly mrtkben nvelheti a teljestmnyt. Hacsak nem hasznlunk nagyon gyakran rtkadsokat, ez a teljestmnybeli nvekeds alig rezhet. A hivatkozsok a PHP 4-es vltozatban kerltek a nyelvbe.

Az alkotelemek

41

Adattpusok
A klnfle tpus adatok tbb-kevesebb helyet foglalnak a memriban, a nyelv pedig mindegyiket nmileg ms mdon kezeli. Ezrt nhny programozsi nyelv megkveteli, hogy a programoz elre meghatrozza a vltoztpust. A PHP 4 gyengn tpusos, ami azt jelenti, hogy az adattpusokat gy kezeli, mintha a tpus az adathoz rendelt kiegszt informci lenne. A PHP vegyes megkzeltst hasznl. Egyfell ez azt jelenti, hogy a vltozk rugalmasan hasznlhatk: egyszer karakterlnc, msszor esetleg szm lehet bennk. Msfell, nagyobb mret programokban zavar forrsa lehet, ha egy adott tpus vltozt vrunk egy vltozban, mikzben valami teljesen ms van benne. A 4.1. tblzat a PHP 4-ben elrhet hat fontosabb adattpust tartalmazza, rvid lerssal s pldval.

4.1. tblzat Adattpusok


Tpus Integer
Double String Boolean Object Array

Plda 5
3.234 "hello" true

Lers Egsz szm


Lebegpontos szm Karakterek sorozata, karakterlnc Logikai vltoz. rtke igaz vagy hamis (true vagy false) lehet Objektum, lsd a nyolcadik, objektumokkal foglalkoz rt Tmb, lsd a hetedik, tmbkkel foglalkoz rt

Az adattpusok kzl a tmbket s az objektumokat ksbbre hagyjuk. A vltoz tpusnak meghatrozsra a PHP 4 beptett gettype() fggvnyt hasznlhatjuk. Ha a fggvnyhvs zrjelei kz vltozt tesznk, a gettype() egy karakterlnccal tr vissza, amely a vltoz tpust adja meg. A 4.4. pldaprogram egy vltozhoz ngy klnbz tpus rtket rendel, majd meghvja a gettype() fggvnyt. A fggvnyekrl bvebben a hatodik rban, a Fggvnyek cm rszben tanulunk.

42

4. ra

4.4. program Vltoz tpusnak vizsglata


1: <html> 2: <head> 3: <title>4.4. program Vltoz tpusnak vizsglata</title> 4: </head> 5: <body> 6: <?php 7: $proba = 5; 8: print gettype( $proba ); // integer 9: print "<br>"; // j sor, hogy ne follyanak ssze a tpusnevek 10: $proba = "t"; 11: print gettype( $proba ); // string 12: print "<br>"; 13: $proba = 5.0; 14: print gettype( $proba ); // double 15: print "<br>"; 16: $proba = true; 17: print gettype( $proba ); // boolean 18: print "<br>"; 19: ?> 20: </body> 21: </html Az elbbi program a kvetkez kimenetet eredmnyezi: integer string double boolean Az integer egsz szm, vagyis olyan szm, amelyben nincs tizedesjegy (tizedespont). Knyvnk ugyan magyar nyelv, a PHP 4 azonban az angol kifejezseket hasznlja. A gettype ezrt adja meg az integer, string, double s boolean szavakat. Ugyangy az angol rsmd szerint a szm egszrszt a trtrsztl nem tizedesvessz, hanem tizedespont vlasztja el. Annak rdekben, hogy ne kvessnk elgpelsi hibkat, a knyv htralev rszben a magyarul kicsit szokatlanul cseng tizedespont kifejezst hasznljuk.

Az alkotelemek A string karakterek sorozata. Ha programunkban karakterlncokkal dolgozunk, mindig aposztrfok (') vagy macskakrmk (") kz kell azokat tennnk. A double lebegpontos szm, vagyis olyan szm, amely tartalmazhat tizedespontot. A boolean a kt logikai rtk, a true (igaz) s a false (hamis) egyikt veheti fel. A PHP-ben a 4-es vltozat eltt nem ltezett a boolean tpus. Ott is hasznlhattuk a true rtket, de azt az rtelmez egyszeren integer tpus 1-re fordtotta.

43

Tpus mdostsa a settype() segtsgvel


A PHP a vltoz tpusnak mdostsra a settype() fggvnyt biztostja. A settype()-ot gy kell hasznlnunk, hogy a megvltoztatand tpus vltozt, valamint a vltoz j tpust a zrjelek kz kell tennnk, vesszvel elvlasztva. A 4.5. pldaprogramban a 3.14-et (lebegpontos szm, vagyis double) olyan tpusokk alaktjuk, mely tpusokat ebben a fejezetben rszletesen trgyalunk.

4.5. program Vltoz tpusnak mdostsa a settype() fggvny segtsgvel


1: <html> 2: <head> 3: <title>4.5. program Vltoz tpusnak mdostsa a settype() fggvny segtsgvel</title> 4: </head> 5: <body> 6: <?php 7: $ki_tudja_milyen_tipusu = 3.14; 8: print gettype( $ki_tudja_milyen_tipusu ); // double 9: print " - $ki_tudja_milyen_tipusu<br>"; // 3.14 10: settype( $ki_tudja_milyen_tipusu, "string" ); 11: print gettype( $ki_tudja_milyen_tipusu ); // string 12: print " - $ki_tudja_milyen_tipusu<br>"; // 3.14 13: settype( $ki_tudja_milyen_tipusu, "integer" ); 14: print gettype( $ki_tudja_milyen_tipusu ); // integer 15: print " - $ki_tudja_milyen_tipusu<br>"; // 3 16: settype( $ki_tudja_milyen_tipusu, "double" ); 17: print gettype( $ki_tudja_milyen_tipusu ); // double 18: print " - $ki_tudja_milyen_tipusu<br>"; // 3.0 19: settype( $ki_tudja_milyen_tipusu, "boolean" ); 20: print gettype( $ki_tudja_milyen_tipusu ); // boolean 21: print " - $ki_tudja_milyen_tipusu<br>"; // 1

44

4. ra

4.5. program (folytats)


22: ?> 23: </body> 24: </html>

A tpusmdosts utn minden esetben a gettype() fggvnyt hasznltuk, hogy meggyzdjnk arrl, hogy a tpus mdostsa sikerlt, majd kirjuk a $ki_tudja_milyen_tipusu nev vltoz rtkt a bngszbe. Amikor a "3.14" karakterlncot egssz alaktjuk, a tizedespont utni informci elvsz. Ezrt trtnhet meg, hogy a $ki_tudja_milyen_tipusu vltoznak mg akkor is 3 az rtke, amikor jbl lebegpontos szmm alaktjuk. A vgn a $ki_tudja_milyen_tipusu vltozt logikai tpusv alaktottuk. Az ilyen talaktsoknl a 0-tl klnbz szmok rtke akrcsak a nem nulla hosszsg karakterlncok mindig true lesz. Amikor a PHP-ben kirunk egy logikai vltozt, akkor ha a vltoz rtke true, a kimeneten 1-et ltunk, mg a false rtk vltozk semmilyen kimenetet nem eredmnyeznek. gy mr rthet, hogy az utols kirats mirt eredmnyezett 1-et.

Tpus mdostsa tpustalaktssal


A vltoz neve el zrjelbe rt adattpus segtsgvel a vltoz rtknek ltalunk meghatrozott tpusv alaktott msolatt kapjuk. A lnyegi klnbsg a settype() fggvny s a tpustalakts kztt, hogy az talakts sorn az eredeti vltoz tpusa s rtke vltozatlan marad, mg a settype() alkalmazsa sorn az eredeti vltoz tpusa s rtke az j adattpus rtelmezsi tartomnyhoz idomul. A 4.6. program ezt hivatott illusztrlni.

4.6. program Vltoz tpusnak mdostsa tpustalakts segtsgvel


1: <html> 2: <head> 3: <title>4.6. program Vltoz tpusnak mdostsa tpustalakts segtsgvel</title> 4: </head> 5: <body> 6: <?php 7: $ki_tudja_milyen_tipusu = 3.14; 8: $tarolo = ( double ) $ki_tudja_milyen_tipusu; 9: print gettype( $tarolo ) ; // double 10: print " - $tarolo<br>"; // 3.14

Az alkotelemek

45

4.6. program (folytats)


11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: $tarolo = ( string ) $ki_tudja_milyen_tipusu; print gettype( $tarolo ); // string print " - $tarolo<br>"; // 3.14 $tarolo = ( integer ) $ki_tudja_milyen_tipusu; print gettype( $tarolo ); // integer print " - $tarolo<br>"; // 3 $tarolo = ( double ) $ki_tudja_milyen_tipusu; print gettype( $tarolo ); // double print " - $tarolo<br>"; // 3.14 $tarolo = ( boolean ) $ki_tudja_milyen_tipusu; print gettype( $tarolo ); // boolean print " - $tarolo<br>"; // 1 ?> </body> </html>

A $ki_tudja_milyen_tipusu vltoz tpust a program egyik pontjn sem vltoztattuk meg, az vgig lebegpontos szm marad. Csupn msolatokat hozunk ltre, amelyek az ltalunk meghatrozott tpusv alakulnak s az j rtk kerl aztn a $tarolo nev vltozba. Mivel a $ki_tudja_milyen_tipusu msolatval dolgozunk, a 4.5. pldaprogrammal ellenttben az eredeti vltozban semmilyen informcit nem vesztnk el.

Mveletjelek s kifejezsek
Most mr kpesek vagyunk adatokat helyezni vltozinkba, meghatrozhatjuk, st meg is vltoztathatjuk egy vltoz tpust. Egy programozsi nyelv azonban nem tl hasznos, ha a trolt adatokkal nem vgezhetnk mveleteket. A mveletjelek (opertorok) olyan jelek, amelyek azon mveleteket jelzik, melyek lehetv teszik, hogy egy vagy tbb rtkbl egy j rtket hozzunk ltre. Az rtket, amellyel a mveletet vgezzk, operandusnak hvjuk. JDONSG Az opertor (mveletjel) jel vagy jelsorozat, amelyet ha rtkek sszekapcsolsra hasznlunk, valamilyen mveletet vgezhetnk, amely ltalban j rtket eredmnyez. Az operandus egy rtk, amelyet a mveletjellel kapcsolatban hasznlunk. Egy mveletjelhez ltalban kt operandus tartozik.

JDONSG

46

4. ra Kapcsoljunk ssze kt operandust s hozzunk ltre egy j rtket: 4 + 5 Itt a 4 s az 5 az operandusok. Az sszead opertor (+) vgez rajtuk mveletet s ez szolgltatja a 9 rtket. A mveletjelek tbbsge kt operandus kztt helyezkedik el, br az ra ksbbi rszben ltni fogunk nhny kivtelt is. Az operandusok s mveletjelek egyttest kifejezsnek hvjuk. Annak ellenre, hogy mg a legelemibb kifejezseket is mveletjelek segtsgvel hozzuk ltre, a kifejezsnek nem kell szksgszeren opertort tartalmaznia. Valjban a PHP mindent, ami rtket hatroz meg, kifejezsnek tekint. gy az llandk, pldul az 543; vltozk, mint a $felhasznalo s a fggvnyhvsok, pldul a gettype() is kifejezsek, a 4+5 kifejezs pedig kt tovbbi kifejezsre (4 s 5) s egy opertorra bonthat. JDONSG A kifejezs a fggvnyek, rtkek s mveletjelek olyan egyttese, amely rtket hatroz meg. ltalnossgban azt mondhatjuk, hogy ha rtkknt hasznlhatunk valamit, akkor az kifejezs. Most, hogy az alapelveket tisztztuk, ideje megismerkednnk a PHP 4 alapvet mveleteivel.

Hozzrendels
Mr tallkoztunk a hozzrendel mveletjellel, valahnyszor rtket adtunk vltozinknak. A hozzrendel opertor egyetlen karakterbl ll, az egyenlsgjelbl (=). Jelentse: a mveletjel jobb oldaln ll kifejezs rtkt hozzrendeljk a bal oldali operandushoz. $nev = "Kmves Kelemen"; A $nev vltoz ekkor a "Kmves Kelemen" szveget fogja tartalmazni. rdekes mdon, ez az rtkads maga is egy kifejezs. Els ltsra gy tnik, hogy a hozzrendels csak a $nev rtkt vltoztatja meg, de valjban a kifejezs, amely a hozzrendel mveletjelbl ll, mindig a jobb oldalon ll kifejezs rtknek msolatt adja vissza. gy a print ( $nev = "Kmves Kelemen" ); utasts kirja a bngszbe, hogy "Kmves Kelemen", azon fell, hogy a "Kmves Kelemen" szveget a $nev vltozhoz rendeli.

Az alkotelemek

47

Aritmetikai mveletek
Az aritmetikai mveletek pontosan azt teszik, amit elvrunk tlk. A 4.2. tblzat a megfelel mveletjeleket sorolja fel. Az sszead mveletjel hozzadja a jobb oldali operandust a bal oldalihoz, a kivon mveletjel a jobb oldali operandust kivonja a bal oldalibl, az oszt mveletjel a bal oldali operandust elosztja a jobb oldalival, a szorz mveletjel pedig sszeszorozza a bal s a jobb oldali operandusokat. A maradkkpz (modulus) mveletjel a bal s a jobb operandus egsz osztsnak maradkt adja.

4.2. tblzat Aritmetikai mveletek


Mveletjel +
/ * %

Nv sszeads
Kivons Oszts Szorzs Maradk

Plda 10+3
10-3 10/3 10*3 10%3

rtk 13
7 3.333333333333 30 1

sszefzs
Az sszefzs jele a pont (.). Mindkt operandust karakterlncnak tekintve, a jobb oldali elemet hozzfzi a bal oldalihoz. Vagyis a "Para" . " Zita" kifejezs rtke: "Para Zita" Az elemek tpusuktl fggetlenl karakterlncknt rtkeldnek ki s az eredmny is mindig karakterlnc lesz.

Tovbbi hozzrendel mveletek


Annak ellenre, hogy valjban csak egy hozzrendel mvelet van, a PHP 4 szmos tovbbi mveletjelet biztost, amelyek a bal oldali operandust mdostjk. A mveletek az operandusokat ltalban nem vltoztatjk meg, ez all azonban a hozzrendels kivtel.

48

4. ra Az sszetett hozzrendel mveletjelek egy hagyomnyos mveletjelbl s az azt kvet egyenlsgjelbl llnak. Az sszetett mveletjelek megkmlnek minket attl, hogy kt opertort kelljen hasznlnunk s az elgpels eslyt is cskkentik. A $x = 4; $x += 4; // $x most 8 pldul egyenrtk a kvetkezvel: $x = 4; $x = $x + 4; // $x most 8 Hozzrendel mveletjelet minden aritmetikai s sszefz jelhez kapcsolhatunk. A 4.3. tblzat a leggyakoribb prostsokat tartalmazza.

4.3. tblzat Nhny sszetett hozzrendel mveletjel


Mveletjel +=
-= *= /= %= .=

Plda $x += 5
$x -= 5 $x *= 5 $x /= 5 $x %= 5 $x .= "prba"

Egyenrtk kifejezs $x = $x + 5
$x = $x - 5 $x = $x * 5 $x = $x / 5 $x = $x % 5 $x = $x . "prba"

A 4.3. tblzat minden pldjban a $x vltoz rtke vltozik meg, a jobb oldali operandusnak megfelelen.

sszehasonlts
Az sszehasonlt mveletek az operandusokon vizsglatokat vgeznek. Logikai rtkkel trnek vissza, vagyis rtkk true lesz, ha a felttelezett viszony fennll, s false, ha nem. Ez a tpus kifejezs az olyan vezrlsi szerkezetekben hasznos, mint az if s while utastsok. Ezekkel az tdik rban tallkozunk majd. Ha meg szeretnnk vizsglni, hogy az $x-ben trolt rtk kisebb-e 5-nl, a kisebb, mint jelet hasznlhatjuk: $x < 5

Az alkotelemek Ha $x rtke 3, a kifejezs rtke true, ha $x rtke 7, a kifejezs rtke false lesz. Az sszehasonlt mveletjeleket a 4.4. tblzatban tallhatjuk. $x rtke 4.

49

4.4. tblzat sszehasonlt mveletek


Mveletjel ==
!= === !== > >=

Nv egyenl
nem egyenl azonos nem azonos nagyobb, mint nagyobb, vagy egyenl

Igaz, ha a kt rtk megegyezik


a kt rtk klnbz a kt rtk s tpus megegyezik a kt rtk vagy tpus klnbz a bal oldal nagyobb a jobb oldalnl a bal oldal nagyobb a jobb oldalnl, vagy egyenl a bal oldal kisebb a jobb oldalnl a bal oldal kisebb a jobb oldalnl, vagy egyenl

Plda $x == 5
$x != 5 $x === 5 $x !== 5 $x > 4 $x >= 4

Eredmny false
true false true false true

< <=

kisebb, mint kisebb, vagy egyenl

$x < 4 $x <= 4

false true

Ezeket a mveletjeleket tbbnyire egszekkel vagy lebegpontos szmokkal hasznljuk, br az egyenlsg karakterlncok esetben is vizsglhat.

Bonyolultabb sszehasonlt kifejezsek ltrehozsa logikai mveletek segtsgvel


A logikai mveletjelek logikai rtkeken vgeznek mveleteket. A vagy opertor pldul true-val tr vissza, ha bal vagy jobb operandusa true. true || false A fenti eredmnye true.

50

4. ra Az s opertor csak akkor ad true-t, ha mindkt operandusa true. true && false A fenti rtke false. Valszntlen azonban, hogy a gyakorlatban logikai llandkon akarunk mveleteket vgezni. Sokkal tbb rtelme van, hogy kt vagy tbb kifejezst vizsgljunk meg. Pldul: ( $x > 2 ) && ( $x < 15 ) Az eredmny itt true, ha az $x-ben trolt rtk nagyobb, mint 2, de kisebb, mint 15. A zrjeleket azrt tettk be, hogy a programkd tlthatbb legyen. A 4.5. tblzat a logikai mveleteket sorolja fel.

4.5. tblzat Logikai mveletek


Mveletjel ||
or xor

Nv vagy
vagy kizr vagy

Igaz, ha a bal vagy a jobb


operandus igaz a bal vagy a jobb operandus igaz vagy a bal, vagy a jobb operandus igaz, de csak az egyikk

Plda true || false


true or false true xor true

Eredmny true
true false

&& and !

s s tagads

a bal s a jobb operandus is igaz a bal s a jobb operandus is igaz az egyetlen operandus hamis

true && false true and false !true

false false false

Mirt kell ktfle vagy s s mveletjel? A magyarzat a mveletek kirtkelsi sorrendjben rejlik, amelyrl a fejezet ksbbi rszben tanulunk.

Az alkotelemek

51

Egsz tpus vltozk rtknek nvelse s cskkentse


Amikor PHP-ben programozunk, gyakran kerlnk olyan helyzetbe, hogy egy egsz tpus vltoz rtkt kell eggyel nvelnnk vagy cskkentennk. Ez jellemzen abban az esetben fordul el, amikor egy ciklusban szmolunk valamit. Mr kt mdjt is tanultuk annak, hogyan tehetjk ezt meg. Egyrszt lehetsgnk van az sszead mveletjellel nvelni a vltoz rtkt: $x = $x + 1; // $x rtke eggyel n

De hasznlhatunk sszetett rtkad-sszead mveletjelet is: $x += 1; // $x rtke eggyel n Az eredmny mindkt esetben $x-be kerl. Mivel az ilyen tpus kifejezsek nagyon gyakoriak, ezrt a PHP (a C nyelv mintjra) biztost egy klnleges mveletet, amely lehetsget ad arra, hogy egy egsz tpus vltozhoz hozzadjunk egyet vagy kivonjunk belle egyet. A megfelel mveletjelek a nvel, illetve cskkent opertorok. Ezeknek uttagknt (poszt-inkrementl s poszt-dekrementl) s eltagknt (pre-inkrementl s pre-dekrementl) hasznlt vltozata is ltezik. Az uttagknt hasznlt nvel mveletjel a vltoz neve utn rt kt pluszjelbl ll. $x++; // $x rtke eggyel n

Ha hasonl mdon kt mnuszjelet runk a vltoz neve utn, a vltoz rtke eggyel cskken. $x-; // $x rtke eggyel cskken

Ha a nvel vagy cskkent mveletjelet feltteles kifejezsen bell hasznljuk, fontos, hogy az operandus rtke csak a felttel kirtkelse utn vltozik meg: $x = 3; $x++ < 4; // igaz

A fenti pldban $x rtke 3, amikor a 4-gyel hasonltjuk ssze, gy a kifejezs rtke igaz. Miutn az sszehasonlts megtrtnt, $x rtke eggyel n. Bizonyos krlmnyek kztt arra lehet szksg, hogy a vltoz rtke a kirtkels eltt cskkenjen vagy njn. Erre szolglnak az eltagknt hasznlt vltozatok. nmagukban ezek a mveletjelek ugyangy viselkednek, mint uttagknt alkalmazott formik, csak a kt plusz- vagy mnuszjelet ekkor a vltoz neve el kell rnunk.

52 ++$x; -$x;

4. ra // $x rtke eggyel n // $x rtke eggyel cskken

Ha ezek a mveletjelek egy nagyobb kifejezs rszei, a vltoz rtknek mdostsa a vizsglat eltt trtnik meg. $x = 3; ++$x < 4; // hamis

Ebben a kdrszletben $x rtke eggyel n, mieltt sszehasonltannk 4-gyel. Az sszehasonlts rtke false, mivel a 4 nem kisebb 4-nl.

A mveletek kirtkelsi sorrendje


Az rtelmez a kifejezseket ltalban balrl jobbra olvassa. A tbb mveletjelet tartalmaz sszetettebb kifejezseknl mr bonyolultabb a helyzet. Elszr vegynk egy egyszer esetet: 4 + 5 Itt minden tiszta s rthet, a PHP hozzadja a 4-et az 5-hz. De mi a helyzet a kvetkez esetben? 4 + 5 * 2 Itt mr egy problmval tallkozunk szembe: a kifejezs azt jelenti, hogy vedd a ngyet s az tt, add ssze ket, majd az eredmnyt szorozd meg kettvel, vagyis 18 az rtke? Esetleg azt, hogy add hozz a ngyhez az t s a kett szorzatt, vagyis az eredmny 14? Ha egyszeren balrl jobbra olvasnnk, akkor az els vltozatot kellene elfogadnunk. A PHP-ben azonban minden mveletjelhez tartozik egy elsbbsgi tnyez (priorits). Mivel a szorzs elsbbsget lvez az sszeadssal szemben, gy (iskolai tanulmnyainkkal sszhangban) a msodik vlasz a helyes megolds. Termszetesen van r lehetsg, hogy kiknyszertsk, hogy elszr az sszeads hajtdjon vgre. Erre a zrjelek hasznlata ad lehetsget: ( 4 + 5 ) * 2 Brmilyen sorrendben rtkeldjenek is ki a mveletek, ha hossz kifejezsekkel dolgozunk vagy nem vagyunk biztosak a dolgunkban, rdemes zrjeleket hasznlnunk, gy rthetbb vlik a program s megkmljk magunkat a hibakeress fradalmaitl. A 4.6. tblzatbl az ebben az rban trgyalt mveletek elsbbsgt tudhatjuk meg (cskken sorrendben).

Az alkotelemek

53

4.6. tblzat A mveletek elsbbsge cskken sorrendben.


Mveletjelek ! ++ -- (tpustalakts)
/ * % + - . < <= => > == === != !== && || = += -= /= %= .= and xor or

Mint ltjuk, az or ksbb rtkeldik ki, mint a || mveletjel, az and-del szemben pedig elsbbsget lvez a &&, gy a kisebb priorits logikai mveletjeleket hasznlva az sszetett logikai kifejezsek olvassmdjt mdosthatjuk. Ez nem felttlenl mindig j tlet. Br a kvetkez kt kifejezs egyenrtk, a msodik kifejezs knnyebben olvashat: $x || $y and $z ( $x || $y ) && $z

llandk
A vltozk rugalmas adattrolsi lehetsget nyjtanak szmunkra. Megvltoztathatjuk rtkket, st tpusukat is, brmely pillanatban. Ha azonban azt szeretnnk, hogy egy adott nv alatt trolt rtk ne vltozzon a program futsa sorn, ltrehozhatunk llandkat (konstansokat) is. Ezt a PHP beptett define() fggvnye segtsgvel tehetjk meg. Miutn az llandt ltrehoztuk, annak rtkt nem szabad (nem tudjuk) megvltoztatni. Az lland nevt, mint karakterlncot s az rtket vesszvel elvlasztva a zrjeleken bellre kell rnunk. define( "ALLANDO_NEVE", 42); Az lland rtke termszetesen lehet szm, karakterlnc vagy logikai tpus is. Az a szoks, hogy az llandk neve CSUPA NAGYBETBL ll. Az llandk neve nem tartalmaz dollrjelet, gy az llandk elrse csupn a nv lersbl ll.

54

4. ra A 4.7. pldaprogramban lthatunk egy pldt llandk elrsre s hasznlatra.

4.7. program lland ltrehozsa


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: <html> <head> <title>4.7. program lland ltrehozsa</title> </head> <body> <?php define ( "FELHASZNALO", "Virg" ); print "dvzlm ".FELHASZNALO; ?> </body> </html>

Figyeljk meg, hogy az llandnak a karakterlncba gyazsakor sszefzst kellett hasznlnunk. Ez azrt szksges, mert az rtelmez nem tudja megklnbztetni a ketts idzjelbe rt egyszer szveget az llandk nevtl.

Minden programban hasznlhat llandk


A PHP nhny beptett llandt automatikusan biztost. Ilyen pldul a __FILE__, amely az rtelmez ltal beolvasott fjl nevt tartalmazza. A __LINE__ az aktulis sor szmt tartalmazza. Ezek az llandk hibazeneteink kirsnl hasznosak. Az ppen hasznlt PHP vltozatszmt tbbek kztt a PHP_VERSION llandbl tudhatjuk meg. Ez akkor lehet elnys, ha egy program csak a PHP egy adott vltozatval futtathat.

sszefoglals
Ebben az rban vgigvettk a PHP nyelv nhny alapvet tulajdonsgt. Tanultunk a vltozkrl s arrl, hogyan rendelhetnk hozzjuk rtket. Hallottunk a dinamikus, vagyis vltoz vltozkrl. Megtanultuk azt is, hogyan kell a vltoz rtknek msolata helyett a vltozkra hivatkozni. j mveletjeleket ismertnk meg s megtanultuk, hogyan kell azokat sszetettebb kifejezsekk sszegyrni. Vgl megtanultuk, hogyan kell llandkat ltrehozni s hasznlni.

Az alkotelemek

55

Krdsek s vlaszok
Mikor kell tudnunk egy vltoz tpust? Elfordul, hogy a vltoz tpusa behatrolja, milyen mveleteket vgezhetnk vele. Pldul mieltt egy matematikai kifejezsben hasznlunk egy vltozt, megnzhetjk, hogy egyltaln egsz vagy lebegpontos szmot tartalmaz-e. Az ehhez hasonl krdsekkel kicsit ksbb, a tizenhatodik fejezetben foglalkozunk. Muszj kvetnnk a vltozk nevre vonatkoz szoksokat? A cl mindig az, hogy a program egyszeren olvashat s rthet legyen. Az olyan vltoznevek, mint az $abc12345 nem mondanak semmit a vltoz programbeli szereprl s elgpelni is knny azokat. Ezrt rdemes rvid s jellemz neveket vlasztanunk. Az $f nv, br rvid, bizonyra nem rul el semmit a vltoz szereprl. Ezt most taln nehz elhinni, de amikor egy hnap elteltvel prbljuk meg folytatni a program rst, majd megtapasztaljuk. A $fajlnev mr sokkal jobb vlaszts. Meg kell tanulnunk a mveletjelek kirtkelsi sorrendjt? Nincs semmi akadlya, hogy megtanuljuk, de tartogassuk energinkat fontosabb dolgokra. Hasznljunk zrjeleket a kifejezsekben, gy programunk jobban olvashat lesz s nem kell trdnnk a kirtkelsi sorrenddel.

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Az albbiak kzl melyek NEM lehetnek vltoznevek? $egy_felhasznalo_altal_elkuldott_ertek $44444444444xyz $xyz44444444444 $______________szamlalo______________ $az elso $fajl-nev 2. Hogyan hasznlhatjuk fel az albbi vltozt dinamikus vltoz ltrehozsra? A vltoznak adjuk a 4 rtket! Hogyan rhetjk el az j vltozt? $en_valtozom = "dinamikus"; 3. Milyen kimenetet eredmnyez az albbi programsor? print gettype("4");

56

4. ra 4. Mit r ki az albbi nhny sor? $proba_valtozo = 5.4566; settype ( $proba_valtozo, "integer"); print $proba_valtozo; 5. Az albbi sorok melyike nem tartalmaz kifejezst? 4; gettype(44); 5/12; 6. Az elz krdsben szerepl sorok melyikben van mveletjel? 7. Az albbi kifejezs milyen rtket ad vissza? 5 < 2 Milyen tpus a krdses rtk?

Feladatok
1. Ksztsnk programot, amely legalbb t klnbz vltozt tartalmaz. Adjunk nekik klnbz tpus rtkeket, majd hasznljuk a gettype() fggvnyt a vltozk tpusainak meghatrozsra. 2. Rendeljnk rtket kt vltozhoz. Hasznljuk az sszehasonlt mveleteket annak eldntsre, hogy az els vltoz rtke azonos-e a msodik vltoz rtkvel kisebb-e a msodik vltoz rtknl nagyobb-e a msodik vltoz rtknl kisebb-e a msodik vltoz rtknl vagy egyenl-e azzal rassuk ki az sszehasonltsok eredmnyt a bngszbe! Vltoztassuk meg a vltozk rtkt s futtassuk le jbl a programot!

5. RA
Vezrlsi szerkezetek
Az elz rban ltrehozott programok minden futtatskor ugyanazt az eredmnyt adtk, mindig ugyanazok az utastsok hajtdtak vgre ugyanabban a sorrendben. Ez nem biztost tl nagy teret a rugalmassgnak. Ebben az rban nhny olyan szerkezettel ismerkednk meg, melyek segtsgvel programunk alkalmazkodhat a krlmnyekhez. A kvetkezket tanuljuk meg: Hogyan hasznljuk az if szerkezetet arra, hogy bizonyos sorok csak adott felttelek teljeslse mellett hajtdjanak vgre? Hogyan adhatunk meg csak bizonyos felttelek nem teljeslse esetn vgrehajtand mveleteket? Hogyan hasznljuk a switch utastst, hogy egy kifejezs rtktl fggen hajtsunk vgre utastsokat? Hogyan ismteljk egy kdrszlet vgrehajtst a while utasts segtsgvel? Hogyan kszthetnk elegnsabb ciklusokat a for utasts segtsgvel? Hogyan lpjnk ki a ciklusokbl? Hogyan gyazzuk egymsba a ciklusokat?

58

5. ra

Elgazsok
A legtbb program feltteleket rtkel ki s azok eredmnynek megfelelen vltoztatja viselkedst. A lehetsget, hogy a PHP oldalak tartalma dinamikuss vljk, az teszi lehetv, hogy a programok kimenete bizonyos felttelektl fgghet. A legtbb programozsi nyelvhez hasonlan a PHP 4-es vltozata is biztostja erre a clra az if utastst.

Az if utasts
Az if utasts kirtkeli a zrjelek kztti kifejezst. Ha a kifejezs rtke igaz, az utastshoz tartoz programrsz vgrehajtdik. Ha a kifejezs hamis, a blokk egyszeren figyelmen kvl marad. Ez teszi lehetv a programoknak, hogy dntseket hozzanak. if ( kifejezs ) { // ha a kifejezs rtke igaz, // ez a blokk vgrehajtdik } Az 5.1. pldaprogramban csak akkor hajtdik vgre az if utni rsz, ha a kifejezs rtke igaz

5.1. program Az if utasts


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: <html> <head> <title>5.1. program Az if utasts</title> </head> <body> <?php $hangulat = "boldog"; if ( $hangulat == "boldog" ) { print "Hurr, j kedvem van!"; } ?> </body> </html>

Vezrlsi szerkezetek A $hangulat vltoz rtkt a "boldog"-gal az sszehasonlt mveletjel (==) segtsgvel hasonltottuk ssze. Ha egyeznek, a kifejezs rtke igaz, gy az if kifejezshez tartoz programblokk vgrehajtdik. Br az elbbi programban a print utastst kapcsos zrjelek kz zrtuk, ez csak akkor szksges, ha az if kifejezstl fggen tbb utastst akarunk vgrehajtani. A kvetkez kt sor gy elfogadhat: if ( $hangulat == "boldog" ) print "Hurr, j kedvem van!"; Ha a $hangulat rtkt "szomor"-ra vltoztatjuk s jbl lefuttatjuk programunkat, az if kifejezs rtke hamis lesz, gy a print utasts nem hajtdik vgre s programunk nem ad kimenetet.

59

Az if utasts else ga
Amikor az if utastst hasznljuk, gyakran szeretnnk, hogy legyen egy olyan alternatv programrsz, amely akkor hajtdik vgre, ha a vizsglt felttel nem igaz. Ezt gy rhetjk el, hogy az if utasts programrsze utn kirjuk az else kulcsszt, majd az alternatv programrszt. A sma a kvetkez: if (felttel) { // itt kvetkezik az a programrsz, amely akkor kerl // vgrehajtsra, ha a felttel rtke igaz } else { // itt pedig az a programrsz tallhat, amely akkor fut le, // ha a felttel rtke hamis } Az 5.2. pldaprogram az 5.1. pldaprogram kiegsztett vltozata. Egy olyan programblokkot tartalmaz, amely akkor hajtdik vgre, ha a $hangulat rtke nem "boldog".

5.2. program Az else ggal kiegsztett if utasts


1: <html> 2: <head> 3: <title>5.2. program Az else ggal kiegsztett if utasts</title> 4: </head>

60

5. ra

5.2. program (folytats)


5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: <body> <?php $hangulat = "szomor"; if ( $hangulat == "boldog" ) { print "Hurr, j kedvem van!"; } else { print "$hangulat vagyok, nem boldog."; } ?> </body> </html>

A pldban a $hangulat rtke "szomor", ami persze nem "boldog", gy az if utasts felttele hamis lesz, vagyis az els programrsz nem kerl vgrehajtsra. Az else-et kvet programblokk azonban lefut s a bngszbe a "szomor vagyok, nem boldog." szveg kerl. Az if utasts else gnak segtsgvel programunkban kifinomultabb dntseket hozhatunk, de egy felttel eredmnye alapjn mg gy is csak ktfle dolgot tehetnk. A PHP 4 azonban tbbre kpes: tbb kifejezs rtke alapjn sokflekpp reaglhatunk.

Az if utasts elseif ga
Mieltt az else gban alternatv kdrszt adnnk meg, tbb kifejezs rtktl fggen az if - elseif - else szerkezet segtsgvel a programmal mst s mst vgeztethetnk. A hasznland utastsforma a kvetkez: if ( felttel ) { // ez a rsz akkor fut le, ha a felttel igaz } elseif ( msik felttel ) { // ez a rsz akkor fut le, ha a msik felttel igaz, // s minden elz felttel hamis } // itt mg tetszleges szm elseif rsz kvetkezhet

Vezrlsi szerkezetek else { // ez a rsz akkor kerl vgrehajtsra, ha egyik // felttel sem volt igaz } A Perl nyelvben gyakorlattal rendelkezk figyeljenek r, hogy a kulcsszt itt elseif-nek hvjk!

61

Ha az els felttel rtke hamis, a hozz tartoz programrsz nem kerl vgrehajtsra. Ezutn a PHP megvizsglja az elseif kifejezs rtkt. Ha a kifejezs igaz, a hozz tartoz programblokk fut le. Vgl, ha egyik felttel sem igaz, az else utni rsz kerl vgrehajtsra. Annyi elseif-et rhatunk a programba, amennyi csak jlesik. St, ha nincs szksgnk else gra, vagyis olyan programrszre, amely akkor hajtdik vgre, ha egyik felttel sem igaz, akr el is hagyhatjuk. Az 5.3. pldaprogram az elzeket egszti ki egy elseif ggal.

5.3. program Egy else s elseif ggal bvtett if utasts


1: <html> 2: <head> 3: <title>5.3. program Egy else s elseif ggal bvtett if utasts</title> 4: </head> 5: <body> 6: <?php 7: $hangulat = "szomor"; 8: if ( $hangulat == "boldog" ) 9: { 10: print "Hurr, j kedvem van!"; 11: } 12: elseif ( $hangulat == "szomor" ) 13: { 14: print "Szomor vagyok."; 15: } 16: else 17: { 18: print "Sem boldog, sem szomor nem vagyok, hanem $hangulat.";

62

5. ra

5.3. program (folytats)


19: } 20: ?> 21: </body> 22: </html>

A $hangulat rtke itt "szomor". Ez nem azonos a "boldog"-gal, ezrt az els blokk nem kerl vgrehajtsra. Az elseif kifejezs a $hangulat vltoz rtkt hasonltja ssze a "szomor" szveggel. Mivel az egyenlsg fennll, ehhez a felttelhez tartoz programrsz hajtdik vgre.

A switch utasts
A switch utasts egy lehetsges mdja annak, hogy egy kdrszletet egy kifejezs rtktl fggen hajtsunk vgre. Van azonban nhny klnbsg az imnt tanult if s a switch kztt. Az if-et az elseif-fel hasznlva tbb kifejezs rtktl tehetjk fggv, hogy mi trtnjen. A switch esetben a program csak egy kifejezst vizsgl meg s annak rtktl fggen klnbz sorokat futtat. A kifejezsnek egyszer tpusnak kell lennie (szm, karakterlnc vagy logikai rtk). Az if felttele csak igaz vagy hamis lehet, a switch kifejezst akrhny rtkkel sszehasonlthatjuk. De nzzk inkbb az ltalnos szerkezetet: switch ( kifejezs ) { case rtk1: // ez trtnjen, ha kifejezs rtke rtk1 break; case rtk2: // ez trtnjen, ha kifejezs rtke rtk2 break; default: // ez trtnjen, ha a kifejezs rtke // egyik felsorolt rtkkel sem egyezett meg break; // az rdg nem alszik, jobban jrunk, ha kitesszk // ezt a felesleges break utastst } A switch utasts kifejezse gyakran egyszeren egy vltoz. A switch-hez tartoz programblokkban vannak a case cmkk. Az utnuk rt rtk kerl sszehasonltsra a switch kifejezsnek rtkvel. Ha rtkk megegyezik, a program ott folytatdik, a break utasts pedig azt eredmnyezi, hogy a program futsa a switch

Vezrlsi szerkezetek blokkja utni rszre kerl. Ha a break-et elfelejtjk, a program tlp a kvetkez case kifejezshez tartoz programrszre s azt is vgrehajtja. Ha a kifejezs rtke egyik elz rtkkel sem egyezik s a switch blokkjn bell szerepel default cmke, akkor az utna lev programrsz kerl vgrehajtsra. Ez sokszor bosszant, de nha hasznos is lehet. Vegyk a kvetkez kis pldt. switch( $hetnapja ) { case "Pntek": print "Kikapcsolni a vekkert, holnap nem kell dolgozni!<br>"; case "Htf": case "Szerda": print "Ma dleltt dolgozom<br>"; break; case "Kedd": case "Cstrtk": print "Ma dlutn dolgozom<br>"; break; case "Vasrnap": print "Bekapcsolni a vekkert!<br>"; case "Szombat": print "Hurr, szabadnap!<br>"; break; default: print "Azt hiszem ideje lenne egy j programozt s/vagy egy jobb naptrat kerteni<br>"; break; } A fenti kis program azt kzli, mikor kell mennnk dolgozni s az bresztra kezelsben is segt. A programot gy ptettk fel, hogy tbb esetben is ugyanazt a kdot kelljen vgrehajtani, gy hasznos, hogy nem adtuk meg minden case cmknl a break utastst. Elg gyakori azonban, hogy a kezd programoz elfelejti megadni a break utastst. Hasonl helyzetekben jusson esznkbe ez a plda. A case cmkvel elkezdett rszeket ne felejtsk el break utastsokkal lezrni. Ha ezt nem tesszk meg, a program a kvetkez case rszt is vgrehajtja s vgl a default utni rsz is lefut. A legtbb esetben nem ez a switch kvnatos viselkedse.

63

64

5. ra Az 5.4. pldaprogram a korbbi, if-fel megoldott pldt alaktja t a switch segtsgvel.

5.4. program A switch utasts


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:

18: 19: 20: 21:

<html> <head> <title>5.4. program A switch utasts</title> </head> <body> <?php $hangulat = "szomor"; switch ( $hangulat ) { case "boldog": print "Hurr, j kedvem van!"; break; case "szomor": print "Szomor vagyok."; break; default: prin "Sem boldog, sem szomor nem vagyok, hanem $hangulat."; } ?> </body> </html>

A $hangulat vltoznak a "szomor" rtket adtuk. A switch utasts kifejezse ez a vltoz lesz. Az els case cmke a "boldog" szveggel val egyezst vizsglja. Mivel nincs egyezs, a program a kvetkez case cmkre ugrik. A "szomor" szveg megegyezik a $hangulat vltoz pillanatnyi rtkvel, gy az ehhez tartoz programrsz fog lefutni. A programrsz vgt a break utasts jelzi.

A ?: mveletjel
A ?: ternlis (hromoperandus) mveletjel egy olyan if utastshoz hasonlt, amely rtket is kpes visszaadni. A visszaadott rtket a vizsglt felttel hatrozza meg: ( felttel ) ? rtk_ha_a_felttel_igaz : rtk_ha_a_felttel_hamis ;

Vezrlsi szerkezetek Ha a vizsglt felttel igaz, a ? s a : kzti kifejezs rtkt adja, ha hamis, akkor a : utnit. Az 5.5. pldaprogram ezt a mveletet hasznlja, hogy egy vltoz rtkt a $hangulat vltoz rtktl fggen lltsa be.

65

5.5. program A ?: mveletjel hasznlata


1: <html> 2: <head> 3: <title>5.5. program A ?: mveletjel hasznlata</title> 4: </head> 5: <body> 6: <?php 7: $hangulat = "szomor"; 8: $szoveg = ( $hangulat=="boldog" ) ? Hurr, j kedvem van!" : "$hangulat vagyok, nem boldog."; 9: print "$szoveg"; 10: ?> 11: </body> 12: </html>

A $hangulat-ot "szomor"-ra lltottuk, majd megnztk, hogy rtke "boldog"-e. Mivel ez nem igaz, a $szoveg vltoz rtke a : utni szveg lesz. Az e mveletet hasznl programokat eleinte nehz megrteni, de a mvelet hasznos lehet, ha csak kt lehetsg kzl lehet vlasztani s szeretnk tmr programot rni.

Ciklusok
Most mr lttuk, hogyan kell dntsek eredmnytl fggen klnbz programrszleteket futtatni. PHP programokkal arra is kpesek vagyunk, hogy megmondjuk, hnyszor kell lefuttatni egy adott programrszt. Erre valk a ciklusok. Segtsgkkel elrhetjk, hogy egyes programrszletek ismtldjenek. Szinte kivtel nlkl igaz, hogy egy ciklus addig fut, amg egy felttel teljesl, vagy meg nem mondjuk, hogy fejezdjn be az ismtls.

66

5. ra

A while ciklus
A while ciklus szerkezete rendkvl hasonlt az if elgazshoz: while ( felttel ) { // valamilyen tevkenysg } Amg a while felttele igaz, a hozz tartoz programrsz jbl s jbl vgrehajtdik. A programrszen bell ltalban megvltoztatunk valamit, ami hatssal lesz a while felttelre; ha ezt nem tesszk meg, a ciklusunk a vgtelensgig futni fog. Az 5.6. pldaprogram a while ciklus segtsgvel rja ki a kettes szorztblt.

5.6. program A while ciklus


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: <html> <head> <title>5.6. program A while ciklus</title> </head> <body> <?php $szamlalo = 1; while ( $szamlalo <= 12 ) { print "$szamlalo ktszerese ".($szamlalo*2)."<br>"; $szamlalo++; } ?> </body> </html>

A pldban ltrehoztuk a $szamlalo nev vltozt. A while kifejezs felttele megvizsglja, hogy ez a vltoz mekkora. Ha az rtk nem nagyobb, mint 12, a ciklus folytatdik (vagy elkezddik). A ciklusban a $szamlalo rtke s annak ktszerese kirsra kerl, majd a $szamlalo rtke eggyel n. Ez az utasts rendkvl fontos, mert ha elfelejtjk, a while felttele soha nem lesz hamis, ezrt vgtelen ciklusba kerlnk.

Vezrlsi szerkezetek

67

A do..while ciklus
A do..while ciklus kicsit hasonlt a while-hoz. A lnyegi klnbsg abban van, hogy ebben a szerkezetben elszr hajtdik vgre a kd s csak azutn rtkeldik ki a felttel: do { // vgrehajtand programrsz } while ( felttel ); A do..while ciklus felttelt tartalmaz zrjel utn mindig ki kell tenni a pontosvesszt.

Ez a ciklus akkor lehet hasznos, ha mindenkppen szeretnnk, hogy a ciklushoz tartoz programrsz mg akkor is legalbb egyszer lefusson, ha a felttel mr az els vgrehajtskor hamis. Az 5.7. pldaprogram a do..while szerkezet egy alkalmazst mutatja be. A programrsz mindig legalbb egyszer lefut.

5.7. program A do..while ciklus


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: <html> <head> <title>5.7. program A do..while ciklus</title> </head> <body> <?php $szam = 1; do { print "Vgrehajtsok szma: $szam<br>\n"; $szam++; } while ( $szam > 200 && $szam < 400 ); ?> </body> </html>

A do..while ciklus megnzi, hogy a $szam vltoz rtke 200 s 400 kztt van-e. Mivel a $szam vltoznak az 1 kezdeti rtket adtuk, gy a felttel hamis. Ennek ellenre a programblokk egyszer vgrehajtdik, mgpedig a felttel kirtkelse eltt, ezrt a bngszben egy sor kirsra kerl.

68

5. ra

A for ciklus
A for semmi jat nem nyjt a while ciklushoz kpest. A for ciklus hasznlatval azonban sokszor takarosabb, biztonsgosabb mdon kzelthetjk meg ugyanazt a problmt. Korbban az 5.6. pldaprogramban ltrehoztunk egy vltozt a while cikluson kvl, majd a while kifejezse megvizsglta ennek a vltoznak az rtkt. Vgl a vltoz rtkt a ciklus vgn eggyel nveltk. A for ciklus mindezt egyetlen sorban teszi lehetv. Ez tmrebb programot eredmnyez s ritkbban fordulhat el, hogy a vltozt elfelejtjk nvelni, ami vgtelen ciklust okoz. for ( vltoz_hozzrendelse; felttel; szmll_nvelse) { // a vgrehajtand programblokk } Az ezt megvalst egyenrtk while: vltoz_hozzrendelse; while ( felttel ) { // a vgrehajtand programblokk szmll_nvelse; } A zrjelekben lev kifejezseket pontosvesszvel kell elvlasztanunk egymstl. Az els kifejezs rendszerint egy szmllnak ad kezdeti rtkt, a msodik egy felttel, ami alapjn eldl, hogy folytatdik-e a ciklus; a harmadik egy szmllt nvel utasts. Az 5.8. pldaprogram az 5.6. pldaprogram for ciklusos megoldsa. A felttel, a szmll_nvelse s a vltoz_hozzrendelse paramterek helyre brmilyen rvnyes PHP llts rhat. A kezdk bnjanak vatosan ezzel a lehetsggel.

5.8. program A for ciklus hasznlata


1: 2: 3: 4: 5: 6: <html> <head> <title>5.8. program A for ciklus hasznlata</title> </head> <body> <?php

Vezrlsi szerkezetek

69

5.8. program (folytats)


7: for ( $szamlalo = 1; $szamlalo <= 12; $szamlalo++ ) 8: { 9: print "$szamlalo ktszerese ".( $szamlalo * 2 )."<br>"; 10: } 11: ?> 12: </body> 13: </html> Az 5.6. s az 5.8. pldaprogram kimenete teljesen azonos. A for ciklus hasznlata a programot sszefogottabb tette. Mivel a $szamlalo nev vltoz ltrehozsa s mdostsa egy sorban van, gy a ciklus egsznek logikja els ltsra vilgos. A for zrjelben az els utasts a $szamlalo vltozt egyre lltja. A feltteles kifejezs megnzi, hogy a $szamlalo rtke nem nagyobb-e, mint 12. Az utols kifejezs a $szamlalo-t eggyel nveli. Amikor a program a for ciklushoz r, megtrtnik az rtkads, majd rgtn utna a felttel kirtkelse. Ha a felttel igaz, a ciklus vgrehajtdik, majd a $szamlalo rtke eggyel n s a felttel kirtkelse jbl vgrehajtdik. A folyamat addig folytatdik, amg a felttel hamiss nem vlik.

Ciklus elhagysa a break utasts segtsgvel


A while s for ciklusok lehetsget biztostanak arra, hogy egy beptett feltteles kifejezs segtsgvel kilpjnk bellk. A break utasts lehetv teszi, hogy ms felttelektl fggen megszaktsuk egy ciklus futst. Ez j lehet pldul hibakezelskor vagy hibk megelzsekor. Az 5.9. pldaprogram egy egyszer for ciklusbl ll, amely egy nagy szmot egy egyre nvekv szmmal oszt el s a mvelet eredmnyt meg is jelenti.

5.9. program Egy for ciklus, amely a 4000-et tz, egyre nvekv szmmal osztja el
1: <html> 2: <head> 3: <title>5.9. program A for ciklus hasznlata 2.</title> 4: </head> 5: <body> 6: <?php

70

5. ra

5.9. program (folytats)


7: 8: 9: 10: 11: 12: 13: 14: for ( $szamlalo=1; $szamlalo <= 10, $szamlalo++ ) { $seged = 4000/$szamlalo; print "4000 $szamlalo rszre osztva $seged.<br>"; } ?> </body> </html>

A pldban a $szamlalo nev vltoznak az 1 kezdeti rtket adjuk. A for utasts feltteles kifejezse ellenrzi, hogy a $szamlalo nem nagyobb-e, mint 10. A ciklus belsejben a 4000-et elosztjuk a $szamlalo-val s az eredmnyt kirjuk a bngszbe. Ez elg clratrnek tnik. De mi a helyzet akkor, ha a $szamlalo rtke a felhasznltl szrmazik? A vltoz rtke lehet negatv szm vagy akr szveg is. Vegyk az els esetet: vltoztassuk meg a $szamlalo kezdrtkt 1-rl -4-re. gy a ciklusmag tdik futtatsa sorn nullval kellene osztani, ami nem elfogadhat. Az 5.10. pldaprogram ezt azzal vdi ki, hogy a ciklus futst befejezi, ha a $szamlalo vltozban a nulla rtk van.

5.10. program A break utasts hasznlata


1: <html> 2: <head> 3: <title>5.10. program A break utasts hasznlata</title> 4: </head> 5: <body> 6: <?php 7: $szamlalo = -4; 8: for ( ; $szamlalo <= 10; $szamlalo++ ) 9: { 10: if ( $szamlalo == 0 ) 11: break; 12: $seged = 4000/$szamlalo; 13: print "4000 $szamlalo rszre osztva $seged.<br>"; 14: } 15: ?> 16: </body> 17: </html>

Vezrlsi szerkezetek

71

A nullval val oszts nem eredmnyez vgzetes hibt a PHP 4ben, csak egy figyelmeztet zenet jelenik meg a bngszben. A program futsa folytatdik.

Egy if utastssal megvizsgljuk a $szamlalo rtkt. Ha nullval egyenl, azonnal kilpnk a ciklusbl; a program ekkor a for ciklus utni sorokat kezdi feldolgozni. Figyeljk meg, hogy a $szamlalo-t a cikluson kvl hoztuk ltre, hogy olyan helyzetet utnozzunk, amikor a $szamlalo rtke kvlrl szrmazik, pldul egy rlaprl vagy egy adatbzisbl. A for ciklus fejbl brmelyik kifejezs elhagyhat, de figyelnnk kell arra, hogy a pontosvesszket mindig kirjuk.

Kvetkez ismtls azonnali elkezdse a continue utasts segtsgvel


A continue utasts segtsgvel az ppen foly ismtlst befejezhetjk, mgpedig gy, hogy ez ne eredmnyezze az egsz ciklusbl val kilpst, csak a kvetkez ismtls kezdett jelentse. Az 5.10. pldban a break utasts hasznlata kicsit drasztikus volt. Az 5.11. pldaprogramban a nullval val osztst gy kerljk el, hogy kzben programunk nem lp ki az egsz ciklusbl.

5.11. program A continue utasts hasznlata


1: <html> 2: <head> 3: <title>5.11. program A continue utasts hasznlata</title> 4: </head> 5: <body> 6: <?php 7: $szamlalo = -4; 8: for ( ; $szamlalo <= 10; $szamlalo++ ) 9: { 10: if ( $szamlalo == 0 ) 11: continue; 12: $seged = 4000/$szamlalo; 13: print "4000 $szamlalo rszre osztva $seged.<br>"; 14: }

72

5. ra

5.11. program (folytats)


15: ?> 16: </body> 17: </html> Itt a break utastst continue-ra cserltk. Ha a $szamlalo rtke nullval egyenl, az ppen foly ismtls vget r, a vgrehajts pedig rgtn a kvetkezre kerl. A break s continue utastsok a ciklus logikjt bonyolultabb, a programot pedig nehezebben olvashatv teszik, gy furcsa programhibkat idzhetnek el, ezrt vatosan hasznlandk.

Egymsba gyazott ciklusok


A ciklusok trzsben is lehetnek ciklusok. Ez a lehetsg klnsen hasznos, ha futsi idben ellltott HTML tblzatokkal dolgozunk. Az 5.12. pldaprogramban kt egymsba gyazott for ciklus segtsgvel egy szorztblt runk ki a bngszbe.

5.12. program Kt for ciklus egymsba gyazsa


1: <html> 2: <head> 3: <title>5.12. program Kt for ciklus egymsba gyazsa</title> 4: </head> 5: <body> 6: <?php 7: print "<table border=1>\n"; // HTML tblzat kezdete 8: for ( $y=1; $y<=12; $y++ ) 9: { 10: print "<tr>\n"; // sor kezdete a HTML tblzatban 11: for ( $x=1; $x<=12; $x++ ) 12: { 13: print "\t<td>"; // cella kezdete 14: print ($x*$y); 15: print "</td>\n"; // cella vge 16: } 17: print "</tr>\n"; // sor vge 18: }

Vezrlsi szerkezetek

73

5.12. program (folytats)


19: 20: 21: 22: print "</table>\n"; // tblzat vge ?> </body> </html>

A kls for ciklus az $y vltoznak az 1 kezdeti rtket adja. A ciklus addig fog futni, amg a vltoz nem nagyobb 12-nl, az utols kifejezs pedig biztostja, hogy $y rtke minden ismtls utn eggyel njn. A ciklus trzse minden ismtls sorn kir egy tr (table row tblzatsor) HTML elemet, majd egy jabb for ciklus kezddik. A bels ciklus az $x vltoz rtkt a kls ciklushoz hasonlan vgigfuttatja 1-tl 12-ig. A ciklus trzsben egy td (table data tblzatcella) elemet r ki, amelybe az $x*$y rtk kerl. Az eredmny egy zlsesen formzott szorztbla lesz.

sszefoglals
Ebben az rban a vezrlsi szerkezetekrl tanultunk s arrl, hogyan segtenek minket programjaink vltozatosabb s rugalmasabb ttelben. A legtbb megtanult szerkezet jbl s jbl meg fog jelenni a knyv htralev rszben. Megtanultuk, hogyan hozzunk ltre if utastsokat, hogyan egsztsk ki azokat elseif s else gakkal. Hallottunk arrl, hogyan hasznljuk a switch utastst, hogy egy kifejezs adott rtkei esetn ms s ms trtnjen. Tanultunk a ciklusokrl, pontosabban a while s a for ciklusokrl, s arrl, hogy a break s a continue utastsok segtsgvel hogyan lphetnk ki vgleg a ciklusbl, illetve hogyan hagyhatunk ki egy-egy ismtlst. Vgl megtanultuk, hogyan kell ciklusokat egymsba gyazni s erre gyakorlati pldt is lttunk.

Krdsek s vlaszok
A vezrlsi szerkezetek feltteles kifejezseinek mindenkppen logikai rtket kell adniuk? Vgs soron igen, br a feltteles kifejezseknl a kirtkels szempontjbl minden, ami nulla, res karakterlnc vagy nem meghatrozott vltoz, false-nak, minden egyb true-nak szmt. A vezrlsi szerkezetekhez tartoz programblokkot mindig kapcsos zrjelbe kell tenni? Ha a programblokk csak egy utastsbl ll, a kapcsos zrjel elhagyhat, de ezt tenni nem clszer, mert ha a programblokkot j utastssal egsztjk ki, vletlenl hibkat idzhetnk el.

74

5. ra Ez az ra bemutatta az sszes ciklust? Nem, a hetedik, tmbkkel foglalkoz rban tallkozunk mg a foreach ciklussal is, melynek segtsgvel egy tmb elemein haladhatunk vgig.

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Hogyan hasznlnnk az if vezrlsi szerkezetet olyan program rsra, hogy ha az $eletkor vltoz rtke 18 s 35 kztt van, az "zenet fiataloknak" szveget rja ki? Ha az $eletkor rtke brmi ms, az "ltalnos zenet" szveg jelenjen meg a bngszben. 2. Hogyan egszthetnnk ki az els krdsbeli programunkat gy, hogy az "zenet gyerekeknek" jelenjen meg akkor, ha az $eletkor vltoz rtke 1 s 17 kztt van? 3. Hogyan ksztennk egy while ciklust, amely kirja az 1 s 49 kztti pratlan szmokat? 4. Hogyan valstannk meg az elz krdsbeli programot for ciklus segtsgvel?

Feladatok
1. Nzzk vgig a vezrlsi szerkezetek utastsformjt! Gondoljuk vgig, hogyan lehetnek ezek a szerkezetek a segtsgnkre! 2. Nzzk meg a ?: mveletet! Miben klnbzik ez a tbbi vezrlsi szerkezettl? Mikor lehet hasznos?

6. RA
Fggvnyek
A fggvny a jl szervezett program lelke, mert a programot knnyen olvashatv s jrahasznosthatv teszi. Fggvnyek nlkl a nagy programok kezelhetetlenek lennnek. Ebben az rban a fggvnyeket tanulmnyozzuk s mutatunk r nhny pldt, hogyan kmlhetnek meg minket az ismtldsekbl add pluszmunktl. Az rban a kvetkezket tanuljuk meg: Hogyan hozhatunk ltre fggvnyeket? Hogyan adjunk t a fggvnyeinknek rtkeket s hogyan kapjuk meg tlk az eredmnyt? Hogyan hvjunk meg fggvnyeket dinamikusan, vltozban trolt karakterlnc segtsgvel? Hogyan rjk el a fggvnyekbl a globlis vltozkat? Hogyan rjk el, hogy fggvnyeinknek emlkezete legyen? Hogyan adjunk t a fggvnyeknek hivatkozsokat?

76

6. ra

Mit neveznk fggvnynek?


A fggvnyt egy gpnek tekinthetjk. A gp a bele tlttt nyersanyagokkal addig dolgozik, amg a kvnt termket el nem lltja vagy el nem ri kitztt cljt. A fggvny rtkeket vesz t tlnk, feldolgozza azokat s vgez velk valamit (pldul kirja az eredmnyt a bngszbe) vagy visszaad egy rtket, esetleg mindkettt. Ha a kedves Olvasnak egy stemnyt kell csinlnia, maga sti meg. De ha tbb ezret, akkor esetleg kszt vagy beszerez egy stemnyst gpezetet. Hasonlkpp, amikor elhatrozzuk, hogy fggvnyt runk, a legfontosabb szempont, amit mrlegelnnk kell, az, hogy az ismtldsek cskkentsvel akkorv zsugorodike a program, hogy rvidebb lesz a fggvny hasznlatval. A fggvny valjban egy zrt, nll kdrszlet, melyet programunkbl meghvhatunk. Amikor meghvjuk, a fggvny trzse lefut. A fggvnynek feldolgozs cljbl rtkeket adhatunk t. Amikor a fggvny vget r, a hvnak egy rtket ad vissza. JDONSG A fggvny olyan kdrszlet, amely nem kzvetlenl hajtdik vgre, hanem a programbl hvhatjuk meg: onnan, ahol pp szksg van r. A fggvnyek lehetnek beptettek vagy felhasznl ltal megadottak. Mkdskhz szksgk lehet informcikra s tbbnyire rtket adnak vissza.

Fggvnyek hvsa
Ktfle fggvny ltezik: a nyelvbe beptett fggvny s az ltalunk ltrehozott fggvny. A PHP 4-ben rengeteg beptett fggvny van. A knyv legels PHP oldala egyetlen fggvnyhvsbl llt: print ("Hello Web!"); A print abbl a szempontbl nem jellegzetes fggvny, hogy paramtereit nem kell zrjelbe tenni. A print ("Hello Web!"); s print "Hello Web!"; egyarnt helyes megoldsok. Ez egy klnleges fggvny. Szinte az sszes tbbi fggvnynl ktelez a zrjel; akr kell paramtert tadnunk, akr nem.

Fggvnyek A fenti pldban a print() fggvnyt a "Hello Web!" szvegparamterrel hvtuk meg. A program a karakterlnc kirst hajtja vgre. A fggvnyhvs egy fggvnynvbl (ebben az esetben ez a print) s az utna tett zrjelekbl ll. Ha a fggvnynek informcit szeretnnk tadni, azt a fggvny utni zrjelbe tesszk. Az informcit, amit ily mdon adunk t a fggvnynek, paramternek hvjuk. Nhny fggvnynek tbb paramtert kell tadni. A paramtereket vesszvel vlasztjuk el. JDONSG A paramter a fggvnynek tadott rtk. A paramtereket a fggvnyhvs zrjeln bellre kell rnunk. Ha tbb paramtert kell tadnunk, az egyes paramtereket vesszvel kell elvlasztanunk egymstl. A paramterek a fggvnyeken bell helyi (loklis) vltozknt rhetk el. valamilyen_fuggveny ( $elso_parameter, $masodik_parameter ); A print() abbl a szempontbl tipikus fggvny, hogy van visszatrsi rtke. A legtbb fggvny, ha nincs rtelmes visszatrsi rtke, informcit ad arrl, hogy munkjt sikeresen befejezte-e. A print() visszatrsi rtke logikai tpus (true, ha sikeres volt). Az abs() fggvny pldul egy szm tpus paramtert vr s a paramter abszoltrtkt adja vissza. Prbljuk is ki a 6.1. pldaprogrammal!

77

6.1. program A beptett abs() fggvny hasznlata


1: <html> 2: <head> 3: <title>6.1. program A beptett abs() fggvny hasznlata</title> 4: </head> 5: <body> 6: <?php 7: $szam = -321; 8: $ujszam = abs( $szam ); 9: print $ujszam; // kirja, hogy "321" 10: ?> 11: </body> 12: </html>

78

6. ra Ebben a pldban a $szam nev vltozhoz a -321-es rtket rendeltk, majd tadtuk az abs() fggvnynek, amely elvgzi a szksges szmtsokat s visszaadja az eredmnyt. Ezt az j rtket rendeljk az $ujszam nev vltozhoz s kirjuk az eredmnyt. A feladatot megoldhattuk volna segdvltozk segtsge nlkl is, az abs() fggvnyt adva kzvetlenl a print() paramtereknt: print( abs( -321 ) ); A felhasznl ltal megrt fggvnyeket teljesen hasonl mdon kell meghvnunk.

Fggvnyek ltrehozsa
Fggvnyt a function kulcssz segtsgvel hozhatunk ltre: funcion valamilyen_fuggveny( $parameter1, $parameter2 ) { // itt van a fggvny trzse } A function kulcsszt a fggvny neve kveti, majd egy zrjelpr. Ha a fggvny paramtereket ignyel, a zrjelbe vesszvel elvlasztott vltozkat kell tenni. A vltozk rtkei a fggvnyhvskor tadott paramterek lesznek. A zrjelprt akkor is ki kell rni, ha a fggvny nem vesz t paramtereket. A 6.2. pldaprogram egy fggvnyt hoz ltre.

6.2. program Fggvny ltrehozsa


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: <html> <head> <title>6.2. program Fggvny ltrehozsa</title> </head> <body> <?php function nagyHello() { print "<h1>HELLO!</h1>"; } nagyHello(); ?> </body> </html>

Fggvnyek A fenti program egyszeren kirja a "HELLO" szveget egy <H1> HTML elemben. A programban egy olyan nagyHello() nev fggvnyt hoztunk ltre, amely nem vesz t paramtereket. Ezrt hagytuk resen a zrjelprt. Br a nagyHello() mkd fggvny, mgsem tl hasznos. A 6.3. pldaprogramban olyan fggvnyt lthatunk, amely egy paramtert fogad s valami hasznosat csinl vele.

79

6.3. program Egy paramtert vr fggvny ltrehozsa


1: <html> 2: <head> 3: <title>6.3. program Egy paramtert vr fggvny ltrehozsa</title> 4: </head> 5: <body> 6: <?php 7: function sorKiir( $sor ) 8: { 9: print ("$sor<br>\n"); 10: } 11: sorKiir("Ez egy sor"); 12: sorKiir("Ez mr egy msik sor"); 13: sorKiir("Ez megint egy j sor"); 14: ?> 15: </body> 16: </html>

6.1. bra
Fggvny, amely egy karakterlncot, majd egy <br> HTML elemet r ki.

80

6. ra A 6.3. pldaprogram kimenett a 6.1. brn lthatjuk. A sorKiir() fggvny egy karakterlncot vr, ezrt tettk a $sor nev vltozt a zrjelbe. Amit a sorKiir() fggvny zrjelei kz tesznk, az kerl a $sor nev vltozba. A fggvny trzsben kirjuk a $sor nev vltozt, majd egy <br> elemet s egy jsor karaktert (hogy a HTML kd is olvashat legyen, ne csak a kimenet). Ha most ki szeretnnk rni egy sort a bngszbe, akkor meghvhatjuk a sorKiir() fggvnyt, ahelyett, hogy a print() fggvnnyel oldannk meg a problmt, gy nem kell a sorvgi jeleket minden sor kirsakor begpelnnk.

Fggvnyek visszatrsi rtke


A fggvnyeknek visszatrsi rtke is lehet, ehhez a return utastsra van szksg. A return befejezi a fggvny futtatst s az utna rt kifejezst kldi vissza a hvnak. A 6.4. pldaprogramban ltrehozunk egy fggvnyt, amely kt szm sszegvel tr vissza.

6.4. program Visszatrsi rtkkel rendelkez fggvny


1: <html> 2: <head> 3: <title>6.4. program Visszatrsi rtkkel rendelkez fggvny</title> 4: </head> 5: <body> 6: <?php 7: function osszead( $elsoszam, $masodikszam ) 8: { 9: $eredmeny = $elsoszam + $masodikszam; 10: return $eredmeny; 11: } 12: print osszead(3,5); // kirja, hogy "8" 13: ?> 14: </body> 15: </html>

Fggvnyek A 6.4. pldaprogram a 8-as szmot rja ki. Az osszead() fggvnyt kt paramterrel kell meghvni (itt a kt paramter a 3 s az 5 volt). Ezek az $elsoszam s a $masodikszam nev vltozkban troldnak. Vrhatan az osszead() fggvny e kt vltoz eredmnyt adja ssze s trolja az $eredmeny nev vltozban. Az $eredmeny nev segdvltoz hasznlatt kikszblhetjk: function osszead( $elsoszam, $masodikszam ) { return ( $elsoszam + $masodikszam ); } A return segtsgvel rtket s objektumot is visszaadhatunk, vagy esetleg semmit. Ha semmit sem adunk meg a return utn, az csak a fggvny futtatsnak befejezst eredmnyezi. A visszatrsi rtk tadsnak mdja tbbfle lehet. Az rtk lehet elre begetett return 4; de lehet kifejezs eredmnye return ( $a / $b ); vagy akr egy msik fggvny visszatrsi rtke is: return ( masik_fuggveny( $parameter ) );

81

Dinamikus fggvnyhvsok
Lehetsgnk van r, hogy karakterlncba tegyk egy fggvny nevt s ezt a vltozt pontosan gy tekintsk, mint ha maga a fggvny neve lenne. Ezt a 6.5. pldaprogramon keresztl prblhatjuk ki.

6.5. program Dinamikus fggvnyhvs


1: 2: 3: 4: 5: 6: <html> <head> <title>6.5. program Dinamikus fggvnyhvs</title> </head> <body> <?php

82

6. ra

6.5. program (folytats)


7: 8: 9: 10: 11: 12: 13: 14: 15: function koszon() { print "J napot!<br>"; } $fuggveny_tarolo = "koszon"; $fuggveny_tarolo(); ?> </body> </html>

Itt a $fuggveny_tarolo vltozhoz a koszon() fggvny nevvel azonos karakterlncot rendeltnk. Ha ezt megtettk, a vltozt arra hasznlhatjuk, hogy meghvja neknk a koszon() fggvnyt, csupn zrjeleket kell tennnk a vltoz neve utn. Mirt j ez? A fenti pldban csak mg tbb munkt csinltunk magunknak azzal, hogy a "koszon" karakterlncot rendeltk a $fuggveny_tarolo nev vltozhoz. A dinamikus fggvnyhvs akkor igazn hasznos, ha a program folyst bizonyos krlmnyektl fggen vltoztatni szeretnnk. Pldul szeretnnk mst s mst csinlni egy URL-krs paramtertl fggen. Ezt a paramtert feldolgozhatjuk s rtktl fggen ms s ms fggvnyt hvhatunk meg. A PHP beptett fggvnyei mg hasznosabb teszik ezt a lehetsget. Az array_walk() fggvny pldul egy karakterlncot hasznl arra, hogy a tmb minden elemre meghvja a fggvnyt. Az array_walk() alkalmazsra a tizenhatodik rban lthatunk pldt.

Vltozk hatkre
A fggvnyben hasznlt vltozk az adott fggvnyre nzve helyiek maradnak. Ms szavakkal: a vltoz a fggvnyen kvlrl vagy ms fggvnyekbl nem lesz elrhet. Nagyobb projektek esetn ez megvhat minket attl, hogy vletlenl kt fggvny fellrja azonos nev vltozik tartalmt. A 6.6. pldaprogramban ltrehozunk egy vltozt a fggvnyen bell, majd megprbljuk kiratni a fggvnyen kvl.

Fggvnyek

83

6.6. program Vltozk hatkre: A fggvnyen bell ltrehozott vltoz a fggvnyen kvlrl nem elrhet
1: <html> 2: <head> 3: <title>6.6. program Vltozk hatkre: A fggvnyen bell ltrehozott vltoz a fggvnyen kvlrl nem elrhet</title> 4: </head> 5: <body> 6: <?php 7: function proba() 8: { 9: $probavaltozo = "Ez egy proba valtozo"; 10: } 11: print "proba valtozo: $probavaltozo<br>"; 12: ?> 13: </body> 14: </html>

6.2 bra
Ksrlet fggvnyen belli vltozra hivatkozsra.

A 6.6. pldaprogram kimenett a 6.2. brn lthatjuk. A $probavaltozo rtke nem rdik ki. Ez annak a kvetkezmnye, hogy ilyen nev vltoz a proba() nev fggvnyen kvl nem ltezik. Figyeljk meg, hogy a nem ltez vltozra trtn hivatkozs nem eredmnyez hibt. Hasonlkpp, a fggvnyen kvl meghatrozott vltoz nem rhet el automatikusan a fggvnyen bellrl.

84

6. ra

Hozzfrs vltozkhoz a global kulcssz segtsgvel


Alaprtelmezs szerint a fggvnyeken bellrl nem rhetjk el a mshol meghatrozott vltozkat. Ha mgis megprbljuk ezeket hasznlni, akkor helyi vltozt fogunk ltrehozni vagy elrni. Prbljuk ki ezt a 6.7. pldaprogrammal:

6.7. program A fggvnyen kvl meghatrozott vltozk a fggvnyen bell alaprtelmezs szerint nem elrhetk
1: <html> 2: <head> 3: <title>6.7. program A fggvnyen kvl meghatrozott vltozk a fggvnyen bell alaprtelmezs szerint nem elrhetk</title> 5: </head> 6: <body> 7: <?php 8: $elet = 42; 9: function eletErtelme() 10: { 11: print "Az let rtelme: $elet<br>"; 12: } 13: eletErtelme(); 14: ?> 15: </body> 16: </html>

6.3. bra
Globlis vltoz elrsi ksrlete fggvnyen bellrl

Fggvnyek A 6.7. pldaprogram kimenett a 6.3. brn lthatjuk. Amint azt vrtuk, az eletErtelme() fggvny nem tudta elrni az $elet vltozt; gy az $elet a fggvnyen bell res. Ezt lthatjuk, amikor a fggvny kirja a vltoz rtkt. Mindent figyelembe vve ez egy j dolog. Megmenekltnk az azonos nev vltozk tkzstl s a fggvny paramtert ignyelhet, ha meg szeretne tudni valamit a klvilg-rl. Esetenknt azonban egy-egy fontos globlis (fggvnyen kvli) vltozt anlkl szeretnnk elrni, hogy azt paramterknt t kellene adnunk. Ez az a helyzet, ahol a global kulcssznak ltjogosultsga van. A 6.8. pldaprogram a global kulcsszval lltja vissza a vilg rendjt.

85

6.8. program Globlis vltoz elrse a global kulcssz segtsgvel


1: <html> 2: <head> 3: <title>6.8. program Globlis vltoz elrse a global kulcssz segtsgvel</title> 4: </head> 5: <body> 6: <?php 7: $elet=42; 8: function eletErtelme() 9: { 10: global $elet; 11: print "Az let rtelme: $elet<br>"; 12: } 13: eletErtelme(); 14: ?> 15: </body> 16: </html>

6.4. bra
Globlis vltoz fggvnybl trtn sikeres elrse a global kulcssz segtsgvel

86

6. ra A 6.8. pldaprogram kimenett a 6.4. brn lthatjuk. Miutn az eletErtelme() fggvnyben az $elet vltoz el a global kulcsszt tesszk, a fggvnyen bell a kls, globlis $elet vltozt rhetjk el. Minden fggvnyben, amely globlis vltozt szeretne elrni, hasznlnunk kell a global kulcsszt. Legynk vatosak! Ha most az $elet nev vltozt a fggvnyen bell megvltoztatjuk, annak a program egszre hatsa lesz. A fggvnynek tadott paramter ltalban valamilyen rtk msolata; a paramter megvltoztatsnak a fggvny vge utn semmilyen hatsa nincs. Ha azonban egy globlis vltoz rtkt vltoztatjuk meg egy fggvnyen bell, akkor az eredeti vltozt vltoztattuk meg s nem egy msolatot. Ezrt a global kulcsszt lehetleg minl kevesebbszer hasznljuk.

llapot megrzse a fggvnyhvsok kztt a static kulcssz segtsgvel


A fggvnyen belli vltozknak egszben vve rvid, de boldog letk van. Ltrejnnek pldul akkor, amikor a szamozottCimsor() fggvnyt meghvjuk s eltnnek, amikor a fggvny futsa befejezdik. Tulajdonkppen ennek gy is kell lennie. A lehet legjobb gy felpteni egy programot, hogy az fggetlen s kis tuds fggvnyekbl lljon. Esetenknt azonban jl jnne, ha egy fggvnynek lehetne valamilyen kezdetleges memrija. Tegyk fel pldul, hogy tudni szeretnnk, hnyszor fut le egy adott fggvny. Mirt? Pldnkban a fggvny clja szmozott cmsor ksztse, ami egy dinamikusan ltrejv dokumentcit eredmnyez. Itt persze hasznlhatnnk a global kulcsszrl jonnan szerzett tudsunkat. Ennek alapjn a 6.9. pldaprogramhoz hasonlt rhatnnk.

6.9. program Vltoz rtknek fggvnyhvsok kzti megrzse a global kulcssz segtsgvel
1: <html> 2: <head> 3: <title>6.9. program Vltoz rtknek fggvnyhvsok kzti megrzse a global kulcssz segtsgvel</title> 4: </head> 5: <body> 6: <?php

Fggvnyek

87

6.9. program (folytats)


7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: $fvHivasokSzama = 0; function szamozottCimsor( $cimszoveg ) { global $fvHivasokSzama; $fvHivasokSzama++; print "<h1>$fvHivasokSzama. $cimszoveg</h1>"; } szamozottCimsor("Alkatrszek"); print("Az alkatrszek szles skljt gyrtjuk<p>"); szamozottCimsor("Mtyrk"); print("A legjobbak a vilgon<p>"); ?> </body> </html>

6.5. bra
A fggvnyhvsok szmnak nyomon kvetse a global kulcssz hasznlatval

Ez gy mkdik, ahogy azt vrtuk. Ltrehoztuk a $fvHivasokSzama nev vltozt a szamozottCimsor() fggvnyen kvl. A vltozt a fggvny szmra a global kulcssz segtsgvel tettk elrhetv. A 6.9. pldaprogram kimenett a 6.5. brn lthatjuk. Valahnyszor meghvjuk az szamozottCimsor() nev fggvnyt, a $fvHivasokSzama vltoz rtke eggyel n, majd a megnvelt rtkkel a cmsort teljess tesszk. Ez nem igazn elegns megolds. A global kulcsszt hasznl fggvnyek nem fggetlenek, nem tekinthetk nll programrsznek. Ha a kdot olvassuk vagy jrahasznostjuk, figyelnnk kell az rintett globlis vltozkra. Ez az a pont, ahol a static kulcssz hasznos lehet. Ha egy fggvnyen bell egy vltozt

88

6. ra a static kulcsszval hozunk ltre, a vltoz az adott fggvnyre nzve helyi marad. Msrszt a fggvny hvsrl hvsra emlkszik a vltoz rtkre. A 6.10. pldaprogram a 6.9. pldaprogram static kulcsszt hasznl vltozata.

6.10. program Fggvnyhvsok kztti llapot megrzse a static kulcssz hasznlatval


1: <html> 2: <head> 3: <title>6.10. program Fggvnyhvsok kztti llapot megrzse a static kulcssz hasznlatval</title> 4: </head> 5: <body> 6: <?php 7: function szamozottCimsor( $cimszoveg ) 8: { 9: static $fvHivasokSzama = 0; 10: $fvHivasokSzama++; 11: print "<h1>$fvHivasokSzama. $cimszoveg</h1>"; 12: } 13: szamozottCimsor("Alkatrszek"); 14: print("Az alkatrszek szles skljt gyrtjuk<p>"); 15: szamozottCimsor("Mtyrk"); 16: print("A legjobbak a vilgon<p>"); 17: ?> 18: </body> 19: </html>

A szamozottCimsor() fggvny gy teljesen fggetlen lett. Amikor a fggvnyt elszr hvjuk meg, a $fvHivasokSzama nev vltoz kezdeti rtket is kap. Ezt a hozzrendelst a fggvny tovbbi meghvsainl figyelmen kvl hagyja a PHP, ehelyett az elz futtatskor megrztt rtket kapjuk vissza. gy a szamozottCimsor() fggvnyt mr beilleszthetjk ms programokba s nem kell aggdnunk a globlis vltozk miatt. Br a 6.10. pldaprogram kimenete teljesen megegyezik a 6.9. pldaprogramval, a programot elegnsabb s hordozhatbb tettk. Gondoljunk bele pldul, mi trtnne akkor, ha a fggvny 6.9. pldaprogrambeli vltozatt egy olyan programba illesztennk bele, amelyben van egy $fvHivasokSzama nev vltoz.

Fggvnyek

89

Paramterek tovbbi tulajdonsgai


Mr lttuk, hogyan kell fggvnyeknek paramtereket tadni, de van mg nhny hasznos dolog, amirl mg nem beszltnk. Ebben a rszben megtanuljuk, miknt lehet a fggvnyparamtereknek alaprtelmezett rtket adni s megtanuljuk azt is, hogyan kell vltozinkra mutat hivatkozst tadni a vltoz rtknek msolata helyett.

Paramterek alaprtelmezett rtke


A PHP nyelv remek lehetsget biztost szmunkra rugalmas fggvnyek kialaktshoz. Eddig azt mondtuk, hogy a fggvnyek tbbsge paramtert ignyel. Nhny paramtert elhagyhatv tve fggvnyeink rugalmasabb vlnak. A 6.11. pldaprogramban ltrehozunk egy hasznos kis fggvnyt, amely egy karakterlncot egy HTML font elembe zr. A fggvny hasznljnak megadjuk a lehetsget, hogy megvltoztathassa a font elem size tulajdonsgt, ezrt a karakterlnc mell kell egy $meret nev paramter is.

6.11. program Kt paramtert ignyl fggvny


1: <html> 2: <head> 3: <title>6.11. program Kt paramtert ignyl fggvny</title> 4: </head> 5: <body> 6: <?php 7: function meretez( $szoveg, $meret ) 8: { 9: print "<font size=\"$meret\" face=\"Helvetica,Arial,Sans-Serif\">$szoveg</font>"; 10: } 11: meretez("Egy cmsor<br>",5); 12: meretez("szveg<br>",3); 13: meretez("jabb szveg<BR>",3); 14: meretez("mg tbb szveg<BR>",3); 15: ?> 16: </body> 17: </html>

90

6. ra

6.6. bra
Fggvny, amely formzott karakterlncokat r ki a bngszbe

A 6.11. pldaprogram kimenett a 6.6. brn lthatjuk. Fggvnynk ugyan hasznos, de valjban a $meret nev paramter majdnem mindig 3. Ha kezdrtket rendelnk ehhez a paramterhez, akkor az elhagyhat lesz. gy ha a fggvnyhvsban nem adunk rtket ennek a paramternek, akkor az ltalunk meghatrozott rtket fogja felvenni. A 6.12. pldaprogram ennek a mdszernek a segtsgvel teszi a $meret paramtert elhagyhatv.

6.12. program Fggvny elhagyhat paramterrel


1: <html> 2: <head> 3: <title>6.12. program Fggvny elhagyhat paramterrel</title> 4: </head> 5: <body> 6: <?php 7: function meretez( $szoveg, $meret=3 ) 8: { 9: print "<font size=\"$meret\" face=\"Helvetica, Arial,Sans-Serif\">$szoveg</font>"; 10: } 11: meretez("Egy cmsor<br>",5); 12: meretez("szveg<br>"); 13: meretez("jabb szveg<BR>"); 14: meretez("mg tbb szveg<BR>"); 15: ?> 16: </body> 17: </html>

Fggvnyek Ha a meretez() fggvnynek van msodik paramtere, akkor a $meret nev vltozt ez fogja meghatrozni. Ha a fggvnyhvskor nem adunk meg msodik paramtert, akkor a fggvny a 3 rtket felttelezi. Annyi elhagyhat paramtert adhatunk meg, ahnyat csak akarunk, de arra vigyznunk kell, hogy az elhagyhat paramtereknek a paramterlista vgn kell szerepelnik. Ezt a korltozst kikerlhetjk, st mg a paramterek sorrendjt sem kell fejben tartanunk, ha a paramtereket egyetlen asszociatv tmbben adjuk t. (Errl bvebben a hetedik, tmbkrl szl fejezetben lesz sz).

91

Hivatkozs tpus paramterek


Amikor a fggvnyeknek paramtereket adunk t, a helyi paramter-vltozkba a paramterek rtknek msolata kerl. Az e vltozkon vgzett mveleteknek a fggvnyhvs befejezdse utn nincs hatsuk az tadott paramterekre. Ennek igazolsra futtassuk le a 6.13. pldaprogramot.

6.13. program Fggvnyparamter rtk szerinti tadsa


1: <html> 2: <head> 3: <title>6.13. program Fggvnyparamter rtk szerinti tadsa</title> 4: </head> 5: <body> 6: <?php 7: function ottelTobb( $szam ) 8: { 9: $szam += 5; 10: } 11: $regiSzam = 10; 12: ottelTobb( $regiSzam ); 13: print( $regiSzam ); 14: ?> 15: </body> 16: </html> Az ottelTobb() fggvny egyetlen szmot vr, majd tt ad hozz. Visszatrsi rtke nincs. A fprogramban a $regiSzam nev vltoznak rtket adunk, majd ezzel a vltozval meghvjuk az ottelTobb() fggvnyt. A $regiSzam vltoz

92

6. ra rtknek msolata kerl a $szam nev vltozba. Amikor kiratjuk a fggvnyhvs utn a $regiSzam vltoz rtkt, azt talljuk, hogy az rtk mg mindig 10. Alaprtelmezs szerint a fggvnyek paramterei rtk szerint addnak t. Ms szavakkal, a vltozk rtkrl helyi msolat kszl. Lehetsgnk van arra is, hogy ne a vltoz rtkt, hanem arra mutat hivatkozst adjunk t. (Ezt cm szerinti paramtertadsnak is hvjk.) Ez azt jelenti, hogy a vltozra mutat hivatkozssal dolgozunk a fggvnyben s nem a vltoz rtknek msolatval. A paramteren vgzett brmilyen mvelet megvltoztatja az eredeti vltoz rtkt is. Hivatkozsokat fggvnyeknek gy adhatunk t, hogy az tadand vltoz vagy a paramter neve el egy & jelet tesznk. A 6.14. s a 6.15. pldaprogram az elz problmra mutatja be a kt elbb emltett mdszert.

6.14. program Cm szerinti paramtertads vltozra mutatkoz hivatkozs segtsgvel


1: <html> 2: <head> 3: <title>6.14. program Cm szerinti paramtertads vltozra mutat hivatkozs segtsgvel</title> 4: </head> 5: <body> 6: <?php 7: function ottelTobb( $szam ) 8: { 9: $szam += 5; 10: } 11: $regiSzam = 10; 12: ottelTobb( &$regiSzam ); 13: print( $regiSzam ); 14: ?> 15: </body> 16: </html>

Fggvnyek

93

6.15. program Cm szerinti paramtertads a fggvnydeklarci mdostsval


1: <html> 2: <head> 3: <title>6.15. program Cm szerinti paramtertads a fggvnydeklarci mdostsval</title> 4: </head> 5: <body> 6: <?php 7: function ottelTobb( &$szam ) 8: { 9: $szam += 5; 10: } 11: $regiSzam = 10; 12: ottelTobb( $regiSzam ); 13: print( $regiSzam ); 14: ?> 15: </body> 16: </html>

Ha az tadand paramtert alaktjuk hivatkozss, akkor nem fogjuk elfelejteni, hogy az tadott paramter rtke megvltozhat, hiszen mi tettk hivatkozss. Ennek a vltozatnak viszont az a veszlye, hogy elfelejtjk kitenni az & jelet. (C programozk mr biztosan tapasztaltk...) Ha a msodik megoldst vlasztjuk, akkor lehet, hogy elfelejtjk, hogy a paramter rtke megvltozhat, viszont nem felejtjk el kitenni az & jelet, mivel nem is kell kitennnk. Mindent egybevve taln tbb rtelme van annak, hogy a fggvnydeklarciban runk & jelet a paramter neve el. gy biztosak lehetnk benne, hogy az egyes fggvnyhvsok azonos mdon viselkednek.

sszefoglals
Ebben az rban megtanultuk, mik azok a fggvnyek s hogyan kell ket hasznlni. Megtanultuk, hogyan kell ltrehozni s paramtereket tadni nekik. Elsajttottuk a global s a static kulcsszavak hasznlatt. Megtanultuk, hogyan kell a fggvnyeknek hivatkozsokat tadni s a paramtereknek alaprtelmezett rtket adni.

94

6. ra

Krdsek s vlaszok
A global kulcsszn kvl van ms md arra, hogy egy fggvny hozz tudjon frni vagy mdostani tudjon egy globlis vltozt? A globlis vltozkat a programon bell brhonnan elrhetjk a $GLOBALS nev asszociatv tmb segtsgvel. A $proba nev globlis vltozt pldul $GLOBALS["proba"]-knt rhetjk el. Az asszociatv tmbkrl a kvetkez rban tanulunk. A globlis vltozt a fggvnyen bell akkor is mdosthatjuk, ha a fggvny paramterknt egy arra mutat hivatkozst kapott. Krds: Lehet-e a fggvnyhvsokat a vltozkhoz hasonlan karakterlncba gyazni? Nem. A fggvnyhvsoknak az idzjeleken kvl kell lennik.

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Igaz-e, hogy ha egy fggvnynek nem kell paramtert tadni, akkor a fggvny neve utn nem szksges kitenni a zrjelprt? 2. Hogyan lehet fggvnybl rtket visszaadni? 3. Mit r ki az albbi kdrszlet? $szam = 50; function tizszer() { $szam = $szam * 10; } tizszer(); print $szam;

Fggvnyek 4. Mit r ki az albbi kdrszlet? $szam = 50; function tizszer() { global $szam; $szam = $szam * 10; } tizszer(); print $szam; 5. Mit r ki az albbi kdrszlet? $szam = 50; function tizszer($sz) { $sz = $sz * 10; } tizszer($szam); print $szam; 6. Mit r ki az albbi kdrszlet? $szam = 50; function tizszer(&$sz) { $sz = $sz * 10; } $tizszer($szam); print $szam;

95

Feladatok
1. rjunk fggvnyt, amely ngy karakterlnc tpus rtket fogad s olyan karakterlnccal tr vissza, amely paramtereit HTML cellaelemekbe (TD) zrja!

7. RA
Tmbk
A tmbk s a kezelsket segt eszkzk nagy mrtkben nvelik a PHP 4 programok rugalmassgt. Ha jl rtnk a tmbkhz, kpesek vagyunk nagy mret, sszetett adatokat trolni s kezelni. Ebben az rban bemutatjuk a tmbket s nhny beptett fggvnyt, amelyek segtik a velk val boldogulst. Az rban a kvetkezket tanuljuk meg: Mik a tmbk s hogyan hozhatk ltre? Hogyan rhetjk el a tmbkben trolt adatokat? Hogyan rendezhetjk a tmbkben trolt adatokat?

98

7. ra

Mit neveznk tmbnek?


Mint mr tudjuk, a vltoz egy vdr, amiben egy rtket lehet trolni. Vltozk segtsgvel olyan programot rhatunk, amely informcit trol, dolgoz fel s r ki. Egy vltozban azonban sajnos csak egy rtket trolhatunk. A tmb olyan klnleges szerkezet vltoz, amelyben nincs ilyen korltozs. Egy tmbbe annyi adatot lehet beletenni, amennyit csak akarunk (amennyi memrink van). Minden elemet egy szm vagy egy karakterlnc segtsgvel azonosthatunk. Ha a vltoz vdr, akkor a tmb iratszekrny, teht olyan trol, amelyben sok-sok elemet trolhatunk. JDONSG A tmb vltozk listja. Tbb vltozt tartalmaz, amelyeket szmok vagy karakterlncok segtsgvel azonosthatunk, gy a klnbz rtkeket egyetlen nvvel trolhatjuk, rendezhetjk s rhetjk el. Termszetesen ha t rtket kell trolnunk, megadhatunk t vltozt is. Akkor mirt j tmbt hasznlni vltozk helyett? Elszr is azrt, mert a tmb rugalmasabb adatszerkezet. Lehet benne kt vagy akr ktszz rtk s ennek elrse rdekben nem kell tovbbi vltozkat ltrehozni. Msodszor, a tmbk elemeit knnyedn kezelhetjk egysgknt is. Ha akarjuk, vgighaladhatunk a tmbn egy ciklussal vagy elrhetjk az elemeit egyenknt. Lehetsgnk van a tmbt rendezni szm szerint, sztri rendezs szerint vagy sajt rendezelv alapjn. A tmb elemeit az index segtsgvel knnyen elrhetjk. Az index lehet szm, de akr karakterlnc is. Alaprtelmezs szerint a tmbket szmokkal indexeljk, mgpedig gy, hogy az els elem indexe 0. Ebbl az kvetkezik, hogy az utols tmbelem indexe mindig eggyel kisebb a tmb mretnl. Teht az t elem tmb utols eleme a 4-es index elem. Ezt ajnlatos mindig fejben tartani! A 7.1. tblzatban a felhasznalok tmbt lthatjuk. Figyeljk meg, hogy pldul a tmb harmadik elemnek indexe 2.

7.1. tblzat A felhasznalok tmb elemei


Index 0
1 2 3

rtk Berci
Mariska Aladr Eleonra

Hnyadik elem Els


Msodik Harmadik Negyedik

Tmbk A karakterlnccal val indexels akkor lehet hasznos, ha egyedi nevek (kulcsok) mellett ms rtkeket is trolni kell. A PHP 4 mind a szmokkal, mind a nevekkel indexelt tmbk elrsre biztost segdeszkzket. Ezek kzl nhnnyal ebben a fejezetben is tallkozni fogunk, msokat a tizenhatodik, adatmveletekkel foglalkoz fejezetben ismernk majd meg.

99

Tmbk ltrehozsa
A tmbk alaprtelmezs szerint rtkek szmmal indexelt listi. rtket egy tmbhz ktflekppen is rendelhetnk: Az egyik md az array() fggvny, a msik a tmbazonost hasznlata szgletes zrjelekkel ([]). A kvetkez kt rszben mind a ktfle vltozattal tallkozni fogunk.

Tmbk ltrehozsa az array() fggvny segtsgvel


Az array() fggvny akkor hasznos, ha egyszerre tbb rtket szeretnnk egy tmbhz rendelni. Hozzunk ltre egy $felhasznalok nev tmbt s rendeljnk hozz ngy elemet! $felhasznalok = array ("Berci", "Mariska", "Aladr", "Eleonra"); Most a $felhasznalok tmb harmadik elemt, melynek indexe 2, rassuk ki! print $felhasznalok[2]; Ez a kvetkez karakterlncot fogja kirni: "Aladr". Az indexet a tmb neve utn kzvetlenl kvetkez szgletes zrjelbe kell rni. A tmbelem rsakor s olvassakor is ezt a jellst kell hasznlni. Ne felejtsk el, hogy a tmbk indexelse nulltl indul, gy brmely tmbelem indexe eggyel kisebb a tmbelem tmbbli helynl. (Az els elem indexe 0, a msodik elem indexe 1.)

Tmb ltrehozsa vagy elem hozzadsa a tmbhz szgletes zrjel segtsgvel


Tmbket gy is ltrehozhatunk, illetve meglev tmbkhz j elemeket adhatunk, ha a tmb neve utn olyan szgletes zrjelprt runk, amelynek belsejben nincs index.

100

7. ra Hozzuk ltre jra a $felhasznalok nev tmbt: $felhasznalok[] $felhasznalok[] $felhasznalok[] $felhasznalok[] = = = = "Berci"; "Mariska"; "Aladr"; "Eleonra";

Figyeljk meg, hogy nem kellett szmot rnunk a szgletes zrjelbe. A PHP 4 automatikusan meghatrozza az indexrtket, gy nem kell neknk bajldni azzal, hogy kiszmtsuk a kvetkez olyan indexet, amelyben mg nincs rtk. Persze rhattunk volna szmokat is a szgletes zrjelbe, de ez nem tancsos. Nzzk a kvetkez programrszletet: $felhasznalok[0] = "Berci"; $felhasznalok[200] = "Mariska"; A tmbnek gy mindssze kt eleme van, de az utols elem indexe 200. A PHP 4 nem fog rtket adni a kztes elemeknek, ami flrertsekre adhat okot az elemek elrsekor. Tmbk ltrehozsa mellett a tmbvltozk szgletes zrjele segtsgvel az array() fggvnnyel ltrehozott tmb vghez j elemet is adhatunk. Az albbi kis programrszletben ltrehozunk egy tmbt az array() fggvny segtsgvel, majd j elemet adunk a tmbhz szgletes zrjellel. $felhasznalok = array ("Berci", "Mariska", "Aladr", "Eleonra"); $felhasznalok[] = "Anna";

Asszociatv tmbk
A szmmal indexelt tmbk akkor hasznosak, ha abban a sorrendben szeretnnk trolni az elemeket, amilyen sorrendben a tmbbe kerltek. Nha azonban j lenne, ha a tmb elemeit meg tudnnk nevezni. Az asszociatv tmb egy karakterlncokkal indexelt tmb. Kpzeljnk el egy telefonknyvet: melyik a jobb megolds: a nv mezt a 4-gyel vagy a nv-vel indexelni? JDONSG A karakterlnccal indexelt tmbket asszociatv tmbknek (nha hash-nek) hvjk.

Tmbk Asszociatv tmbk ltrehozsa a szmokkal indexelt tmbkkel megegyezen trtnik, az array() fggvny vagy a szgletes zrjelek segtsgvel. A szmmal s a karakterlnccal indexelt tmbk kzti hatrvonal a PHP-ben nem les. Nem klnbz tpusok, mint a Perlben, ennek ellenre helyes az a hozzlls, ha kln-kln kezeljk ket, mert az egyes tpusok ms hozzfrsi s kezelsi mdot ignyelnek.

101

Asszociatv tmbk ltrehozsa az array() fggvny segtsgvel


Ha asszociatv tmbt szeretnnk ltrehozni az array() fggvny segtsgvel, minden elemnek meg kell adni a kulcst s az rtkt. Az albbi programrszlet egy $karakter nev asszociatv tmbt hoz ltre ngy elemmel. $karakter = array ( "nev" => "Jnos", "tevekenyseg" => "szuperhs", "eletkor" => 30, "kulonleges kepesseg" => "rntgenszem" ); Most elrhetjk a $karakter elemeit (mezit): print $karakter["eletkor"];

Asszociatv tmbk ltrehozsa s elrse kzvetlen rtkadssal


Asszociatv tmbt gy is ltrehozhatunk vagy j nvrtk prt adhatunk hozz, ha egyszeren a megnevezett elemhez (mezhz) j rtket adunk. Az albbiakban jra ltrehozzuk a $karakter nev tmbt, gy, hogy az egyes kulcsokhoz egyenknt rendelnk rtkeket.

102

7. ra $karakter["nev"] => "Jnos"; $karakter["tevekenyseg"] => "szuperhs"; $karakter["eletkor"] => 30; $karakter["kulonleges kepesseg"] => "rntgenszem";

Tbbdimenzis tmbk
Eddig azt mondtuk, hogy a tmbk elemei rtkek. A $karakter tmbnkben az elemek kzl hrom karakterlncot tartalmaz, egy pedig egy egsz szmot. A valsg ennl egy kicsit bonyolultabb. Egy tmbelem valjban lehet rtk, objektum vagy akr egy msik tmb is. A tbbdimenzis tmb valjban tmbk tmbje. Kpzeljk el, hogy van egy tmbnk, amelynek tmbk az elemei. Ha el akarjuk rni a msodik elem harmadik elemt, kt indexet kell hasznlnunk: $tomb[1][2] JDONSG A tmbt, amelynek elemei tmbk, tbbdimenzis tmbnek hvjuk.

A tny, hogy egy tmbelem lehet tmb is, lehetsget biztost arra, hogy kifinomultabb adatszerkezeteket kezeljnk viszonylag egyszeren. A 7.1. pldaprogram egy tmbt r le, amelynek elemei asszociatv tmbk.

7.1. program Tbbdimenzis tmb ltrehozsa


1: <html> 2: <head> 3: <title>7.1. program Tbbdimenzis tmb ltrehozsa</title> 4: </head> 5: <body> 6: <?php 7: $karakter = array 8: ( 9: array ( 10: "nev" => "Jnos", 11: "tevekenyseg" => "szuperhs", 12: "eletkor" => 30, 13: "kulonleges kepesseg" => "rntgenszem" 14: ),

Tmbk

103

7.1. program (folytats)


15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: array ( "nev" => "Szilvia", "tevekenyseg" => "szuperhs", "eletkor" => 24, "kulonleges kepesseg" => "nagyon ers" ), array ( "nev" => "Mari", "tevekenyseg" => "fgonosz", "eletkor" => 63, "kulonleges kepesseg" => "nanotechnolgia" ) );

26: 27: 28: 29: print $karakter[0]["tevekenyseg"]; //kirja, hogy szuperhs 30: ?> 31: </body> 32: </html>

Figyeljk meg, hogy array() fggvnyhvsokat ptettnk egy array() fggvnyhvsba. Az els szinten adjuk meg a tmbt, melynek minden eleme asszociatv tmb. A $karakter[2] tmbelemhez trtn hozzfrskor a legfels szint tmb harmadik elemt, egy asszociatv tmbt kapunk. Az asszociatv tmb brmely elemt elrhetjk, pldul a $karakter[2]["nev"] rtke "Mari" lesz, a $karakter[2]["eletkor"] pedig 63. Ha a fogalmak tisztk, asszociatv s hagyomnyos tmbk prostsval egyszeren hozhatunk ltre sszetett adatszerkezeteket.

104

7. ra

Tmbk elrse
Eddig azt lttuk, hogyan kell tmbket ltrehozni s elemeket adni azokhoz. Most vgignznk nhny lehetsget, amit a PHP 4 a tmbk elrsre biztost.

Tmb mretnek lekrdezse


A tmb brmely elemt elrhetjk indexnek hasznlatval: print $felhasznalo[4]; A tmbk rugalmassga miatt nem mindig egyszer feladat kiderteni, hny elem van a tmbben. A PHP a count() fggvnyt biztostja erre a feladatra. A count() a tmbben lev elemek szmval tr vissza. Az albbi programrszben egy szmokkal indexelt tmbt hozunk ltre, majd a count() fggvnyt hasznljuk a tmb utols elemnek elrsre. $felhasznalok = array ("Berci", "Marci", "dn", "Tlap"); $felhasznalok[count($felhasznalok)-1]; Figyeljk meg, hogy egyet ki kellett vonnunk a count() ltal visszaadott rtkbl. Ez azrt van gy, mert a count() nem az utols elem indext adja vissza, hanem a tmbelemek szmt. Semmi sem garantlja, hogy ezzel a mdszerrel brmilyen (szmokkal indexelt) tmb utols elemt megkapjuk. Vegyk pldul az albbi programot: $tomb = array("Ecc, pecc"); // Egyelem tmb! $tomb[2] = "kimehetsz"; print "Az utols elem: " . $tomb[count($tomb)-1]; A fenti kdot futtatva azt tapasztaljuk, hogy az "Az utols elem: " szveg utn semmi nem rdik ki. Ez azrt van, mert a tmbnek nincs 1 index eleme. Az els elem a 0 indexen tallhat, a msodik a 2 indexen, mivel az rtkadskor az indexet kzvetlenl hatroztuk meg. A tmbk indexelse alaprtelmezs szerint nulltl indul, de ezt meg lehet vltoztatni. Ha azonban vilgos s kvetkezetes programokat szeretnnk rni, ne ljnk ezzel a lehetsggel.

Tmb bejrsa
Tbb mdja van annak, hogy egy tmb minden elemt vgigjrjuk. Mi most a PHP 4 igen hatkony foreach szerkezett hasznljuk, de a tizenhatodik rban tovbbi mdszereket is megvizsglunk.

Tmbk

105

A foreach a PHP 4-es vltozatban kerlt a nyelvbe.

A szmmal indexelt tmbkre a foreach szerkezetet gy kell hasznlni: foreach($tombnev as $atmeneti) { } $tombnev a tmb neve, amit vgig szeretnnk jrni, az $atmeneti pedig egy vltoz, amelybe minden ismtls sorn a tmb egy-egy eleme kerl. Az albbi pldban egy szmmal indexelt tmbt hozunk ltre s a foreach vezrlsi szerkezet segtsgvel rjk el annak elemeit: $felhasznalok = array ("Berci", "Marci", "dn"); $felhasznalok[10] = "Tlap"; foreach($felhasznalok as $szemely) { print"$szemely<br>"; } A program kimenett a 7.1-es brn lthatjuk.

7.1. bra
Tmb bejrsa

7
A tmb minden eleme tmenetileg a $szemely vltozba kerlt, amit a program kir a bngszbe. A Perlben gyakorlattal rendelkezk vigyzzanak, a foreach szerkezet a kt nyelvben jelentsen klnbzik! A Perlben ha az tmeneti vltoz rtkt megvltoztatjuk, a megfelel tmbelem is megvltozik.

106

7. ra Ha ugyanezt az elz pldban tesszk, a $felhasznalok tmb rtke nem fog megvltozni. A tizenhatodik rban ltni fogjuk, hogyan mdosthatjuk a foreach segtsgvel a tmbk tartalmt. Figyeljk meg, hogy annak ellenre, hogy a tmb lyukas, a program a foreach szerkezet segtsgvel bejrt tmb minden elemt kirta s az utols sor eltt nem jelentek meg res sorok, teht a 3 s 9 indexek kztti tmbelemeket (melyek nem meghatrozottak, vagyis res karakterlncok) nem rja ki a program. Ahol csak md van r, ne hasznljunk tmbindexeket. A tmbket sokszor csak egyszer listaknt hasznljuk, ahol nem szmt az, hogy egy adott elemnek mi az indexe. A PHP a tmbk elrsre a tmbindexek hasznlatnl hatkonyabb s ttekinthetbb fggvnyeket biztost, programunk ezltal rugalmasabb, knnyebben mdosthat s jl olvashat lesz.

Asszociatv tmb bejrsa


Ha az asszociatv tmb kulcst s rtkt is el szeretnnk rni, egy kicsit mskppen kell a foreach szerkezet hasznlnunk. Asszociatv tmbknl a foreach gy alkalmazhat: foreach( $tomb as $kulcs => $ertek ) { // a tmbelem feldolgozsa } ahol $tomb a tmb neve, amin vgig szeretnnk menni, $kulcs a vltoz, amelyben az elem kulcsa jelenik meg, a $ertek pedig a kulcshoz tartoz tmbelem rtke. A 7.2. pldaprogramban ltrehozunk egy asszociatv tmbt, majd egyesvel elrjk s kirjuk a tmb elemeit

Tmbk

107

7.2. program Asszociatv tmb bejrsa a foreach segtsgvel


1: <html> 2: <head> 3: <title>7.2 pldaprogram Asszociatv tmb bejrsa a foreach segtsgvel</title> 4: </head> 5: <body> 6: <?php 7: $karakter = array ( 8: "nev" => "Jnos", 9: "tevekenyseg" => "szuperhs", 10: "eletkor" => 30, 11: "kulonleges kepesseg" => "rntgenszem" 12: ); 13: 14: foreach ( $karakter as $kulcs => $ertek ) 15: { 16: print "$kulcs = $ertek<br>"; 17: } 18: ?> 19: </body> 20: </html> A 7.2. pldaprogram kimenett a 7.2. brn lthatjuk.

7.2. bra
Asszociatv tmb bejrsa

108

7. ra

Tbbdimenzis tmb bejrsa


Most mr ismernk olyan mdszereket, amelyek segtsgvel a 7.1. pldaprogramban ltrehozott tbbdimenzis tmbt bejrhatjuk. A 7.3. pldaprogramban ltrehozunk egy tbbdimenzis tmbt s a foreach segtsgvel vgigjrjuk az elemeit.

7.3. program Tbbdimenzis tmb bejrsa


1: <html> 2: <head> 3: <title>7.3. program - Tbbdimenzis tmb bejrsa</title> 4: </head> 5: <body> 6: <?php 7: $karakterek = array 8: ( 9: array ( 10: "nev" => "Jnos", 11: "tevekenyseg" => "szuperhs", 12: "eletkor" => 30, 13: "kulonleges kepesseg" => "rntgenszem" 14: ), 15: array ( 16: "nev" => "Szilvia", 17: "tevekenyseg" => "szuperhs", 18: "eletkor" => 24, 19: "kulonleges kepesseg" => "nagyon ers" 20: ), 21: array ( 22: "nev" => "Mari", 23: "tevekenyseg" => "fgonosz", 24: "eletkor" => 63, 25: "kulonleges kepesseg" => "nanotechnolgia" 26: ) 27: );

Tmbk

109

7.3. program (folytats)


28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: foreach ( $karakterek as $karakter ) { foreach ( $karakter as $kulcs => $ertek ) { print "$kulcs: $ertek<br>"; } print "<br>"; } ?> </body> </html>

A 7.3. pldaprogram kimenett a 7.3. brn lthatjuk. Kt foreach ciklust hasznlunk. A kls ciklusban a szmmal indexelt $karakterek tmb elemeit vesszk vgig, az egyes elemek pedig a $karakter nev vltozba kerlnek. A $karakter maga is egy tmb, ezrt ennek rtkeit is egy foreach ciklussal jrjuk vgig. Mivel a $karakter egy asszociatv tmb, a foreach szerkezetet az ennek megfelel formban hasznljuk, a kulcs-rtk prok pedig a $kulcs s az $ertek vltozkba kerlnek. Annak rdekben, hogy ez a mdszer jl mkdjn, biztosnak kell lennnk abban, hogy a $karakter vltoz valban mindig tmbt tartalmaz. A kdot megbzhatbb tehetnnk, ha meghvnnk a $karakter vltozra az is_array() fggvnyt. Az is_array() fggvny szmra egy paramtert kell megadnunk. A visszatrsi rtk true lesz, ha a vltoz tpusa tmb, minden ms esetben false rtket ad. Bonyolultabb programok esetben gyakran elfordul, hogy kvncsiak vagyunk egy tmb vagy valamilyen ms sszetett vltoz tartalmra. Ilyenkor ltalban nem kell sajt tmblistz kdot hasznlnunk, hiszen a PHP 4 biztostja szmunkra a print_r() fggvnyt, amely a paramtereknt megadott vltoz tartalmt rja ki.

110

7. ra

Mveletek tmbkkel
Most mr fel tudunk tlteni tmbket elemekkel, elrhetjk azokat, de a PHP rengeteg fggvnnyel segti a tmbk feldolgozst is. A Perlben jrtas olvas bizonyra ismersnek fogja tallni ezen fggvnyek nagy rszt.

Kt tmb egyestse az array_merge() fggvny segtsgvel


Az array_merge() fggvny legalbb kt paramtert vr: az egyestend tmbket. A visszatrsi rtk az egyestett tmb lesz. Az albbi pldban ltrehozunk kt tmbt, egyestjk azokat, majd vgigjrjuk a keletkez harmadik tmbt: $elso = array( "a", "b", "c" ); $masodik = array( 1, 2, 3 ); $harmadik = array_merge( $elso, $masodik ); foreach( $harmadik as $ertek ) { print "$ertek<br>"; } A $harmadik tmb az $elso s a $masodik tmbk elemeinek msolatt tartalmazza. A foreach ciklus ennek a tmbnek az elemeit ("a", "b", "c", 1, 2, 3) rja ki a bngszbe. Az egyes elemeket a <br> (sortrs) vlasztja el egymstl. Az array_merge() fggvny a PHP 4-es vltozatban kerlt a nyelvbe.

Egyszerre tbb elem hozzadsa egy tmbhz az array_push() fggvny segtsgvel


Az array_push() fggvny egy tmbt s tetszleges szm tovbbi paramtert fogad. A megadott rtkek a tmbbe kerlnek. Figyeljk meg, hogy az array_merge() fggvnnyel ellenttben az array_push() megvltoztatja els paramternek rtkt. E fggvny visszatrsi rtke a tmbben lv elemek szma (miutn az elemeket hozzadta). Hozzunk ltre egy tmbt, majd adjunk hozz nhny elemet:

Tmbk $elso = array( "a", "b", "c" ); $elemszam = array_push( $elso, 1, 2, 3 ); print "sszesen $elemszam elem van az \$elso tmbben<P>"; foreach( $elso as $ertek ) { print "$ertek<br>"; } Mivel az array_push() fggvny visszaadja a mdostott tmb elemeinek szmt, az rtket (ami ebben az esetben 6) egy vltozban trolhatjuk s kirathatjuk a bngszbe. Az $elso tmb ekkor az eredeti hrom bett tartalmazza, melyekkel az els sorban feltltttk, illetve a hrom szmot, amit az array_push() fggvny segtsgvel adtunk hozz. Az gy ltrehozott tmb elemeit a foreach ciklus segtsgvel kiratjuk a bngszbe. Figyeljk meg, hogy a "$elso" karakterlnc el egy fordtott perjelet kellett tennnk. Ha a PHP egy macskakrms (ketts idzjeles) karakterlncban egy dollrjelet kvet bet- s/vagy szmsorozatot tall, vltozknt prblja rtelmezni azt s megksrli az rtkt berni. A fenti pldban mi a '$elso' karaktersorozatot szerettk volna megjelenteni, ezrt kellett a dollrjel el a fordtott perjel karakter. gy a PHP mr nem prblja meg vltozknt rtelmezni, hanem kirja a karaktereket. Ezt a mdszert a szakirodalomban gyakran escape-knt emlegetik. A Perlben gyakorlattal rendelkezk figyeljenek arra, hogy ha a PHP-ben az array_push() msodik paramtereknt tmbt adnak meg, a tmb egy tmb tpus elemmel bvl, ezltal tbbdimenzis tmb keletkezik. Ha kt tmb elemeit szeretnnk egyesteni, hasznljuk az array_merge() fggvnyt.

111

Ha egy karakterlncban nem szeretnnk, hogy a vltozk behelyettestdjenek, a karakterlnc jellsre egyszeres idzjeleket hasznljunk; ekkor a s a \ karakterek helyett \-t s \\-t kell rnunk.

112

7. ra

Az array_shift() eltvoltja a paramterknt tadott tmb els elemt s az elem rtkvel tr vissza. A kvetkez pldban az array_shift() fggvny segtsgvel eltvoltjuk a tmb els elemt. Ezt a mveletet egy while ciklusba tesszk s a mveletet addig ismteljk, amg el nem fogy a tmb. Annak ellenrzsre, hogy van-e mg elem a tmbben, a count() fggvnyt hasznljuk. <?php $egy_tomb = array( "a", "b", "c" ); while ( count( $egy_tomb ) ) { $ertek = array_shift( $egy_tomb ); print "$ertek<br>"; print '$egy_tomb-ben most ' . count( $egy_tomb ) . 'elem van<br>'; } ?> A program kimenett a 7.4. brn lthatjuk.

Az els elem eltvoltsa az array_shift() fggvny segtsgvel

7.4. bra
A tmb egyes elemeinek trlse s kiratsa az array_shift() fggvny segtsgvel

Az array_shift() akkor lehet hasznos, amikor egy sor elemein kell valamilyen tevkenysget vgezni, amg a sor ki nem rl. Az array_shift() fggvny a PHP 4-es vltozatban kerlt a nyelvbe.

Tmbk

113

Az array_slice() fggvny egy tmb egy darabjt adja vissza. A fggvny egy tmbt, egy kezdpozcit (a szelet els elemnek tmbbeli indext) s egy (elhagyhat) hossz paramtert vr. Ha ez utbbit elhagyjuk, a fggvny felttelezi, hogy a kezdpozcitl a tmb vgig tart szeletet szeretnnk megkapni. Az array_slice() nem vltoztatja meg a paramterknt tadott tmbt, hanem jat ad vissza, amelyben a hv ltal krt elemek vannak. Az albbi pldban ltrehozunk egy tmbt, majd egy j, hrom elem tmbt lltunk el belle: $elso = array( "a", "b", "c", "d", "e", "f" ); $masodik = array_slice( $elso, 2, 3 ); foreach( $masodik as $ertek ) { print "$ertek<br>"; } A fenti plda a "c", "d" s "e" elemeket rja ki, a <br> kdelemmel elvlasztva. Mivel kezdpozciknt a kettt adtuk meg, gy az els elem, ami a $masodik tmbbe kerl, az $elso[2]. Ha kezdpozciknt negatv szmot adunk meg, a tmbszelet els eleme htulrl a megadott szm elemtl kezddik. Ez azt jelenti, hogy ha a msodik paramter rtke -1, a tmbszelet az utols elemtl fog kezddni. Ha hossz paramterknt nullnl kisebb szmot adunk meg, a visszakapott tmbszelet a tmb htulrl a megadott szm elemig tart. Az array_slice() fggvny a PHP 4-es vltozatban jelent meg.

Tmb rsznek kinyerse az array_slice() fggvny segtsgvel

Tmbk rendezse
Taln a rendezs a legnagyszerbb mvelet, amit egy tmbn el lehet vgezni. A PHP 4 fggvnyeinek ksznheten egykettre rendet teremthetnk a koszban. A kvetkez rsz nhny olyan fggvnyt mutat be, amelyek szmmal s karakterlnccal indexelt tmbket rendeznek.

114

7. ra

Szmmal indexelt tmb rendezse a sort() fggvny segtsgvel


A sort() fggvny egy tmb tpus paramtert vr s a tmb rendezst vgzi el. Ha a tmbben van karakterlnc, a rendezs (alapbelltsban angol!) bcsorrend szerinti lesz, ha a tmbben minden elem szm, szm szerint trtnik. A fggvnynek nincs visszatrsi rtke, a paramterknt kapott tmbt alaktja t. Ebbl a szempontbl klnbzik a Perl hasonl fggvnytl. Az albbi programrszlet egy karakterekbl ll tmbt hoz ltre, rendezi, majd a rendezett tmb elemeit egyenknt kirja: $tomb = array( "x", "a", "f", "c" ); sort( $tomb ); foreach ($tomb as $elem) { print "$elem<br>"; } Nzzk egy kis pldt egy tmb ktfle rendezsi mdjra! $tomb = array( 10, 2, 9 ); sort( $tomb ); print '___Rendezs szm szerint___'<br>; foreach ($tomb as $elem) { print "$elem<br>"; } $tomb[]="a"; sort( $tomb ); print '___Rendezs bcsorrend szerint___<br>'; foreach ($tomb as $elem) { print "$elem<br>"; } A fenti plda kimenete: ___Rendezs szm szerint___ 2 9 10

Tmbk ___Rendezs bcsorrend szerint___ 10 2 9 a A sort() fggvnyt ne hasznljuk asszociatv (karakterlnccal indexelt) tmbkre! Ha mgis megtesszk, azt fogjuk tapasztalni, hogy a tmb elemei ugyan rendezettek lesznek, de az elemek kulcsai elvesznek, az egyes elemek gy nulltl kezdd szmokkal rhetk el, ugyanis a tmb szmmal indexelt tmbb alakul t.

115

Ha cskken sorrendben szeretnnk rendezni egy tmb elemeit, hasznljuk a sort() fggvnyhez hasonlan mkd rsort() fggvnyt.

Asszociatv tmb rendezse rtk szerint az asort() fggvny segtsgvel


Az asort() fggvny egy asszociatv tmb tpus paramtert vr s a tmbt a sort() fggvnyhez hasonlan rendezi. Az egyetlen klnbsg, hogy az asort() hasznlata utn megmaradnak a karakterlnc-kulcsok: $a_tomb = array( "elso"=>5, "masodik"=>2, "harmadik"=>1 ); asort( $a_tomb ); foreach( $a_tomb as $kulcs => $ertek ) { print "$kulcs = $ertek<br>"; } Ennek a programocsknak a kimenett a 7.5. brn lthatjuk.

116

7. ra

7.5. bra
Asszociatv tmb rtk szerinti rendezse az asort() fggvny segtsgvel

Ha cskken sorrendben szeretnnk rendezni egy asszociatv tmb elemeit, hasznljuk a arsort() fggvnyt.

Asszociatv tmb rendezse kulcs szerint a ksort() fggvny segtsgvel


A ksort() a paramterben megadott asszociatv tmbt rendezi kulcs szerint. A tbbi tmbrendez fggvnyhez hasonlan ez a fggvny sem ad vissza semmifle visszatrsi rtket, hanem a tmbt alaktja t: $tomb = array( "x" => 5, "a" => 2, "f" => 1 ); ksort( $tomb ); foreach( $tomb as $kulcs => $ertek ) { print "$kulcs = $ertek<BR>"; } A program kimenett a 7.6. brn lthatjuk.

7.6. bra
Asszociatv tmb rendezse kulcs szerint a ksort() fggvny segtsgvel

Tmbk

117

sszefoglals
Ebben az rban a tmbkrl s a hozzjuk kapcsold eszkzkrl tanultunk, melyeket a PHP 4 a rajtuk vgzett mveletekhez nyjt. Most mr tudunk norml (szmmal indexelt) s asszociatv (karakterlnccal indexelt) tmbket is ltrehozni, illetve tmbket bejrni a foreach ciklus segtsgvel. Tbbdimenzis tmbket is ltre tudunk hozni, a bennk lev informcit pedig ki tudjuk nyerni egymsba gyazott foreach ciklusokkal. A tmbkhz egyszerre tbb elemet is adhatunk, illetve onnan kivehetnk. Vgl megtanultuk, hogy a PHP 4-es vltozata milyen lehetsgeket nyjt a tmbk rendezsre.

Krdsek s vlaszok
Ha a foreach ciklus csak a PHP 4-esben kerlt a nyelvbe, akkor a PHP 3-as vltozatt hasznl programozk hogyan jrtak vgig egy tmbt? A PHP 3-asban az each() fggvnyt hasznltk egy while() ciklusban. Errl bvebben a tizenhatodik rban olvashatunk. Van olyan tmbt kezel fggvny, amellyel nem foglalkoztunk ebben az rban? A PHP 4-es vltozatban nagyon sok tmbkezel fggvny van. Errl bvebben a tizenhatodik rban fogunk tanulni. A kziknyv errl szl rsze megtallhat az Interneten, a http://www.php.net/manual/en/ref.array.php cmen. (A kziknyv magyar vltozata a http://hu.php.net/manual/hu/ oldalon tallhat.) Ha a tmb elemeinek szmt ismerem, norml tmb bejrsra a for ciklust hasznljam? (Ekkor szmll segtsgvel cmzem meg a tmb elemeit.) Nagyon vatosan kell bnni ezzel a megkzeltssel. Nem lehetnk biztosak abban, hogy az ltalunk hasznlt tmb indexei 0-tl indulnak s egyesvel nnek.

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Melyik fggvnnyel hozhatunk ltre tmbket? 2. Az albb ltrehozott tmb utols elemnek mi az indexe? $torpek = array( "Tudor", "Vidor", "Kuka" );

118

7. ra 3. Fggvnyek hasznlata nlkl hogyan tudnnk "Hapci"-t az imnt ltrehozott $torpek nev tmbhz adni? 4. Melyik fggvny segtsgvel tudnnk "Morg"-t a $torpek nev tmbbe felvenni? 5. Hogyan lehet egy tmb elemszmt megtudni? 6. A PHP 4-es vltozatban mi a legegyszerbb mdja egy tmb bejrsnak? 7. Milyen fggvny segtsgvel lehet kt tmbt egyesteni? 8. Hogyan rendeznnk egy asszociatv tmbt kulcsai szerint?

Feladatok
1. Hozzunk ltre egy tbbdimenzis tmbt, amely filmeket tartalmaz, zsner szerint rendezve! Pontosabban hozzunk ltre egy asszociatv tmbt, amelynek kulcsai filmtpusok ("Scifi", "Akci", "Romantikus")! A tmb elemei legyenek tmbk, amelyek filmcmeket tartalmaznak ("2001", "Alien", "Terminator",...)! 2. Jrjuk vgig az elz feladatban ltrehozott tmbt s rjuk ki az sszes filmtpust s a hozz tartoz filmcmeket!

8. RA
Objektumok
Az objektumkzpont programozs veszlyes. Megvltoztatja a programozsrl val gondolkodsmdunkat s ha egyszer a hatalmba kert, nem tudunk tle szabadulni. A PHP a Perlhz hasonlan fokozatosan ptette be az objektumkzpontsgot a nyelvtanba. A PHP 4-es vltozatnak megjelensvel kpess vltunk arra, hogy programjainkat teljes mrtkben objektumkzpont szemlletmdban rjuk. Ebben az rban a PHP 4-es vltozatnak objektumkzpont tulajdonsgaival foglalkozunk s azokat vals letbl vett pldkra alkalmazzuk. Az rban a kvetkezket tanuljuk meg: Mik az osztlyok s objektumok? Hogyan lehet osztlyokat s objektumpldnyokat ltrehozni? Hogyan lehet tagfggvnyeket s tulajdonsgokat ltrehozni s elrni? Hogyan lehet olyan osztlyt ltrehozni, mely ms osztly leszrmazottja? Mirt j az objektumkzpont programozs s hogyan segti munknk szervezst?

120

8. ra

Mit neveznk objektumnak?


Az objektum vltozk s fggvnyek egybezrt csomagja, amely egy klnleges sablonbl jn ltre. Az objektum bels mkdse nagy rszt elrejti az objektumot hasznl ell, gy, hogy egyszer hozzfrsi felletet biztost, melyen keresztl krseket kldhetnk s informcit kaphatunk. A fellet klnleges fggvnyekbl, gynevezett tagfggvnyekbl (metdusokbl) ll. A tagfggvnyek mindegyike hozzfrhet bizonyos vltozkhoz, amelyeket tulajdonsgoknak neveznk. A tpus jellegzetessgeit objektumtpusok (osztlyok, class) ltrehozsval hatrozzuk meg. Objektumpldnyok (vagy rviden objektumok) ltrehozsval pedig egyedeket hozunk ltre. Ezen egyedek rendelkeznek a tpusuknak megfelel jellemzkkel, de termszetesen a jellemzk rtke ms s ms lehet. Pldul ha ltrehozunk egy gepkocsi osztlyt, akkor az osztlynak lehet egy jellemzje, amelynek a szin nevet adjuk. Az objektumpldnyokban a szin tulajdonsg rtke lehet pldul "kk" vagy "zld". Az osztly tagfggvnyek s tulajdonsgok egyttese. Az osztlyokat a class kulcssz segtsgvel hozhatjuk ltre. Az osztlyok sablonok, amelyekbl objektumokat llthatunk el. JDONSG Az objektum az osztly egy pldnya, vagyis egy objektum nem ms, mint az osztlyban rgztett mkdsi szablyok megtesteslse. Egy adott tpus objektum a new kulcssz utn rt objektumtpus nevnek segtsgvel testesthet meg. Amikor egy objektumpldny ltrejn, sszes tulajdonsga s tagfggvnye elrhetv vlik. Az objektumkzpont program legnagyobb elnye valsznleg a kd jrahasznosthatsga. Mivel az osztlyokat egysgbezrt objektumok ltrehozsra hasznljuk, egyszeren vihetk t egyik projektbl a msikba, radsul lehetsg van arra is, hogy gyermekosztlyokat hozzunk ltre, amelyek a szl tulajdonsgait rklik s kpesek azt kiegszteni vagy mdostani. E mdszer segtsgvel rengeteg sszetett vagy egyedi tulajdonsggal rendelkez objektumot, vagyis objektumcsaldot lehet ltrehozni, amelyek egy alaposztlyra plnek, de kzben egyni tulajdonsgokkal is rendelkeznek, egyedi tagfggvnyeket is biztostanak. Az objektumkzpont programozs bemutatsnak taln legjobb mdja, ha a bemutatott pldk alapjn ksrletezgetnk.

Objektumok

121

Objektum ltrehozsa
Ahhoz, hogy ltre tudjunk hozni egy objektumot, elszr ltre kell hozni a sablont, amelyre pl. Ezt a sablont hvjuk osztlynak. A PHP 4-es vltozatban ilyen sablont a class kulcsszval hozhatunk ltre: class elso_osztaly { // ez egy nagyon buta osztly } Az elso_osztaly a minta, amely alapjn tetszleges szm elso_osztaly tpus objektumot hozhatunk ltre. Objektumot ltrehozni a new kulcssz segtsgvel lehet: $obj1 $obj2 print print = new elso_osztaly(); = new elso_osztaly(); "\$obj1 " . gettype($obj1) . " tpus<br>"; "\$obj2 " . gettype($obj2) . " tpus<br>";

A PHP gettype() fggvnyvel ellenriztk, hogy az $obj1 s az $obj2 vltozkban valban objektum van-e. A gettype() szmra egy tetszleges tpus vltozt kell tadnunk, a fggvny pedig egy karakterlnccal tr vissza, ami a vltoz tpust tartalmazza. Az elz programrszletben a gettype() visszatrsi rtke "object", amit a print segtsgvel a bngsz szmra kirtunk. Meggyzdhettnk rla, hogy kt objektumunk van. A pldnak els rnzsre tl sok hasznt mg nem ltjuk, de segtsgvel jabb nzpontbl vizsglhatjuk az osztlyokat. Az osztlyokra gy tekinthetnk, mint ntmintra: annyi objektumot nthetnk a segtsgvel, amennyit csak szeretnnk. Adjunk nhny tovbbi szolgltatst az osztlyhoz, hogy objektumaink kicsit rdekesebbek legyenek.

Objektumtulajdonsgok
Az objektumok a tulajdonsg nven emltett klnleges vltozk rvn mkdnek. Ezek az osztlyban brhol ltrehozhatk, de az tlthatsg kedvrt az osztlymeghatrozs elejre clszer kigyjteni azokat, gy mi is ezt tesszk. A tulajdonsgok lehetnek rtkek, tmbk, de ms objektumok is: class elso_osztaly { var $nev = "Gizike"; }

122

8. ra Figyeljk meg, hogy a vltozt a var kulcssz segtsgvel hoztuk ltre; ha ezt egy osztlyon bell nem rjuk ki, rtelmezsi hibt (parse error) kapunk. Most, hogy ezt a vltozt ltrehoztuk, minden elso_osztaly tpus objektumnak lesz egy nev tulajdonsga, melynek "Gizike" lesz a kezdeti rtke. Ehhez a tulajdonsghoz az objektumon kvlrl is hozz lehet frni, st meg is lehet vltoztatni: class elso_osztaly { var $nev = "Gizike"; } $obj1 = new elso_osztaly(); $obj2 = new elso_osztaly(); $obj1->nev = "Bonifc"; print "$obj1->nev<br>"; print "$obj1->nev<br>"; A -> mveletjel teszi lehetv, hogy egy objektum tulajdonsgait elrhessk vagy mdosthassuk. Br az $obj1 s az $obj2 objektumokat "Gizike" nvvel hoztuk ltre, rbrtuk az $obj2 objektumot, hogy meggondolja magt, a nev tulajdonsghoz a "Bonifc" rtket rendelve, mieltt a -> jelet ismt hasznlva kituk volna mindkt objektum nev tulajdonsgnak rtkt. Az objektumkzpont nyelvek, mint a Java, megkvnjk, hogy a programoz belltsa a tulajdonsgok s tagfggvnyek biztonsgi szintjt. Ez azt jelenti, hogy a hozzfrs gy korltozhat, hogy csak bizonyos, az objektumot kezel magas szint fggvnyek legyenek elrhetk, a bels hasznlatra sznt tulajdonsgok, tagfggvnyek pedig biztonsgosan elrejthetk. A PHP-nek nincs ilyen vdelmi rendszere. Az objektum sszes tulajdonsga elrhet, ami problmkat okozhat, ha a tulajdonsgot (kvlrl) nem lenne szabad megvltoztatni.

Az objektumot adattrolsra is hasznlhatjuk, de az objektumok tbbre kpesek, mint egy egyszer asszociatv tmb utnzsa. A kvetkez rszben ttekintjk az objektumok tagfggvnyeit, amelyek segtsgvel objektumaink letre kelnek.

Az objektumok tagfggvnyei
A tagfggvny olyan fggvny, amelyet egy osztlyon bell hozunk ltre. Minden objektumpldny kpes meghvni osztlya tagfggvnyeit. A 8.1. pldaprogram az elso_osztaly nev osztlyt egy tagfggvnnyel egszti ki.

Objektumok

123

8.1. program Egy osztly tagfggvnnyel


1: <html> 2: <head> 3: <title>8.1. program Egy osztly tagfggvnnyel</title> 4: <body> 5: <?php 6: class elso_osztaly 7: { 8: var $nev; 9: function koszon() 10: { 11: print "dvzlm!"; 12: } 13: } 14: $obj1 = new elso_osztaly(); 15: $obj1->koszon(); // kirja, hogy "dvzlm!" 16: ?> 17: </body> 18: </html>

Amint ltjuk, a tagfggvny a szokvnyos fggvnyekhez nagyon hasonlan viselkedik. A klnbsg csak annyi, hogy a tagfggvnyt mindig osztlyon bell hozzuk ltre. Az objektumok tagfggvnyeit a -> mveletjel segtsgvel hvhatjuk meg. Fontos, hogy a tagfggvnyek hozzfrnek az objektum vltozihoz. Mr lttuk, hogyan lehet egy objektumtulajdonsgot az objektumon kvlrl elrni, de hogyan hivatkozhat egy objektum sajt magra? Lssuk a 8.2. pldaprogramot:

8.2. program Tulajdonsg elrse tagfggvnybl


1: <html> 2: <head> 3: <title>8.2. program Tulajdonsg elrse tagfggvnybl</title> 4: <body> 5: <?php 6: class elso_osztaly 7: { 8: var $nev = "Krisztin"; 9: function koszon()

124

8. ra

8.2. program (folytats)


10: { 11: print"dvzlm! $this->nev vagyok.<BR>"; 12: } 13: } 14: 15: $obj1 = new elso_osztaly(); 16: $obj1->koszon(); // kirja, hogy "dvzlm! Krisztin vagyok." 17: ?> 18: </body> 19: </html>

Az osztlynak van egy klnleges vltozja, a $this, ami az objektumpldnyra mutat. Tekinthetjk szemlyes nvmsnak. Br programunkban az objektumra hivatkozhatunk azzal a vltozval, amihez hozzrendeltk (pldul $obj1), az objektumnak hivatkoznia kell sajt magra, erre j a $this vltoz. A $this vltoz s a -> mveletjel segtsgvel az osztlyon bellrl az osztly minden tulajdonsgt s tagfggvnyt elrhetjk. Kpzeljk el, hogy minden egyes elso_osztaly tpus objektumhoz ms s ms nev tulajdonsgot szeretnnk rendelni. Ezt megtehetnnk kzzel, az objektum nev tulajdonsgt megvltoztatva, de ltrehozhatunk egy tagfggvnyt is, ami ezt teszi. Az utbbi megoldst lthatjuk a 8.3. pldaprogramban.

8.3. program Tulajdonsg rtknek mdostsa tagfggvnyen bellrl


1: <html> 2: <head> 3: <title>8.3. program Tulajdonsg rtknek mdostsa tagfggvnyen bellrl</title> 4: </head> 5: <body> 6: <?php 7: class elso_osztaly 8: { 9: var $nev = "Krisztin"; 10: function atkeresztel( $n ) 11: { 12: $this->nev = $n; 13: }

Objektumok

125

8.3. program (folytats)


14: function koszon() 15: { 16: print"dvzlm! $this->nev vagyok.<BR>"; 17: } 18: } 19: 20: $obj1 = new elso_osztaly(); 21: $obj1->atkeresztel("Aladr"); 22: $obj1->koszon(); // kirja, hogy "dvzlm! Aladr vagyok." 23: ?> 24: </body> 25: </html>

Az objektum nev tulajdonsga a ltrehozskor mg "Krisztin" volt, de aztn meghvtuk az objektum atkeresztel() tagfggvnyt, ami "Aladr" rtkre vltoztatta azt. Lthatjuk, hogy az objektum kpes sajt tulajdonsgait mdostani. Figyeljk meg, hogy a tagfggvnynek a hagyomnyos fggvnyekhez hasonlan adhatunk t paramtereket. Mg mindig van egy fogs, amit nem ismertnk meg. Ha egy metdusnak ppen azt a nevet adjuk, mint az osztlynak (az elz pldban ez az elso_osztaly), akkor a metdus automatikusan meghvdik, amikor egy j objektumpldny ltrejn. E mdszer segtsgvel mr szletskkor testreszabhatjuk objektumainkat. A ltrejv pldny az ezen fggvnynek tadott paramterek vagy ms tnyezk alapjn hozhatja magt alapllapotba. Ezeket a klnleges metdusokat konstruktoroknak (ltrehoz fggvnyeknek) hvjuk. A 8.4. pldaprogramban az elso_osztaly objektumtpus konstruktorral kiegsztett vltozatt lthatjuk.

8.4. program Konstruktorral rendelkez osztly


1: <html> 2: <head> 3: <title>8.4. program Konstruktorral rendelkez osztly</title> 4: </head> 5: <body> 6: <?php

126

8. ra

8.4. program (folytats)


7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: class elso_osztaly { var $nev; function elso_osztaly( $n="Anonymous" ) { $this->nev = $n; } function koszon() { print"dvzlm! $this->nev vagyok.<BR>"; } } $obj1 = new elso_osztaly("Krisztin"); $obj2 = new elso_osztaly("Aladr"); $obj1->koszon(); // kirja, hogy "dvzlm! Krisztin vagyok." $obj2->koszon(); // kirja, hogy "dvzlm! Aladr vagyok." ?> </body> </html>

Amikor egy elso_osztaly tpus objektumot ltrehozunk, az elso_osztaly() konstruktor automatikusan meghvsra kerl. Ha az objektum ltrehozsakor nem adunk meg nevet, a paramter rtke "anonymus" lesz.

Egy bonyolultabb plda


Most ksztsnk egytt egy kicsit bonyolultabb s hasznosabb programot: egy tblzat osztlyt hozunk ltre, amelyben az egyes oszlopokat nevk alapjn is elrhetjk. Az adatszerkezet soralap lesz, a bngszben val megjelentst pedig egy butcska fggvnyre bzzuk. A tblzat takaros formzsa a problma megoldsnak ebben a fzisban nem szksges.

Az osztly tulajdonsgai
Elszr is el kell dntennk, hogy milyen tulajdonsgokat troljunk az objektumban. Az oszlopok neveit egy tmbben troljuk, a sorokat pedig egy ktdimenzis tmbben. A tblzat oszlopainak szmt kln, egy egsz tpus vltozba helyezzk.

Objektumok class Tablazat { var $tablazatSorok = array(); var $oszlopNevek = array(); var $oszlopszam; }

127

A konstruktor
A tblzat ltrehozsakor a programnak mr tudnia kell, mik lesznek a feldolgozand oszlopok nevei. Ez az informci az objektumhoz a konstruktor egy karakterlnc tpus tmbparamtere segtsgvel fog eljutni. Ha az oszlopok neveit a konstruktor mr ismeri, knnyszerrel meghatrozhatja az oszlopok szmt s berhatja az $oszlopszam tulajdonsgba: function Tablazat( $oszlopNevek ) { $this->oszlopNevek = $oszlopNevek; $this->oszlopszam = count ( $oszlopNevek ); } Ha feltesszk, hogy a konstruktor szmra helyes informcit adtunk t, az objektum mr tudni fogja oszlopainak szmt s nevt. Mivel ez az informci tulajdonsgokban (mezkben) troldik, minden tagfggvny szmra hozzfrhet.

Az ujSor() tagfggvny
A Tablazat osztly a sorokat tmbk formjban kapja meg. Ez persze csak akkor mkdik helyesen, ha a tmbben s a fejlcben az oszlopok sorrendje azonos: function ujSor( $sor ) { if ( count ($sor) != $this->oszlopszam ) return false; array_push($this->tablazatSorok, $sor); return true; } Az ujSor() tagfggvny egy tmbt vr, amit a $sor nev vltozban kap meg. A tblzat oszlopainak szmt mr az $oszlopszam tulajdonsgba helyeztk, gy most a count() fggvnnyel ellenrizhetjk, hogy a kapott $sor paramter megfelel szm oszlopot tartalmaz-e. Ha nem, akkor a fggvny false rtket ad vissza.

128

8. ra A PHP 4-es vltozatnak array_push() fggvnye segtsgvel az j sort a $tablazatSor tmb vghez fzhetjk. Az array_push() kt paramtert vr: a tmbt, amihez az j elemet hozz kell adni, illetve a hozzadand elemet. Ha a msodik paramter maga is egy tmb, akkor az egy elemknt addik az els tmbhz, gy tbbdimenzis tmb jn ltre. Ezen eljrs segtsgvel teht tbbdimenzis tmbket is ltrehozhatunk.

Az ujNevesSor() tagfggvny
Az ujSor() tagfggvny csak akkor hasznlhat knyelmesen, ha a tmbknt tadott paramterben az elemek sorrendje megfelel. Az ujNevesSor() tagfggvny ennl tbb szabadsgot ad. A metdus egy asszociatv tmbt vr, ahol az egyes elemek kulcsa az oszlopok neve. Ha olyan kulcs elem kerl a paramterbe, amely a Tablazat objektum $oszlopNevek tulajdonsgban nem szerepel, az adott elem egyszeren nem kerl bele a tblzatba. Ha egy oszlopnv nem jelenik meg a paramterben kulcsknt, akkor az adott oszlopba egy res karakterlnc kerl. function ujNevesSor( $asszoc_sor ) { if ( count ($asszoc_sor) != $this->oszlopszam ) return false; $sor = array(); foreach ( $this->oszlopNevek as $oszlopNev ) { if ( ! isset( $asszoc_sor[$oszlopNev] )) $asszoc_sor[$oszlopNev] = ""; $sor[] = $asszoc_sor[$oszlopNev]; } array_push($this->tablazatSorok, $sor); } Az ujNevesSor()-nak tadott asszociatv tmb az $asszoc_sor nev vltozba kerl. Elszr ltrehozunk egy res $sor tmbt, amely majd a tblzatba beillesztend sort tartalmazza, az elemek helyes sorrendjvel. Majd vgigvesszk az $oszlopNevek tmb elemeit, s megnzzk, hogy a tmbben kaptunk-e ilyen kulcs elemet az $asszoc_sor paramterben. Ehhez a PHP 4-es isset() fggvnyt hasznljuk, amely egy vltozt vr. Ha a vltozhoz mr rendeltnk rtket, a fggvny visszatrsi rtke true, egybknt false lesz. A fggvnynek az $asszoc_sor tmb azon elemt kell tadnunk, melynek kulcsa megegyezik a kvetkez oszlop nevvel. Ha nem ltezik ilyen elem az $asszoc_sor tmbben, ltrehozunk egy ilyet s res karakterlncot runk bele. Most mr folytathatjuk a vgleges $sor tmb felptst s hozzadhatjuk az $asszoc_sor megfelel elemt, hiszen pp az imnt biztostottuk, hogy az elem ltezik. Mire befejezzk

Objektumok az $oszlopNevek tmb bejrst, a $sor tmb mr tartalmazni fogja az $asszoc_sor tmbben tadott elemeket, mgpedig a megfelel sorrendben, a nem meghatrozott rtkeket res karakterlncokkal kitltve. Most mr van kt tagfggvnynk, amelyek segtsgvel sorokat adhatunk a Tablazat tpus objektumok $tablazatSorok nev mezjhez. Errl azonban j lenne valahogy meggyzdni: hinyzik mg egy olyan tagfggvny, amely kpes megjelenteni a tblzatot.

129

A kiir() tagfggvny
A kiir() tagfggvny kirja a bngszbe a tblzat fejlct s a $tablazatSorok tmbt. A fggvny csak nyomkvetsi clokat szolgl. Az ra ksbbi rszben egy sokkal szebb megoldst fogunk ltni. 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>"; } A program magrt beszl. Elszr az $oszlopNevek elemeit rjuk ki, majd a $tablazatSorok sorait. Mivel a $tablazatSorok tulajdonsg ktdimenzis tmb, vagyis a tmb minden eleme maga is egy tmb, ketts ciklust kell hasznlnunk.

sszell a kp
A 8.5. pldaprogram eddigi munknk gymlcst, a Tablazat osztlyt tartalmazza, majd a program vgn ltrehoz egy Tablazat tpus objektumot s meghvja valamennyi tagfggvnyt.

130

8. ra

8.5. program A Tablazat osztly


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: <html> <head> <title>8.5. program A Tablazat osztly</title> </head> <body> <?php class Tablazat { var $tablazatSorok = array(); var $oszlopNevek = array(); var $oszlopszam; function Tablazat( $oszlopNevek ) { $this->oszlopNevek = $oszlopNevek; $this->oszlopszam = count ( $oszlopNevek ); } function ujSor( $sor ) { if ( count ($sor) != $this->oszlopszam ) return false; array_push($this->tablazatSorok, $sor); return true; } function ujNevesSor( $asszoc_sor ) { if ( count ($asszoc_sor) != $this->oszlopszam ) return false; $sor = array(); foreach ( $this->oszlopNevek as $oszlopNev ) { if ( ! isset( $asszoc_sor[$oszlopNev] )) $asszoc_sor[$oszlopNev] = ""; $sor[] = $asszoc_sor[$oszlopNev]; } array_push($this->tablazatSorok, $sor); }

Objektumok

131

8.5. program (folytats)


40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 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>"; } } $proba = new Tablazat( array("a","b","c")); $proba->ujSor( array(1,2,3)); $proba->ujSor( array(4,5,6)); $proba->ujNevesSor( array ( "b"=>0, "a"=>6, "c"=>3 )); $proba->kiir(); ?> </body> </html>

A 8.5. pldaprogram kimenett a 8.1. brn lthatjuk.

8.1. bra
Egy Tablazat tpus objektum kimenete

132

8. ra A kimenet csak akkor jelenik meg helyesen, ha az egy oszlopban lev elemek egyforma hosszak.

Ami mg hinyzik...
Br az osztly hatkonyan elvgzi a munkt, amit neki szntunk, ha tbb idnk s helynk lenne, kibvthetnnk nhny tovbbi szolgltatssal s adatvdelmi lehetsggel. Mivel a PHP gyengn tpusos nyelv, a mi felelssgnk megbizonyosodni arrl, hogy a tagfggvnyeknek tadott paramterek a megfelel tpusak-e. Ehhez a tizenhatodik, az adatkezelsrl szl fejezetben trgyalt fggvnyeket hasznlhatjuk. Ezen kvl rhatnnk tagfggvnyeket a tblzat brmely oszlop szerinti rendezsre is.

Mirt hasznljunk osztlyt?


Mirt jobb osztlyt hasznlni erre a clra ahelyett, hogy egyszeren rnnk nhny tmbkezel fggvnyt? Vagy mirt ne rhatnnk bele egyszeren a programba a tmbkezelst? Azrt, mert ez nem lenne hatkony, mert gy az elvont adatok trolst vgz programokba valami egszen ms is bekerlne. De vajon mirt okoz ez neknk problmt? Elszr is a kdot jra fel lehet hasznlni. Ennek clja jl meghatrozott: bizonyos ltalnos adatkezelst tesz lehetv, amelyet ezutn beilleszthetnk brmely programba, melynek arra van szksge, hogy ilyen tpus adatokat kezeljen s kirjon. Msodszor, a Tablazat osztly tevkeny: megkrhetjk arra, hogy adatokat rjon ki, anlkl, hogy bajldnunk kellene azzal, hogy vgigjrjuk a $tablazatSorok elemeit. Harmadszor, az objektumba egy felletet is beptettnk. Ha elhatrozzuk, hogy ksbb javtunk az osztly mkdsn, anlkl tehetjk meg, hogy a program tbbi rszt mdostannk, ha a korbban ltrehozott tagfggvnyek kvlrl ugyangy viselkednek. Vgl, ltrehozhatunk jabb osztlyokat is, amelyek mr korbban ltrehozott osztlyoktl rklnek, kiterjeszthetik vagy mdosthatjk a mr meglv tagfggvnyeket. Ez teszi igazn hatkonny az objektumkzpont programozst, melynek kulcsszavai az egysgbezrs, az rkls s a kd-jrahasznosts.

Objektumok

133

rkls
Ahhoz, hogy olyan osztlyt hozzunk ltre, amely szolgltatsait szljtl rkli, egy kicsit mdostanunk kell az osztly meghatrozst. A 8.6. pldaprogram ismt a fejezet els felben lev tmakrbl mutat egy pldt.

8.6. program Msik osztlytl rkl osztly


1: <html> 2: <head> 3: <title>8.6. program Msik osztlytl rkl osztly </title> 4: </head> 5: <body> 6: <?php 7: class elso_osztaly 8: { 9: var $nev = "Krisztin"; 10: function elso_osztaly( $n ) 11: { 12: $this->nev = $n; 13: } 14: function koszon() 15: { 16: print "dvzlm! $this->nev vagyok.<BR>"; 17: } 18: } 19: 20: class masodik_osztaly extends elso_osztaly 21: { 22: 23: } 24: 25: $proba = new masodik_osztaly("Krisztin fia"); 26: $proba->koszon(); // kirja, hogy "dvzlm! Krisztin fia vagyok." 27: ?> 28: </body> 29: </html>

134

8. ra Figyeljk meg, hogyan szrmaztattunk az elso_osztaly-tl egy j osztlyt! Az extends kulcsszt az osztly meghatrozsban kell hasznlnunk. Ezzel azt adjuk meg, hogy a kulcssz utn meghatrozott osztly minden tulajdonsgt s tagfggvnyt rklni szeretnnk. Az sszes masodik_osztaly tpus objektum rendelkezni fog egy koszon() nev tagfggvnnyel s egy $nev nev tulajdonsggal, mint ahogyan minden elso_osztaly tpus objektum is rendelkezik ezekkel. Ha ez nem lenne elg, nzzk tovbb a 8.6. pldaprogramot s keressnk szokatlan dolgokat! Pldul figyeljk meg, hogy mg konstruktort sem adtunk meg a masodik_osztaly osztlynak. Akkor hogy lehet az, hogy az objektum $nev tulajdonsga az alaprtelmezett "Krisztin" karakterlncrl arra a "Krisztin fia" karakterlncra vltozott, amit a konstruktor ltrehozsakor tadtunk? Mivel nem hoztunk ltre j konstruktort, a szl objektumtpus (elso_osztaly) konstruktora hvdott meg. Ha egy osztlybl egy msikat szrmaztatunk, amelynek nincsen sajt konstruktora, akkor a szl osztly konstruktora hvdik meg, amikor egy gyermekobjektumot hozunk ltre. Ez a PHP 4-es vltozatnak jdonsga.

A szl tagfggvnyeinek fellrsa


A masodik_osztaly tpus objektumok most pontosan gy viselkednek, mint az elso_osztaly tpusak. Az objektumkzpont vilgban a gyermek osztlyban fell lehet rni a szl osztly tagfggvnyeit, ezltal lehetv vlik, hogy a gyermek objektumok bizonyos tagfggvnyei a szlktl eltren viselkedjenek (tbbalaksg, polimorfizmus), ms tagfggvnyek viszont rintetlenl hagyva ugyangy jelenjenek meg a gyermek osztlyban. A 8.7. pldban lecserljk a masodik_osztaly koszon() tagfggvnyt.

8.7. program Egy fellrt tagfggvny


1: 2: 3: 4: 5: 6: <html> <head> <title>8.7. program Egy fellrt tagfggvny</title> </head> <body> <?php

Objektumok

135

8.7. program (folytats)


7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: class elso_osztaly { var $nev = "Krisztin"; function elso_osztaly( $n ) { $this->nev = $n; } function koszon() { print "dvzlm! $this->nev vagyok.<BR>"; } } class masodik_osztaly extends elso_osztaly { function koszon() { print "Azrt se mondom meg a nevem!<BR>"; } }

$proba = new masodik_osztaly("Krisztin fia"); $proba->koszon(); // kirja, hogy "Azrt se mondom meg a nevem!" 30: ?> 31: </body> 32: </html>

A gyermek koszon() tagfggvnye hvdik meg, mert elnyt lvez a szl hasonl nev tagfggvnyvel szemben.

A fellrt tagfggvny meghvsa


Elfordulhat, hogy a szl osztly szolgltatsait szeretnnk hasznlni, de jakat is be szeretnnk pteni. Az objektumkzpont programozsban ez megvalsthat. A 8.8. pldaprogramban a masodik_osztaly koszon() tagfggvnye meghvja az elso_osztaly tagfggvnyt, amelyet ppen fellr.

136

8. ra

8.8. program Fellrt tagfggvny meghvsa


1: <html> 2: <head> 3: <title>8.8. program Fellrt tagfggvny meghvsa</title> 4: </head> 5: <body> 6: <?php 7: class elso_osztaly 8: { 9: var $nev = "Krisztin"; 10: function elso_osztaly( $n ) 11: { 12: $this->nev = $n; 13: } 14: function koszon() 15: { 16: print "dvzlm! $this->nev vagyok.<BR>"; 17: } 18: } 19: 20: class masodik_osztaly extends elso_osztaly 21: { 22: function koszon() 23: { 24: print "Azrt se mondom meg a nevem! - "; 25: elso_osztaly::koszon(); 26: } 27: } 28: 29: $proba = new masodik_osztaly("Krisztin fia"); 30: $proba->koszon(); // kirja, hogy "Azrt se mondom meg a nevem! - dvzlm! Krisztin fia vagyok." 31: ?> 32: </body> 33: </html> A szuloOsztalyNeve::tagfuggvenyNeve() smt hasznlva brmely fellrt tagfggvnyt meghvhatunk. A sma j, a PHP 3-as vltozatban mg hibt okozott volna.

Objektumok

137

Egy plda az rklsre


Mr lttuk, hogyan tud egy osztly egy msiktl rklni, annak tagfggvnyeit fellrni s kpessgeit kibvteni. Most a tanultaknak hasznt is vehetjk. Ksztsnk egy osztlyt, amely a 8.5. pldaprogramban szerepl Tablazat osztlytl rkl! Az j osztly neve HTMLTablazat lesz. Ezt az osztly azrt szksges, hogy kikszblje a Tablazat kiir() tagfggvnynek szpsghibit s a bngsz lehetsgeit kihasznlva szp kimenetet eredmnyezzen.

A HTMLTablazat sajt tulajdonsgai


A HTMLTablazat arra szolgl, hogy a mr korbban ltrehozott Tablazat tpus objektumot szabvnyos HTML formban jelenthessk meg. Pldnkban a tblzat cellPadding s a cellk bgColor tulajdonsgai mdosthatk, a vals programokban azonban termszetesen tbb tulajdonsgot szeretnnk majd belltani. class HTMLTablazat extends Tablazat { var $hatterSzin; var $cellaMargo = 2; } Egy j osztlyt hoztunk ltre, amely a Tablazat osztlytl fog rklni. Kt j tulajdonsgot adtunk meg, az egyiknek a kezdrtkt is meghatroztuk.

A konstruktor
Mr lthattuk, hogy a szl konstruktora hvdik meg, ha a gyermekosztlyban nem hozunk ltre konstruktort. Most azonban azt szeretnnk, hogy konstruktorunk tbbre legyen kpes, mint amennyit a Tablazat osztly konstruktora tett, ezrt azt fell kell rnunk. function HTMLTablazat( $oszlopNevek, $hatter="#ffffff" ) { Tablazat::Tablazat($oszlopNevek); $this->hatterSzin=$hatter; } A HTMLTablazat paramtereiben az oszlopok neveinek tmbjt, illetve egy karakterlncot vr. A karakterlnc lesz a HTML tblzat bgColor tulajdonsga. Megadtunk egy kezdeti rtket is, gy ha nem adunk t msodik paramtert a konstruktornak, a httr szne fehr lesz. A konstruktor meghvja a Tablazat osztly konstruktort a kapott oszlopnv-tmbbel. A lustasg erny a programozs tern: hagyjuk, hogy a Tablazat konstruktora tegye a dolgt s a tovbbiakban

138

8. ra nem foglalkozunk a tblzat kezelsvel (ha egyszer mr megrtuk, akkor hasznljuk is). A konstruktor msik dolga a HTMLTablazat hatterSzin tulajdonsgnak belltsa. Ha a gyermek osztly rendelkezik konstruktorral, akkor a szl osztly konstruktora mr nem kerl automatikusan meghvsra. Ezrt ha szksges, a gyermek osztlybl kell meghvni a szl konstruktort.

A cellaMargoAllit() tagfggvny
A szrmaztatott osztly sajt, j tagfggvnyeket is ltrehozhat. A cellaMargoAllit() tagfggvny segtsgvel a felhasznl a tblzat szvege s a tblzat kztti res rs nagysgt llthatja be. Persze megtehetn ezt a cellaMargo tulajdonsg kzvetlen elrsvel is ,de ez nem tl j tlet. Alapszably, hogy az objektumot hasznl szemly rdekben legjobb tagfggvnyeket ltrehozni erre a clra. Az osztlyok bonyolultabb leszrmazottaiban a cellaMargoAllit() tagfggvny esetleg ms tulajdonsgokat is knytelen mdostani, hogy megvltoztathassa a marg mrett. Sajnos nincs elegns md ennek a kiknyszertsre. function cellaMargoAllit( $margo ) { $this->cellaMargo = $margo; }

A kiir() tagfggvny
A kiir() tagfggvny fellrja a Tablazat osztly azonos nev tagfggvnyt. Ez a fggvny a szl osztly logikjval azonos mdon rja ki a tblzatot, de a HTML table elemt hasznlja a tblzat formzsra. 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";

Objektumok foreach ( $this->tablazatSorok as $sor => $cellak ) { print "<tr>\n"; foreach ( $cellak as $cella ) print "<td bgColor=\"$this ->hatterSzin\">$cella</td>\n"; print "</tr>\n"; } print "</table>"; } Ha a Tablazat osztlybeli vltozat vilgos, az itteni kiir() tagfggvny is elg ttekinthet kell, hogy legyen. Elszr az $oszlopNevek elemeit rjuk ki, majd a $tablazatSorok sorait. A formzst a HTML table elemnek cellPadding s bgColor tulajdonsgai segtsgvel szablyozhatjuk.

139

A Tablazat s a HTMLTablazat osztlyok a maguk teljessgben


A 8.9. pldaprogramban a Tablazat s a HTMLTablazat pldkat egy helyen lthatjuk. Ltrehozunk egy HTMLTablazat tpus objektumot, megvltoztatjuk cellaMargo tulajdonsgt, runk bele nhny sort, majd meghvjuk a kiir() tagfggvnyt. A valsgban az adatok minden bizonnyal kzvetlenl egy adatbzisbl szrmaznnak.

8.9. program A Tablazat s a HTMLTablazat osztlyok


1: <html> 2: <head> 3: <title>8.9. program A Tablazat s a HTMLTablazat osztlyok</title> 4: </head> 5: <body> 6: <?php 7: class Tablazat 8: { 9: var $tablazatSorok = array(); 10: var $oszlopNevek = array(); 11: var $oszlopszam;

140

8. ra

8.9. program (folytats)


12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: function Tablazat( $oszlopNevek ) { $this->oszlopNevek = $oszlopNevek; $this->oszlopszam = count ( $oszlopNevek ); } function ujSor( $sor ) { if ( count ($sor) != $this->oszlopszam ) return false; array_push($this->tablazatSorok, $sor); return true; } function ujNevesSor( $asszoc_sor ) { if ( count ($asszoc_sor) != $this->oszlopszam ) return false; $sor = array(); foreach ( $this->oszlopNevek as $oszlopNev ) { if ( ! isset( $asszoc_sor[$oszlopNev] )) $asszoc_sor[$oszlopNev] = ""; $sor[] = $asszoc_sor[$oszlopNev]; } array_push($this->tablazatSorok, $sor); } 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"; }

Objektumok

141

8.9. program (folytats)


52: print "</pre>"; 53: } 54: } 55: 56: class HTMLTablazat extends Tablazat 57: { 58: var $hatterSzin; 59: var $cellaMargo = 2; 60: function HTMLTablazat( $oszlopNevek, $hatter="#ffffff" ) 61: { 62: Tablazat::Tablazat($oszlopNevek); 63: $this->hatterSzin=$hatter; 64: } 65: 66: function cellaMargoAllit( $margo ) 67: { 68: $this->cellaMargo = $margo; 69: } 70: function kiir() 71: { 72: print "<table cellPadding=\"$this->cellaMargo\" border=1>\n"; 73: print "<tr>\n"; 74: foreach ( $this->oszlopNevek as $oszlopNev ) 75: print "<th bgColor=\"$this->hatterSzin\" >$oszlopNev</th>"; 76: print "</tr>\n"; 77: foreach ( $this->tablazatSorok as $sor => $cellak ) 78: { 79: print "<tr>\n"; 80: foreach ( $cellak as $cella ) 81: print "<td bgColor=\"$this->hatterSzin\" >$cella</td>\n"; 82: print "</tr>\n"; 83: } 84: print "</table>"; 85: } 86: } 87:

142

8. ra

8.9. program (folytats)


88: $proba = new HTMLTablazat( array("a","b","c"), "#00FF00"); 89: $proba->cellaMargoAllit( 7 ); 90: $proba->ujSor( array(1,2,3)); 91: $proba->ujSor( array(4,5,6)); 92: $proba->ujNevesSor( array ( "b"=>0, "a"=>6, "c"=>3 )); 93: $proba->kiir(); 94: ?> 95: </body> 96: </html> A 8.9. pldaprogram kimenett a 8.2. brn lthatjuk.

8.2. bra
Egy HTMLTablazat tpus objektum kimenete

Mirt alkalmazzunk rklst?


Mirt vgtuk kett a feladatot egy Tablazat s egy HTMLTablazat rszre? Biztos, hogy idt s fradsgot takarthattunk volna meg, ha a HTML tblzat kpessgeit beptjk a Tablazat osztlyba? A vlasz kulcsa a rugalmassg krdse. Kpzeljk el, hogy egy gyfl azt a megbzst adja neknk, hogy hozzunk ltre egy osztlyt, amely olyan tblzatok kezelsre kpes, ahol a tblzat oszlopainak neve van. Ha egyetlen rszbl ll osztlyt hozunk ltre, amelybe minden szolgltatst (a HTML megjelents minden apr rszletvel) beleptnk, els ltsra minden szpnek s jnak tnhet. De ha visszajn az gyfl, hogy szeretn, ha a program zlsesen formzott szveges kimenetet eredmnyezne, valsznleg jabb tagfggvnyeket kellene megprblnunk felvenni, melyek megoldjk a problmt.

Objektumok Egy-kt hten bell gyfelnk rbred, hogy szeretn a programot elektronikus levelek kldsre hasznlni s ha mr gyis fejlesztnk a programon, a cg bels hlzata az XML nyelvet hasznlja, nem lehetne bepteni a tmogatst ehhez is? Ennl a pontnl, ha minden szolgltatst egyetlen osztlyba ptnk bele, a program kezd ormtlanul nagy lenni, esetleg a teljes trst fontolgatjuk. Jtsszuk el ezt a forgatknyvet a Tablazat s a HTMLTablazat osztlyainkkal! Alaposan sikerlt elklnteni az adatok feldolgozst s megjelentst. Ha gyfelnk azzal a krssel fordul hozznk, hogy szeretn a tblzatot fjlba menteni, csak egy j osztlyt kell szrmaztatnunk a Tablazat osztlybl. Nevezzk ezt TablazatFajl osztlynak. Eddigi osztlyainkhoz hozz sem kell nylnunk. Ez igaz a TablazatLevel s az XMLTablazat osztlyokra is. A 8.3. bra az osztlyok kztti kapcsolatokat (fggsgeket, leszrmazsokat) mutatja.

143

8.3. bra
Kapcsolatok a Tablazat osztly s gyermekei kztt

St, tudjuk, hogy minden, a Tablazat osztlybl szrmaztatott osztlynak van egy kiir() tagfggvnye, gy azokat egy tmbbe is gyjthetjk. Azutn vgigszaladunk a tmbn, meghvjuk minden elem kiir() tagfggvnyt s nem kell azzal foglalkoznunk, hogy az adott elem a Tablazat melyik leszrmazottja, a megfelel kir fggvny kerl meghvsra. Egy egyszer Tablazat osztlybl szrmaztatott tpus objektumok tmbje segtsgvel elektronikus leveleket rhatunk, illetve HTML, XML vagy szveges llomnyokat llthatunk el a kiir() fggvny meghvsval.

sszefoglals
Sajnos nincs r md, hogy az objektumkzpont programozst minden szempontbl megvizsgljuk egy rvidke ra alatt, de remlem, hogy a fontosabb lehetsgeket sikerlt bemutatni. Azt, hogy milyen mrtkben hasznlunk osztlyokat a programokban, neknk kell eldntennk. Az objektumkzpont megkzeltst intenzven hasznl programok ltalban nmileg tbb erforrst ignyelnek, mint a hagyomnyosak, viszont a rugalmassg s tlthatsg jelentsen n.

144

8. ra Ebben az rban arrl tanultunk, hogyan hozhatunk ltre osztlyokat s bellk objektumpldnyokat. Megtanultunk tulajdonsgokat s tagfggvnyeket ltrehozni s elrni. Vgl azt is megtanultuk, hogyan hozhatunk ltre j osztlyokat ms osztlyokbl az rkls s a tagfggvny-fellrs segtsgvel.

Krdsek s vlaszok
Ebben az rban nhny bartsgtalan fogalommal tallkoztunk. Valban szksges az objektumkzpontsgot megrteni ahhoz, hogy j PHP programoz vlhasson az emberbl? Erre a rvid vlasz: nem. A legtbb PHP programoz alig vagy egyltaln nem r objektumkzpont programot. Az objektumkzpont megkzelts nem tesz szmunkra olyan dolgokat lehetv, amelyek eddig elrhetetlenek voltak. A dolog lnyege a programok szervezsben, az egyszer megrt programrszek jrahasznostsban s a knny fejleszthetsgben rejlik. Mg ha el is hatroznnk, hogy soha nem fogunk objektumkzpont programot rni, elfordulhat, hogy bele kell javtanunk msok ltal rt programokba, amelyekben osztlyok vannak, ezrt rtennk kell a szemllet alapjait. Ez az ra ebben is segtsget nyjthat. Nem rtem a $this vltoz szerept. Egy osztlyon bell szksges az osztly tagfggvnyeit vagy tulajdonsgait elrni. Ekkor a $this vltozt kell hasznlni, amely egy mutat az adott objektumra, amelynek valamely tagfggvnyt meghvtuk. Mivel a $this vltoz mutat (hivatkozs), sszetevinek elrshez a -> mveletjelet kell hasznlni.

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Hogyan hoznnk ltre egy uresOsztaly nev osztlyt, amelynek nincsenek tagfggvnyei s tulajdonsgai? 2. Adott egy uresOsztaly nev osztly. Hogyan hoznnk ltre egy pldnyt? 3. Hogyan lehet az osztlyba egy tulajdonsgot felvenni? 4. Hogyan kell a konstruktor nevt megvlasztani? 5. Hogyan lehet egy osztlyban konstruktort ltrehozni?

Objektumok 6. Hogyan lehet ltrehozni kznsges tagfggvnyeket? 7. Hogyan lehet osztlyon bellrl az osztly tulajdonsgaihoz s tagfggvnyeihez hozzfrni? 7. Hogyan lehet osztlyon kvlrl az osztly tulajdonsgaihoz s tagfggvnyeihez hozzfrni? 8. Mit kell tennnk, ha azt szeretnnk, hogy egy osztly ms osztlytl rkljn?

145

Feladatok
1. Hozzuk ltre a Szamolo nev osztlyt, amely kt egsz szmot trol. rjunk hozz egy kiszamol() nev tagfggvnyt, amely kirja a kt szmot a bngszbe! 2. Hozzuk ltre az Osszead osztlyt, amely a Szamolo osztlytl rkl. rjuk t ennek kiszamol() tagfggvnyt gy, hogy az a kt tulajdonsg sszegt rja ki a bngszbe! 3. Az elz feladathoz hasonlan mdon ksztsk el a Kivon osztlyt!

III. RSZ
Munka a PHP-vel
9. ra 10. ra 11. ra 12. ra 13. ra 14. ra 15. ra 16. ra 17. ra 18. ra 19. ra 20. ra 21. ra 22. ra rlapok Fjlok hasznlata A DBM fggvnyek hasznlata Adatbzisok kezelse MySQL Kapcsolat a klvilggal Dinamikus kpek kezelse Dtumok kezelse Az adatok kezelse Karakterlncok kezelse A szablyos kifejezsek hasznlata llapotok trolsa stikkel s GET tpus lekrdezsekkel llapotok trolsa munkamenet-fggvnyekkel Munka kiszolgli krnyezetben Hibakeress

9. RA
rlapok
A knyv eddigi pldiban egy nagyon fontos dolgot nem lttunk. Ltrehoztunk vltozkat s tmbket, ksztettnk s meghvtunk klnbz fggvnyeket, klnfle objektumokkal dolgoztunk, eddigi ismereteink azonban rtelmetlenek, amg a felhasznl ltal megadott adatokat kezelni nem tudjuk. Ebben az rban ezt a tmakrt tekintjk t. A Vilghln alapveten a HTML rlapokon keresztl ramlik az informci a felhasznl s a kiszolgl kztt. A PHP-t gy terveztk, hogy a kitlttt HTML rlapokat knnyen fel tudja dolgozni. Ebben az rban a kvetkezket tanuljuk meg: Hogyan frjnk hozz a krnyezeti vltozkhoz s hogyan hasznljuk azokat? Hogyan frjnk hozz az rlapmezkben megadott informcikhoz? Hogyan dolgozzunk az rlapok tbb elem kivlasztst engedlyez elemeivel?

150

9. ra Hogyan ksztsnk olyan kdot, amely egyszerre tartalmazza a HTML rlapot s az ezt kezel PHP programot? Hogyan mentsk az llapotot rejtett mezkkel? Hogyan irnytsuk a felhasznlt j oldalra? Hogyan ksztsnk fjlfeltlt HTML rlapot s hogyan rjunk olyan PHP programot, amely kezeli ezt?

Globlis s krnyezeti vltozk


Mieltt elksztennk els igazi rlapunkat, kis kitrt kell tennnk, hogy jra ttekintsk a globlis vltozkat. A globlis vltozkkal elszr a fggvnyekrl szl hatodik rban tallkoztunk. A globlis vltozk azok a vltozk, amelyeket a program legfels szintjn, azaz a fggvnyeken kvl vezettnk be. Minden fggvny szmra elrhet a beptett $GLOBALS nev tmb. A $GLOBALS tmb hasznlatt lthatjuk a 9.1. pldban, amelyben egy ciklussal kirjuk programunk sszes globlis vltozjt.

9.1. program A $GLOBALS tmb elemeinek kirsa


1: <html> 2: <head> 3: <title>9.1. program A $GLOBALS tmb elemeinek kirsa</title> 4: </head> 5: <body> 6: <?php 7: $user1 = "Judit"; 8: $user2 = "Istvn"; 9: $user3 = "Jnos"; 10: foreach ( $GLOBALS as $kulcs=>$ertek ) 11: { 12: print "\$GLOBALS[\"$kulcs\"] == $ertek<br>"; 13: } 14: ?> 15: </body> 16: </html>

rlapok Hrom vltozt vezettnk be s a $GLOBALS tmb elemein vgiglpkedve kirtuk a vltozk neveit s rtkeit a bngszben. Lthatjuk az ltalunk megadott vltozkat, de a program ezeken kvl msokat is kirt, a PHP ugyanis automatikusan bevezet nhny globlis vltozt, amelyek a kiszolgl s az gyfl krnyezett rjk le. Ezeket a vltozkat krnyezeti vltozknak nevezzk. A kiszolgltl, a rendszertl s a belltsoktl fggen klnfle krnyezeti vltozk ltezhetnek, ezek ismerete rendkvl fontos. A 9.1. tblzatban a leggyakoribb krnyezeti vltozkat soroltuk fel. A krnyezeti vltozk rtke kzvetlenl vagy a $GLOBALS tmb rszeknt rhet el.

151

9.1. tblzat Krnyezeti vltozk


Vltoz $HTTP_USER_AGENT
$REMOTE_ADDR $REQUESTED_METHOD $QUERY_STRING

Tartalma A bngsz neve s


vltozatszma Az gyfl IP cme A krelem mdja (GET vagy POST) A GET krelmeknl az URL-hez kapcsolt kdolt adat

Plda Mozilla/4.6 (X11;I;


Linux2.2.6-15apmac ppc) 158.152.55.35 POST nev=janos&cim= ismeretlen /php-konyv/urlapok/ 9.14.program.php?nev= janos http://www.proba.hu/ egy_oldal.html

$REQUEST_URI

A krelem teljes cme a lekrdez karaktersorozattal

$HTTP_REFERER

Az oldal cme, amelyrl a krelem rkezett

A PHP ltrehoz ms krnyezeti vltozkat is. Pldul a $GLOBALS["PHP_SELF"] az ppen fut program elrsi tjt adja meg. A szerz rendszern az rtk a kvetkez volt: /php-konyv/urlapok/9.1.program.php

152

9. ra A vltoz rtke kzvetlenl is elrhet, $PHP_SELF nven. Ebben az rban mg sokszor fogjuk hasznlni ezt a vltozt. A HTML oldalt ler s az rlapot elemz PHP kdot gyakran troljuk egy llomnyban. Az oldal nevnek trolshoz a $PHP_SELF vltoz rtkt a HTML FORM elemnek ACTION paramterhez rendeljk. A $GLOBALS tmb ezenkvl mg sok msra is hasznlhat.

Adatok bekrse a felhasznltl


Jelenleg a HTML s PHP kdot kln llomnyban troljuk. A 9.2. pldban egy egyszer HTML rlap kdjt lthatjuk.

9.2. program Egy egyszer HTML rlap


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: <html> <head> <title>9.2. program Egy egyszer HTML rlap</title> </head> <body> <form action="9.3.program.php" method="GET"> <input type="text" name="felhasznalo"> <br> <textarea name="cim" rows="5" cols="40"> </textarea> <br> <input type="submit" value="rendben"> </form> </body> </html>

Egy HTML rlapot hoztunk ltre, amely egy "felhasznalo" nev szvegmezt, egy "cim" nev szvegterletet, s egy gombot tartalmaz. Knyvnk nem foglakozik rszletesen a HTML ismertetsvel, ha mgis nehznek talljuk a pldkat, olvassunk el egy, a HTML nyelvvel foglalkoz ktetet vagy szmtgpes lerst. A FORM elem ACTION paramtere a 9.3.program.php fjlra mutat, amely feldolgozza az rlapon megadott adatokat. Mivel az ACTION csak a fjl nevt adja meg, a HTML s PHP kdot tartalmaz fjloknak egy knyvtrban kell lennik. A 9.3. pldaprogram kirja a felhasznl ltal megadott informcikat.

rlapok

153

9.3. progran A 9.2. plda rlapjnak feldolgozsa


1: <html> 2: <head> 3: <title>9.3. program A 9.2. plda rlapjnak feldolgozsa</title> 4: </head> 5: <body> 6: <?php 7: print "dvzlet <b>$felhasznalo</b><P>\n\n"; 8: print "A cme:<P>\n\n<b>$cim</b>"; 9: ?> 10: </body> 11: </html>

Ez a knyv els olyan programja, amelyet nem hivatkozson keresztl hvunk meg s nem kzvetlenl a bngszbe rjuk be a cmt. A 9.3. pldban tallhat kdot az 9.3.program.php fjlban troljuk. A fjlban lv kdot akkor hvjuk meg, amikor a felhasznl kitlti a 9.2. pldban tallhat rlapot. A program a $felhasznalo s a $cim vltozk rtkt rja ki, amelyek a HTML rlap "felhasznalo" szvegmezjnek s "cim" terletnek rtkt tartalmazzk. Lthat, hogy a PHP 4 segtsgvel milyen egyszeren kezelhetek az rlapok. Brmilyen megadott informci globlis vltozknt hozzfrhet s a vltozk neve megegyezik a megfelel HTML elem nevvel.

Tbb elem kivlasztsa a SELECT elemmel


Elz pldnkban olyan HTML rlap szerepelt, amely egy elemhez egyetlen rtk hozzrendelst engedlyezte. Most megtanuljuk a SELECT elem kezelst, melynek segtsgvel tbb elem kivlasztst engedlyezhetjk. Ha a SELECT elemnek egyszer nevet adunk: <select name="termekek" multiple> akkor a feldolgoz program csak az egyik kivlasztott elemhez fr hozz. Ha minden elemet el szeretnnk rni a programbl, az elem neve utn rjunk res szgletes zrjeleket. Ezt lthatjuk a 9.4. pldban.

154

9. ra

9.4. program SELECT elemet tartalmaz HTML rlap


1: <html> 2: <head> 3: <title>9.4. program SELECT elemet tartalmaz HTML rlap</title> 4: </head> 5: <body> 6: <form action="9.5.program.php" method="POST"> 7: <input type="text" name="felhasznalo"> 8: <br> 9: <textarea name="cim" rows="5" cols="40"> 10: </textarea> 11: <br> 12: <select name="termekek[]" multiple> 13: <option>Ultrahangos csavarhz 14: <option>Tricorder 15: <option>ORAC AI 16: <option>HAL 2000 17: </select> 18: <br> 19: <input type="submit" value="rendben"> 20: </form> 21: </body> 22: </html> Az rlapot feldolgoz programban a SELECT elemben kivlasztott adatok a $termekek tmbben tallhatak. Ezt mutatjuk be a 9.5. pldban

9.5. program A 9.4. pldban ltott rlap feldolgozsa


1: <html> 2: <head> 3: <title>9.5. program A 9.4. pldban ltott rlap feldolgozsa</title> 4: </head> 5: <body> 6: <?php 7: print "dvzlet <b>$felhasznalo</b><P>\n\n"; 8: print "A cme:<P>\n\n<b>$cim</b>"; 9: print "A kvetkez termkeket vlasztotta:<p>\n\n"; 10: print "<ul>\n\n";

rlapok

155

9.5. program (folytats)


11: 12: 13: 14: 15: 16: 17: 18: foreach ( $termekek as $termek ) { print "<li>$termek<br>\n"; } print "</ul>"; ?> </body> </html>

Nem csak a SELECT elem engedlyezi tbb elem kivlasztst. Ha tbb jellngyzetnek ugyanazt a nevet adjuk, ahol a felhasznl tbb elemet is kivlaszthat, csak az utols kivlasztott rtket kapjuk meg, de ha a nevet res szgletes zrjelek kvetik, az adott nev elemeket a PHP tmbknt kezeli. A 9.4. plda SELECT elemt jellngyzetekre cserlhetjk s ugyanazt a hatst rjk el: <input <input <input <input type="checkbox" name="termekek[]" value="Ultrahangos csavarhz">Ultrahangos csavarhz<br> type="checkbox" name="termekek[]" value="Tricorder">Tricorder<br> type="checkbox" name="termekek[]" value= "ORAC AI">ORAC AI<br> type="checkbox" name="termekek[]" value= "HAL 2000">HAL 2000<br>

Az rlap minden mezjnek hozzrendelse egy tmbhz


Az eddig megtanult mdszerek mindaddig jl mkdnek, amg programunk tudja, milyen mezkkel dolgozik. Gyakran azonban olyan programra van szksgnk, amely az rlap vltozsaihoz alkalmazkodik vagy egyszerre tbbfle rlapot kpes kezelni, anlkl, hogy kevern a mezk neveit. A PHP 4 globlis vltozi erre a problmra is megoldst nyjtanak. Attl fggen, hogy a kitlttt rlap GET vagy POST metdust hasznlt, elrhetv vlnak a $HTTP_GET_VARS vagy a $HTTP_POST_VARS vltozk. Ezek az asszociatv tmbk tartalmazzk az rlap mezinek neveit s a hozzjuk rendelt rtkeket. A 9.6. plda azt mutatja be, hogyan listzhat ki az rlap minden mezje egy GET krelem esetn.

156

9. ra

9.6. program A $HTTP_GET_VARS tmb hasznlata


1: <html> 2: <head> 3: <title>9.6. program A $HTTP_GET_VARS tmb hasznlata</title> 4: </head> 5: <body> 6: <?php 7: foreach ( $HTTP_GET_VARS as $kulcs => $ertek ) 8: { 9: print "$kulcs == $ertek<BR>\n"; 10: } 11: ?> 12: </body> 13: </html>

A fenti kd a GET krelmen keresztl rkezett paramterek neveit s rtkeit rja ki. Termszetesen itt mg nem kezeltk azt az esetet, amikor valamelyik tadott paramter tmb. Ha a 9.4. pldaprogrammal olyan HTML rlaprl rkez adatok feldolgozst vgeztetjk, amelyben tbb elem kivlasztst engedlyez SELECT mez szerepel, valami hasonlt olvashatunk: felhasznalo == Kiss Ivn cim == Budapest, Magyarorszg termekek == Array A termekek tmbt tartalmazza a $HTTP_GET_VARS tmb, de kdunk mg nem tudja ezt kezelni. A 9.7. pldaprogram ellenrzi, hogy a paramter tpusa tmb-e s ha igen, kirja a tmb elemeit.

9.7. program A $HTTP_GET_VARS tmb hasznlata, ha tmbt tartalmaz


1: <html> 2: <head> 3: <title>9.7. program A $HTTP_GET_VARS tmb hasznlata, ha tmbt tartalmaz</title> 4: </head> 5: <body> 6: <?php

rlapok

157

9.7. program (folytats)


7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: foreach ( $HTTP_GET_VARS as $kulcs => $ertek ) { if ( gettype( $ertek ) == "array" ) { print "$kulcs == <br>\n"; foreach ( $ertek as $tombelem ) print ".........$tombelem<br>"; } else { print "$kulcs == $ertek<br>\n"; } } ?> </body> </html>

Mieltt a forearch segtsgvel a $HTTP_GET_VARS tmb elemein vgiglpkednnk, a gettype() fggvnnyel ellenrizzk, hogy a kvetkez elem tmb-e. Ha az elem tmb, egy msodik foreach segtsgvel vgiglpkednk az elemein s kirjuk azokat a bngszbe.

Klnbsgek a GET s a POST tovbbts kztt


A program akkor rugalmas, ha el tudja dnteni, hogy $HTTP_POST_VARS vagy $HTTP_GET_VARS tmbbl olvassa-e ki az elemeket. A tovbbts tpust (GET vagy POST) a legtbb rendszerben a $REQUEST_METHOD krnyezeti vltoz tartalmazza, rtke rtelemszeren "get" vagy "post". rdemes tudni, hogy a $HTTP_POST_VARS tmb csak POST tovbbtsi md esetn tartalmaz elemeket. A 9.8. program mindig a megfelel tmbbl olvassa ki a paramtereket.

158

9. ra

9.8. program A GET s POST krelmek kezelse


1: <html> 2: <head> 3: <title>9.8. program A GET s POST krelmek kezelse</title> 5: </head> 6: <body> 7: <?php 8: $PARAMETEREK = ( count( $HTTP_POST_VARS ) ) 9: ? $HTTP_POST_VARS : $HTTP_GET_VARS; 10: foreach ( $PARAMETEREK as $kulcs => $ertek ) 11: { 12: if ( gettype( $ertek ) == "array" ) 13: { 14: print "$kulcs == <br>\n"; 15: foreach ( $ertek as $tombelem ) 16: print ".........$tombelem<br>"; 17: } 18: else 19: { 20: print "$kulcs == $ertek<br>\n"; 21: } 22: } 23: ?> 24: </body> 25: </html> A feltteles mveletjellel belltjuk a $PARAMETEREK vltoz rtkt. A count() fggvnnyel ellenrizzk, hogy a $HTTP_POST_VARS vltoz tartalmaz-e elemeket. A count() visszatrsi rtke a tmb elemeinek szma: pozitv, ha a paramterben megadott vltoz tartalmaz elemeket s 0 (false), ha nem. Ha a $HTTP_POST_VARS tartalmaz elemeket, akkor a $PARAMETEREK vltozt egyenlv tesszk vele, egybknt a $PARAMETEREK a $HTTP_GET_VARS rtkt veszi fel. Most mr kirathatjuk a $PARAMETEREK tmb tartalmt a korbban ltott mdon.

rlapok

159

PHP s HTML kd sszekapcsolsa egy oldalon


Nhny esetben szksg lehet r, hogy az rlapot ler HTML kdot s az rlapot kezel PHP kdot egyetlen fjlban troljuk. Ez akkor lehet hasznos, amikor a felhasznl szmra tbbszr adjuk t ugyanazt az rlapot. Termszetesen kdunk sokkal rugalmasabb, ha dinamikusan rjuk meg, de ekkor elvesztjk a PHP hasznlatnak elnyt. A HTML s PHP kdot ne keverjk a kzs fjlon bell, mert gy a forrs nehezebben lesz olvashat s mdosthat. Ahol lehetsges, ksztsnk HTML kdbl meghvhat PHP fggvnyeket, amelyeket ksbb fel tudunk hasznlni. A kvetkez pldkban olyan oldalt fejlesztnk, amely az rlaprl berkez egsz szmrl megmondja, hogy kisebb vagy nagyobb-e egy elre megadott egsz rtknl. A 9.9. pldban a fenti feladat megoldst tartalmaz HTML kdot lthatjuk. A kd egy egyszer szvegmezt s nmi PHP kdot tartalmaz.

9.9. program Sajt magt meghv HTML kd


1: <html> 2: <head> 3: <title>9.9. program Sajt magt meghv HTML kd</title> 4: </head> 5: <body> 6: <form action="<?php print $PHP_SELF?>" method="POST"> 7: Ide rja a tippjt: <input type="text" name="tipp"> 8: </form> 9: </body> 10: </html> A fenti rlap sajt magt hvja meg, mert a FORM elem ACTION paramternek a $PHP_SELF rtket adtunk. Vegyk szre, hogy nem ksztettnk gombot, amely elkldi a bert szmot. Az jabb bngszk a szvegmez kitltse s az ENTER lenyomsa utn automatikusan elkldik a megadott adatot, viszont nhny rgebbi bngsz ezt nem teszi meg. A 9.9. pldban lv program nem dinamikus, hiszen nem r ki semmit, ami a felhasznltl fgg. A 9.10. pldban tovbbi PHP kdot ptnk az oldalba. Elszr meg kell adnunk a szmot, amit a felhasznlnak ki kell tallnia. A teljes vltozatban valsznleg vletlenszmot lltannk el, most azonban egyszeren megadjuk, mondjuk a 42-t. Ezutn megnzzk, hogy az rlapot kitltttk-e mr, klnben

160

9. ra olyan vltozval szmolnnk, amely mg nem ltezik. A $tipp vltoz ltezsnek ellenrzsvel megtudhatjuk, hogy az rlapot kitltttk-e mr. Amikor az rlap elkldi a "tipp" paramtert, a $tipp vltoz globlis vltozknt hozzfrhet lesz a programban. A $tipp vltoz ltezse esetn egszen biztosak lehetnk benne, hogy az rlapot a felhasznl kitlttte, gy elvgezhetjk a tovbbi vizsglatokat.

9.10. program Szmkitalls PHP program


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: <?php $kitalalando_szam = 42; $uzenet = ""; if ( ! isset( $tipp ) ) { $uzenet = "dvzlm a szmkitalls jtkban!"; } elseif ( $tipp > $kitalalando_szam ) { $uzenet = "A(z) $tipp tl nagy, prbljon egy kisebbet!"; } elseif ( $tipp < $kitalalando_szam ) { $uzenet = "A(z) $tipp tl kicsi, prbljon egy nagyobbat!"; } else // egyenlk kell, hogy legyenek { $uzenet = "Telitallat!"; } ?> <html> <head> <title>9.10. program Szmkitalls PHP program</title> </head> <body> <h1> <?php print $uzenet ?> </h1> <form action="<?php print $PHP_SELF?>" method="POST"> Ide rja a tippjt: <input type="text" name="tipp"> </form> </body> </html>

rlapok A program trzsben egy if szerkezettel vizsgljuk a $tipp vltozt s adunk rtket az $uzenet vltoznak. Ha a $tipp vltoz mg nem ltezik, a felhasznl csak most lpett az oldalra, ezrt dvzljk. Klnben megvizsgljuk az elre megadott szmot s a $tipp rtkt, s ez alapjn rendeljk az $uzenet vltozhoz a megfelel szveget. Vgl a HTML oldal trzsben csak ki kell rnunk az $uzenet rtkt. A program persze mg tovbbfejleszthet. A PHP s a HTML kdot sztvlasztva tartva egy grafikus knnyen mdosthatja az oldalt, a programoz kzremkdse nlkl.

161

llapot mentse rejtett mezkkel


A 9.10. pldban tallhat program nem tudja, hogy a felhasznl hnyszor tippelt, egy rejtett mez bevezetsvel azonban ez is szmon tarthat. A rejtett mez ugyangy mkdik, mint a szvegmez, de a felhasznl nem ltja, hacsak meg nem nzi a HTML forrskdot. A 9.11. pldban tallhat programban bevezetnk egy rejtett mezt, amely a tallgatsok szmt tartalmazza.

9.11. program llapot mentse rejtett mezvel


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: <?php $kitalalando_szam = 42; $uzenet = ""; $probalkozasok = ( isset( $probalkozasok ) ) ? ++$probalkozasok : 0; if ( ! isset( $tipp ) ) { $uzenet = "dvzlm a szmkitalls jtkban!"; } elseif ( $tipp > $kitalalando_szam ) { $uzenet = "A(z) $tipp tl nagy, prbljon egy kisebbet!"; } elseif ( $tipp < $kitalalando_szam ) { $uzenet = "A(z) $tipp tl kicsi, prbljon egy nagyobbat!"; } else // egyenlk kell, hogy legyenek { $uzenet = " Telitallat!"; }

162

9. ra

9.11. program (folytats)


21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: $tipp = (int) $tipp; ?> <html> <head> <title>9.11. program llapot mentse rejtett mezvel</title> </head> <body> <h1> <?php print $uzenet ?> </h1> Tippels sorszma: <?php print $probalkozasok?> <form action="<?php print $PHP_SELF?>" method="POST"> Ide rja a tippjt: <input type="text" name="tipp" value="<?php print $tipp?>"> <input type="hidden" name="probalkozasok" value="<?php print $probalkozasok?>"> </form> </body> </html>

A rejtett mez neve "probalkozasok". A PHP segtsgvel kirjuk a "probalkozasok" s a "tipp" mez rtkt, hogy a felhasznl tudja, hnyszor prblkozott s mit tippelt utoljra. Ez az eljrs akkor lehet hasznos, amikor a kitlttt rlapot elemezzk. Ha az rlapot rosszul tltttk ki, a felhasznl tudni fogja, mit rontott el. A beadott tipp rtkt egsz szmm alaktjuk a krdvbe rs eltt. Egy kifejezs rtknek kirshoz a bngszben a print() vagy az echo() utastsokat hasznlhatjuk. PHP mdban ezt egyszerbben is megtehetjk. Ha egyenlsgjelet (=) tesznk a PHP blokkot nyit elem utn, a bngsz az azt kvetkez kifejezs rtkt kirja, gy a <? print $proba?> helyett rhatjuk a kvetkezt is: <?=$proba?>

rlapok A PHP kd trzsben egy felttellel megvizsgljuk, hogy kell-e nvelni a $probalkozasok vltoz rtkt. Ha a vltoz ltezik, akkor nveljk az rtkt, klnben 0-ra lltjuk. A HTML kd trzsben folyamatosan kirjuk, hnyszor prblkozott a felhasznl. Ne bzzunk meg felttel nlkl a rejtett mezkben. Nem tudhatjuk, hogy honnan szrmazik az rtkk. Nem mondjuk, hogy ne hasznljuk ket, csak azt, hogy nagy krltekintssel tegyk. A felhasznl a forrs megvltoztatsval knnyedn csalhat a programban. A rejtett mezk hasznlata nem biztonsgos.

163

A felhasznl tirnytsa
Programunknak van egy nagy htultje. Az rlap mindig jratltdik, akr kitallta a felhasznl a szmot, akr nem. A HTML nyelvben sajnos elkerlhetetlen az egsz oldal jratltse, a felhasznlt azonban tirnythatjuk egy gratull oldalra, ha kitallta a szmot. Amikor az gyflprogram elkezdi a kapcsolatot a kiszolglval, elkld egy fejlcet, amely klnbz informcikat tartalmaz az azt kvet dokumentumrl. A PHP ezt automatikusan megteszi, de a header() fggvnnyel mi is bellthatjuk a fejlc egyes elemeit. Ha a header() fggvnyt szeretnnk hasznlni, biztosnak kell benne lennnk, hogy a bngsznek nem rtunk ki semmit, klnben a fggvnyhvs eltt a PHP elkldi a sajt fejlct. Ez mindenfle kirs, mg sortrs s szkz karakter esetn is bekvetkezik. A header() fggvny hasznlatakor semmi nem lehet a fggvnyhvs eltt, gy ellenriznnk kell a felhasznland kls llomnyokat is. A 9.12. pldban egy jellemz PHP fejlcet lthatunk.

9.12. plda Egy jellemz PHP fejlc


1: 2: 3: 4: 5: 6: HEAD /php-konyv/urlapok/9.1.program.php HTTP/1.0 HTTP/1.1 200 OK Date: Sun, 09 Jan 2000 18:37:45 GMT Server: Apache/1.3.9 (Unix) PHP/4.0 Connection: close Content-Type: text/html

164

9. ra

A fejlcet a Telnet programmal rathatjuk ki. Kapcsoldjunk a 80-as kapun a webkiszolglhoz s gpeljk be a kvetkezt: HEAD /utvonal/fajl.html HTTP/1.0 Az gyflprogram ekkor kirja a fejlcet.

Egy "Location" fejlc elkldsvel a bngszt egy msik lapra irnythatjuk: header( "Location: http://www.kiskapu.hu/" ); Tegyk fel, hogy ksztettnk egy "gratulacio.html" oldalt, ahova tirnytjuk a felhasznlt, amikor kitallta a megadott szmot. A megoldst a 9.13. pldban talljuk.

9.13. program Fejlc kldse a header() fggvnnyel


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: <?php $kitalalando_szam = 42; $uzenet = ""; $probalkozasok = ( isset( $probalkozasok ) ) ? ++$probalkozasok : 0; if ( ! isset( $tipp ) ) { $uzenet = "dvzlm a szmkitalls jtkban!"; } elseif ( $tipp > $kitalalando_szam ) { $uzenet = "A(z) $tipp tl nagy, prbljon egy kisebbet!"; } elseif ( $tipp < $kitalalando_szam ) { $uzenet = "A(z) $tipp tl kicsi, prbljon egy nagyobbat!"; } else // egyenlk kell, hogy legyenek { header( "Location: gratulacio.html" ); exit; } $tipp = (int) $tipp;

rlapok

165

9.13. program (folytats)


23: ?> 24: <html> 25: <head> 26: <title>9.13. program Fejlc kldse a header() fggvnnyel</title> 27: </head> 28: <body> 29: <h1> 30: <?php print $uzenet ?> 31: </h1> 32: Tippels sorszma: <?php print $probalkozasok?> 33: <form action="<?php print $PHP_SELF?>" method="POST"> 34: Ide rja a tippjt: 35: <input type="text" name="tipp" value="<?php print $tipp?>"> 36: <input type="hidden" name="probalkozasok" 37: value="<?php print $probalkozasok ?>"> 38: </form> 39: </body> 40: </html>

Az if szerkezet else gban a bngszt tirnytjuk a "gratulacio.html" oldalra. A header() fggvny meghvsa utn az oldalnak exit utastssal kell vgzdnie, hogy befejezze az rlap vizsglatt.

Fjlfeltlt rlapok s programok


Megtanultuk, hogyan krhetnk be adatokat a felhasznltl, de a Netscape Navigator 2-tl s az Internet Explorer 4-tl kezdve lehetsgnk van fjlok feltltsre is. Ebben a rszben azzal foglalkozunk, hogyan lehet a fjlok feltltst kezelni a PHP 4 segtsgvel. Elszr ltre kell hoznunk egy HTML rlapot, amely tartalmazza a fjlfeltlt mezt, melynek egyik paramtere ktelezen a kvetkez: ENCTYPE="multipart/form-data" A feltlt mez eltt meg kell adnunk egy rejtett mezt is. Ennek neve MAX_FILE_SIZE kell, hogy legyen, s a fogadand fjl lehetsges legnagyobb mrett adja meg, bjtban. Nem lehet nagyobb, mint a php.ini fjlban megadott

166

9. ra upload_max_filesize rtke, amely alaprtelmezs szerint 2 megabjt. Miutn kitltttk a MAX_FILE_SIZE mezt, a fjlt egy egyszer INPUT elemmel tlthetjk fel, melynek TYPE paramtere "file". Brmilyen nevet adhatunk neki. A 9.14. pldban a fjlt feltlt HTML kdot lthatjuk.

9.14. program Fjlfeltlt rlap


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: <html> <head> <title>9.14. program Fjlfeltlt rlap</title> </head> <body> <form enctype="multipart/form-data" action="<?print $PHP_SELF?>" method="POST"> <input type="hidden" name="MAX_FILE_SIZE" value="51200"> <input type="file" name="fajl"><br> <input type="submit" value="feltlts!"> </form> </body> </html>

Vegyk szre, hogy a program meghvja az oldalt, amely tartalmazza, hogy PHP kddal kezeljk a fjlt. A legnagyobb fjlmretet 50 kilobjtban adjuk meg s "fajl"-nak nevezzk el. Amikor a fjlt feltltttk, az egy ideiglenes knyvtrban troldik (ez alapbelltsban a /tmp, ha UNIX rendszerrl van sz). A fjl elrsi tjt a betlt mez nevvel megegyez globlis vltoz tartalmazza (pldnkban a $fajl). A fjlrl a klnbz informcikat a PHP globlis vltozkban trolja. Nevk a fjl elrsi tjt tartalmaz vltoznv, kiegsztve a "name", "size" s "type" uttagokkal. A vltozk jelentst a 9.2. tblzat tartalmazza.

9.2. tblzat Feltlttt fjlhoz kapcsold globlis vltozk


Vltoznv $fajl
$fajl_name $fajl_size $fajl_type

Tartalma A fjl ideiglenes elrsi tja


A feltlttt fjl neve A feltlttt fjl mrete bjtban A feltlttt fjl tpusa

Plda /tmp/php5Pq3fU
test.gif 6835 image/gif

rlapok A PHP 4 a feltlttt fjlok adatainak trolsra beptett tmb tpus vltozkat hasznl. Ha egy vagy tbb fjlt tltnk fel egy rlapon keresztl, a fjlok adatai a $HTTP_POST_FILES tmbben troldnak. A tmb indexei a feltltst meghatroz mezk nevei. A 9.3. tblzatban lthatjuk a tmb elemeinek nevt s rtkt.

167

9.3. tblzat Feltlttt fjlhoz kapcsold globlis vltozk


Elem Tartalma $HTTP_POST_FILES["fajl"]["name"] A feltlttt fjl neve
$HTTP_POST_FILES["fajl"]["size"] A feltlttt fjl mrete bjtban $HTTP_POST_FILES["fajl"]["type"] A feltlttt fjl tpusa image/gif

Plda test.gif
6835

A 9.15. pldban lthat program kirja a rendelkezsre ll informcikat a feltlttt fjlrl, s ha az GIF formtum, megjelenti.

9.15. program Fjlfeltlt program


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: <html> <head> <title>9.15. program - Fjlfeltlt program</title> </head> <?php $feltoltes_konyvtar = "/home/httpd/htdocs/feltoltesek"; $feltoltes_url = "http://php.kiskapu.hu/feltoltesek"; if ( isset( $fajl ) ) { print "elrsi t: $fajl<br>\n"; print "nv: $fajl_name<br>\n"; print "mret: $fajl_size bjt<br>\n"; print "tpus: $fajl_type<p>\n\n"; if ( $fajl_type == "image/gif" ) { copy ( $fajl, "$feltoltes_konyvtar/$fajl_name") or die ("Nem lehet msolni");

17: 18: print "<img src=\"$feltoltes_url/$fajl_name\"><p>\n\n"; 19: } 20: }

168

9. ra

9.15. program (folytats)


21: ?> 22: <body> 23: <form enctype="multipart/form-data" action="<?php print $PHP_SELF?>" method="POST"> 24: <input type="hidden" name="MAX_FILE_SIZE" value="51200"> 25: <input type="file" name="fajl"><br> 26: <input type="submit" value="feltlts!"> 27: </form> 28: </body>

A 9.15. pldban elszr ellenrizzk, hogy a $fajl globlis vltoz ltezik-e. Ha ltezik, feltehetjk, hogy a feltlts sikeres volt (legalbbis e plda erejig). Mindig csak megbzhat forrsbl fogadjunk fjlt s ellenrizzk, hogy programunk szmra megfelel formtum-e. A rosszindulat ltogatk olyan rlapot kszthetnek, amelyben megegyez nev elemek tallhatak, de teljesen ms tartalommal, gy programunk nem a vrt adatokat kapja meg. Lehet, hogy ez paranoinak tnik, de jegyezzk meg, hogy a kiszolgloldali programozsban a paranoia j dolog. Soha ne bzzunk kls forrsbl rkez adatokban, mg akkor sem, ha a kls forrs egy olyan rlap, amit ppen mi ksztettnk. Miutn feltltttk a fjlt, a bngszben megjelentjk a $fajl, $fajl_name, $fajl_size s $fajl_type vltozk tartalmt, amelyek a fjlrl informcikat tartalmaznak. Ezutn ellenrizzk a $fajl_type vltozt. Ha rtke "image/gif", akkor az rkezett llomnyt GIF kpknt megjelenthetjk. A tpust a fjlkiterjeszts alapjn llaptja meg a rendszer, ezrt rdemes ellenrizni, hogy a fjl valban GIF formtum-e. Ennek mdjrl a tizenhetedik, karakterlncokkal foglalkoz rban tanulunk. A copy() fggvnnyel a feltlttt fjlt a kiszolgl msik knyvtrba msolhatjuk. A copy() fggvnynek kt paramtert kell megadni: az els a msoland fjl elrsi tja, a msodik a fjl j elrsi tja. A fjl eredeti elrsi tja a $fajl vltozban tallhat. Az j elrsi t szmra ltrehozunk egy $feltoltes_konyvtar nev vltozt, amihez hozzfzzk a $fajl_name rtket. Ezutn a copy() fggvnnyel tmsoljuk a fjlt. UNIX rendszerben a kiszolglprogramok a 'nobody' felhaszn-

rlapok lnv alatt futnak, ezrt mieltt msolatot ksztennk a fjlrl, ellenriznnk kell, hogy a mvelet engedlyezett-e. Az or mvelettel a die() fggvnyt hasznljuk, ha a msols sikertelen. Ezt a mdszert a tizedik, a fjlokkal foglalkoz rban rszletesebben ttekintjk. Msols utn az eredeti fjlt nem kell trlnnk, a PHP ezt megteszi helyettnk. Ha nem msoljuk vagy helyezzk t a feltlttt llomnyt, a fjl elvsz, mivel az a PHP kd vgrehajtsa utn trldik az ideiglenes knyvtrbl. Amikor ltrehozzuk a $feltoltes_konyvtar vltozt, ltrehozzuk a $feltoltes_url vltozt is, a clknyvtr URL cmnek trolsra. A lemsolt fjlt HTML kp elemknt jelentjk meg.

169

sszefoglals
Eddig olyan dolgokat tanultunk, amelyek segtsgvel igazi interaktv krnyezetet hozhatunk ltre. Van azonban mg nhny tanulnival. A felhasznlrl kpesek vagyunk informcikat szerezni, de mit tegynk ezekkel? Pldul fjlba rhatjuk. Ez lesz a kvetkez ra tmja. Ebben az rban megtanultuk, hogyan hasznljuk a $GLOBALS tmbt, az rlapok adatait, a feltlttt fjlokat s a globlis vltozkat. Megtanultuk, hogyan kldhetnk fejlcet az gyflnek a bngsz tirnytsa rdekben. Megnztk, hogyan listzzuk ki az rlaprl kapott adatokat s rejtett mezket hasznltunk, adatok tadsra a programtl a bngsznek.

Krdsek s vlaszok
Ltre lehet hozni tmbt olyan elemek trolsra is, amelyek nem vlasztmezvel vagy jellngyzetekkel megadottak? Igen. Minden elem, amely nevnek vgn res szgletes zrjel van, tmbknt troldik, gy az elemek csoportba rendezhetk. A header() fggvny nagyon hasznosnak tnik. Tanulunk mg a HTTP fejlcekrl? Magrl a HTTP-rl mg beszlnk a tizenharmadik rban. Az elemek nevnek automatikus vltoznvv alaktsa veszlyesnek tnik. Kikapcsolhat valahol ez a lehetsg? Igen a php.ini fjl register_globals elemt kell off-ra lltani a lehetsg kikapcsolshoz.

170

9. ra

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Melyik krnyezeti vltoz tartalmazza a felhasznl IP cmt? 2. Melyik krnyezeti vltoz tartalmaz a bngszrl informcikat? 3. Hogyan nevezzk el az rlap mezjt, hogy a r hivatkoz globlis vltoz $urlap_tomb nev tmb legyen? 4. Melyik beptett tmb tartalmazza a GET krelmen keresztl rkez vltozkat? 5. Melyik beptett tmb tartalmazza a POST krelmen keresztl rkez vltozkat? 6. Melyik fggvnyt hasznljuk a bngsz tirnytsra? Milyen karaktersorozatot kell tadnunk a fggvnynek? 7. Hogyan lehet korltozni egy rlaprl feltlthet fjl mrett? 8. Hogyan korltozhat az sszes rlaprl vagy programbl feltlthet fjl mrete?

Feladatok
1. Ksztsnk szmolgp-programot, amelyben a felhasznl megadhat kt szmot s a rajtuk vgrehajtand mveletet (sszeads, kivons, szorzs vagy oszts ezeket ismerje a program). 2. Ksztsnk programot, amely rejtett mez hasznlatval megmondja, hogy a felhasznl hnyszor hasznlta az els feladatban szerepl szmolgpet.

10. RA
Fjlok hasznlata
A programozsi nyelvek egyik legfontosabb lehetsge, hogy fjlokat lehet ltrehozni, olvasni, rni velk. A PHP-nek szintn megvannak ezek a tulajdonsgai. Ebben a fejezetben ezeket a lehetsgeket fogjuk ttekinteni: Hogyan gyazzunk be fjlokat a dokumentumokba? Hogyan vizsgljuk a fjlokat s knyvtrakat? Hogyan nyissunk meg egy fjlt? Hogyan olvassunk adatokat a fjlokbl? Hogyan rjunk egy fjlba vagy fzznk hozz? Hogyan zrjunk le egy fjlt? Hogyan dolgozzunk knyvtrakkal?

172

10. ra

Fjlok begyazsa az include() fggvnnyel


Az include() fggvny lehetsget ad arra, hogy fjlt gyazzunk be a PHP dokumentumokba. A fjlban szerepl PHP kd gy hajtdik vgre, mintha a fdokumentum rsze lenne, ami hasznos, ha egy tbboldalas programban kls kdokat szeretnnk begyazni. Eddig, ha olyan kdot rtunk, amelyet tbbszr is fel akartunk hasznlni, minden egyes helyre be kellett msolnunk azt. Ha hibt talltunk benne vagy lehetsgeit tovbb akartuk bvteni, mindentt t kellett rnunk. Ezekre a problmkra megolds az include() fggvny. Gyakran hasznlt fggvnyeinket kls fjlba menthetjk s az include() fggvnnyel futsi idben tlthetjk be programunkba. Az include() fggvny paramtere a fjl elrsi tja. A 10.1. pldban lthat, hogyan gyazhat be egy fjl a PHP kdba az include() fggvny segtsgvel.

10.1. program Az include() hasznlata


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: <html> <head> <title>10.1. program Az include() hasznlata</title> </head> <body> <?php include("10.2.program.php"); ?> </body> </html>

10.2. program A 10.1. pldban szerepl beillesztett fjl


1: Engem gyaztak be!!

A 10.1. pldban tallhat kdba az 10.2.program.php fjl van begyazva. Amikor lefuttatjuk a 10.1. pldban tallhat kdot, az "Engem gyaztak be!!" szveg jelenik meg, azaz szveget gyaztunk be a PHP kdba. Nem okoz ez gondot? A begyazott fjl tartalma alaprtelmezsben HTML formtumban jelenik meg. Ha vgrehajtand PHP kdot szeretnnk begyazni, akkor azt az eredeti fjlban PHP cmkk kz kell zrni. A 10.3. s 10.4. pldban a begyazott fjlban van a megjelent kd.

Fjlok hasznlata

173

10.3. program Az include() fggvny hasznlata PHP kd vgrehajtsra ms fjlban


1: <html> 2: <head> 3: <title>10.3. program Az include() fggvny hasznlata PHP kd vgrehajtsra ms fjlban</title> 4: </head> 5: <body> 6: <?php 7: include("10.4.program.php"); 8: ?> 9: </body> 10: </html>

10

10.4. program PHP kdot tartalmaz begyazott fjl


1: 2: 3: 4: <?php print "Engem gyaztak be!!<br>"" print "De most mr ssze tudok adni ... 4 + 4 = ".(4+4); ?>

A PHP 4-ben a begyazott fjlokban szerepl kdnak ugyangy lehet visszatrsi rtket adni, mint a fggvnyeknek. A visszatrsi rtket a fjl vge eltt egy return utasts utn kell meghatrozni. A 10.5. s 10.6. pldkban olyan fjlokat gyazunk be a dokumentumba, amelyeknek visszatrsi rtkk van.

10.5. program PHP kd vgrehajtsa s visszatrsi rtk megadsa az include() fggvny hasznlatval
1: <html> 2: <head> 3: <title>10.5. program PHP kd vgrehajtsa s visszatrsi rtk megadsa az include() fggvny hasznlatval</title> 4: </head> 5: <body> 6: <?php 7: $eredmeny = include("10.6.program.php"); 8: print "A visszatrsi rtk $eredmeny"; 9: ?> 10: </body> 11: </html>

174

10. ra

10.6. program Visszatrsi rtkkel rendelkez begyazott fjl


1: 2: 3: 4: 5: <?php $vissza = ( 4 + 4 ); return $vissza; ?> Ez a HTML soha nem jelenik meg, mert a visszatrs utn rtuk!

PHP 3 hasznlatakor a begyazott fjlnak csak akkor lehet visszatrsi rtket adni a return utastssal, ha fggvnyben szerepel. A 10.6. plda a PHP 3-ban hibt okoz.

Ha az include() fggvnyt alkalmazzuk, megadhatunk feltteleket is. A megadott fjlt csak akkor gyazza be az include(), ha a fjlra teljeslnek a felttelek. A kvetkez kdban tallhat begyazs soha nem fog vgrehajtdni: $proba = false; if ( $proba ) { include( "egy_fajl.txt" ); //nem gyazza be } Ha az include() fggvnyt ciklusban hasznljuk, az include()-ban megadott fjl tartalma minden ismtlsnl bemsoldik s a fjlban lv kd minden hvsnl vgrehajtdik. A 10.7. pldban tallhat kdban az include() fggvny egy for ciklus belsejben szerepel. Az include() paramtere minden ismtlsnl ms fjlra mutat.

10.7. program Az include() hasznlata cikluson bell


1: 2: 3: son 4: 5: 6: 7: 8: 9: <html> <head> <title>10.7. program Az include() hasznlata ciklubell</title> </head> <body> <?php for ( $x = 1; $x<=3; $x++ ) { $incfajl = "incfajl$x.txt";

Fjlok hasznlata

175

10.7. program (folytats)


10: print "Megprblom begyazni az $incfajl t"; 11: include( "$incfajl" ); 12: print "<p>"; 13: } 14: ?> 15: </body> 16: </html>

10

A 10.7. programban tallhat kd futs kzben hrom klnbz fjlt gyaz be, ezek az "incfajl1.txt", "incfajl2.txt" s "incfajl3.txt". Mindegyik fjl tartalmazza a nevt s azt a szveget, hogy begyaztk: Megprblom begyazni az incfajl1.txt -t Ez a fjl az incfajl1.txt Megprblom begyazni az incfajl2.txt -t Ez a fjl az incfajl2.txt Megprblom begyazni az incfajl3.txt -t Ez a fjl az incfajl3.txt Rendelkezsre ll egy msik PHP fggvny is, a require(), amely hasonlan mkdik az include()-hoz. Ciklusban azonban a require() nem hasznlhat gy, mint az include(), ugyanis a require() a program futsnak kezdetekor helyettestdik be. Mg egy fontos klnbsg a kt fggvny kztt, hogy a require()-nak nem lehet visszatrsi rtke a PHP 4-esben.

Fjlok vizsglata
Mieltt elkezdnk ismerkedni a fjlokkal s knyvtrakkal, fussunk t nhny velk kapcsolatos tudnivalt. A PHP 4 igen sok lehetsget ad arra, hogy a rendszernkben tallhat fjlokon klnbz mveleteket hajtsunk vgre. A kvetkez bekezdsekben ezeket a fggvnyeket tekintjk t.

Fjl ltezsnek ellenrzse a file_exists() fggvnnyel


Fjl ltezst a file_exists() fggvnnyel vizsglhatjuk. A file_exists() paramtere egy karakterlnc, amely a krdses fjl elrsi tjt s nevt tartalmazza. A fggvny visszatrsi rtke true, ha a fjl ltezik, egybknt false.

176

10. ra if ( file_exists("proba.txt") ) print("A fjl ltezik!");

Fjl vagy knyvtr?


Az is_file() fggvny azt dnti el, hogy paramtere fjl-e. A paramterben meg kell adnunk egy elrsi utat. Ha a megadott elrsi t fjlt jell, a fggvny visszatrsi rtke true, egybknt false lesz. if ( is_file( "proba.txt" ) ) print("a proba.txt egy fjl"); Ellenrizhetjk azt is, hogy az elrsi t knyvtrat jell-e. Az ellenrzst az is_dir() fggvny vgzi. Ha a fggvny paramterben megadott elrsi t knyvtrat hatroz meg, a visszatrsi rtk true, egybknt false lesz. if ( is_dir( "/tmp" ) ) print "a /tmp egy knyvtr";

Fjl llapotnak lekrdezse


Miutn megtudtuk, hogy egy fjl ltezik s valban fjl, klnfle dolgokat vgezhetnk vele. ltalban runk bele, olvassuk vagy vgrehajtjuk. A PHP-ben klnbz fggvnyek llnak rendelkezsre ezen lehetsgek lekrdezsre. Az is_readable() fggvnnyel megtudhatjuk, hogy az adott fjl olvashat-e szmunkra. UNIX rendszerben lehet, hogy ltjuk a fjlt a knyvtrszerkezetben, de nincs jogosultsgunk annak olvassra. Ha az is_readable() paramterben elrsi ttal megadott fjl olvashat, visszatrsi rtke true, egybknt false lesz. if ( is_readable( "proba.txt" ) ) print "a proba.txt olvashat"; Az is_writeable() fggvnnyel megtudhatjuk, hogy az adott fjl rhat-e szmunkra. Ha az is_writeable() paramterben elrsi ttal megadott fjl rhat, visszatrsi rtke true, egybknt false lesz. if ( is_writeable( "proba.txt" ) ) print "a proba.txt rhat"; Az is_executable() fggvnnyel azt tudhatjuk meg, hogy az adott fjl futtathat-e. A visszatrsi rtk jogosultsgunktl s a fjl kiterjesztstl fgg. Ha az is_executable() paramterben elrsi ttal megadott fjl futtathat, a visszatrsi rtk true, egybknt false lesz.

Fjlok hasznlata if ( is_executable( "proba.txt" ) print "a proba.txt futtathat";

177

Fjl mretnek lekrdezse a filesize() fggvnnyel


A filesize() fggvny a paramterben elrsi ttal megadott fjl bjtban szmtott mretvel tr vissza. A vgeredmny false, ha brmilyen hiba trtnik. print "A proba.txt mrete: "; print filesize( "proba.txt" );

10

Klnfle fjlinformcik
Szksgnk lehet r, hogy tudjuk, mikor hoztk ltre a fjlt vagy mikor hasznltk utoljra. A PHP-vel ezeket az informcikat is megszerezhetjk. A fjl utols megnyitsnak dtumt a fileatime() fggvny segtsgvel kaphatjuk meg. A fggvny paramterben meg kell adni a fjl elrsi tjt. Visszatrsi rtkknt az utols megnyits dtumt kapjuk meg. A megnyits jelenthet rst vagy olvasst is. Ezen fggvnyek visszatrsi rtke UNIX idblyeg formtum, azaz mindig az 1970 janur elseje ta eltelt msodpercek szma. A kvetkez pldban ezt a szmot a date() fggvny segtsgvel olvashat formra alaktjuk. A date() fggvny lersa a tizentdik rban szerepel. $atime = fileatime( "proba.txt" ); print "A proba.txt legutols megnyitsnak dtuma:"; print date("Y.m.d. H:i", $atime); //Egy minta vgeredmny: 2000.01.23. 14:26 A filemtime() fggvnnyel a fjl utols mdostsnak idejt kaphatjuk meg. A fggvny paramtere a fjl elrsi tja, visszatrsi rtke pedig UNIX idblyeg formtum. A mdosts azt jelenti, hogy a fjl tartalma valamilyen mdon megvltozott. $mtime = filemtime( "proba.txt" ); print "A proba.txt utols mdostsnak dtuma:"; print date("Y.m.d. H:i", $mtime); //Egy minta vgeredmny: 2000.01.23. 14:26 A filectime() a fjl utols vltozsnak idpontjt adja meg. UNIX rendszerben a vltozs alatt azt rtjk, amikor a fjl tartalma valamilyen mdon mdosul vagy a jogosultsgok, illetve a tulajdonos megvltozik. Ms rendszerekben a filectime() visszatrsi rtke a fjl ltrehozsnak dtuma.

178

10. ra $ctime = filectime( "proba.txt" ); print "A proba.txt utols vltozsnak dtuma:"; print date("Y.m.d. H:i", $ctime); //Egy minta vgeredmny: 2000.01.23. 14:26

Tbb fjltulajdonsgot egyszerre megad fggvny


A 10.8. pldban olyan fggvnyt hozunk ltre, amely az elzekben ltott lehetsgeket fogja ssze egyetlen fggvnyben.

10.8. program Egyszerre tbb fjltulajdonsgot megad fggvny


1: <html> 2: <head> 3: <title>10.8. program Egyszerre tbb fjltulajdonsgot megad fggvny</title> 4: </head> 5: <body> 6: <?php 7: $fajl = "proba.txt"; 8: fileInformaciok( $fajl ); 9: function fileInformaciok( $f ) 10: { 11: if ( ! file_exists( $f ) ) 12: { 13: print "$f nem ltezik <BR>"; 14: return; 15: } 16: print "$f ".(is_file( $f )?"":"nem ")."fjl<br>" 17: print "$f ".(is_dir( $f )?"":"nem "). "knyvtr<br>" 18: print "$f ".(is_readable( $f )?"":"nem "). "olvashat<br>" 19: print "$f ".(is_writeable( $f )?"":"nem "). "rhat<br>" 20: print "$f ".(is_executable( $f )?"":"nem "). "futtathat<br>" 21: print "$f ".(filesize( $f ))."bjt mret<br>" 22: print "$f utols megnyitsnak dtuma: ". date( "Y.m.d. H:i", fileatime( $f ) ). "<br>"; 23: print "$f utols mdostsnak dtuma: ". date( "Y.m.d. H:i", filemtime( $f ) ). "<br>";

Fjlok hasznlata

179

10.8. program (folytats)


24: print "$f utols vltozsnak dtuma: ". date( "Y.m.d. H:i", filectime( $f ) ). "<br>";

25: } 26: 27: ?> 28: </body> 29: </html>

10

Az egyszerbb lers kedvrt ? : mveleteket hasznltunk. Nzzk meg ezek kzl az egyiket: print "$f ".(is_file( $f )?"":"nem ")."fjl<br>" A mveletjel bal oldalra kerlt az is_file() fggvny. Ha ennek eredmnye true, akkor az opertor visszatrsi rtke res karakterlnc, egybknt a "nem " szveg. A visszatrsi rtk utn a szvegsszefzs jelet kvet karakterlnc is kirdik. Az elbbi kifejezs kevsb tmr formban a kvetkezkppen rhat le: $igen_vagy_nem = is_file( $f ) ? "" : "nem "; print "$f $igen_vagy_nem"."fjl<br>" Az if vezrlsi szerkezettel mg vilgosabb kdot rhatunk, ekkor azonban a program mrete jelentsen n. if ( is_file( $f ) ) print "$f fjl<br>"; else print "$f nem fjl<br>"; Mivel az elz pldk ugyanannak a feladatnak a megoldsai, szabadon vlaszthatjuk ki a neknk tetszt.

Fjlok ltrehozsa s trlse


Ha egy fjl nem ltezik, a touch() fggvny segtsgvel hozhatjuk ltre. A fggvny paramterben meg kell adni egy elrsi utat. Ezen az elrsi ton prbl meg ltrehozni a touch() egy res fjlt. Ha a fjl mr ltezik, tartalma nem vltozik meg, de a mdosts dtuma a touch() fggvny vgrehajtsi idejre mdosul.

180

10. ra touch("sajat_fajl.txt"); Ltez fjlt trlni az unlink() fggvnnyel lehet. Az unlink() paramtere a fjl elrsi tja: unlink("sajat_fajl.txt"); A ltrehozs, trls, rs, olvass, mdosts csak akkor lehetsges egy fjlon, ha a megfelel jogosultsgokkal rendelkeznk.

Fjl megnyitsa rsra, olvassra, hozzfzsre


Mieltt elkezdnk dolgozni egy fjllal, meg kell nyitnunk rsra vagy olvassra. Ezt az fopen() fggvnnyel tehetjk meg. A fggvny paramterben meg kell adni a fjl elrsi tjt s a megnyitsi mdot. A legtbbszr hasznlt mdok az olvass ("r"), rs ("w"), hozzfzs ("a"). A fggvny visszatrsi rtke egy egsz szm. Ez az egsz szm az gynevezett fjlazonost, amelyet vltozknt trolhatunk. Ezzel hivatkozhatunk ksbb a fjlra. Fjl olvassra val megnyitshoz a kvetkezt kell bernunk: $fa = fopen( "proba.txt", 'r' ); Az rsra val megnyitshoz a kvetkezt: $fa = fopen( "proba.txt", 'w' ); Ha a fjlt hozzfzsre akarjuk megnyitni, teht nem kvnjuk fellrni a tartalmt, csak a vghez szeretnnk fzni valamit, a kvetkezt kell tennnk: $fa = fopen( "proba.txt", 'a' ); Az fopen() false rtkkel tr vissza, ha valamirt nem tudta megnyitni a fjlt, ezrt rdemes mindig ellenrizni, hogy sikeres volt-e a megnyits. Ezt pldul az if vezrlsi szerkezettel tehetjk meg: if ( $fa = fopen( "proba.txt", "w" ) ) { // $fa-val csinlunk valamit } Esetleg hasznlhatunk logikai mveletet, hogy megszaktsuk a vgrehajtst, ha a fjl nem ltezik:

Fjlok hasznlata ( $fa = fopen( "proba.txt", "w" ) ) or die ("A fjl sajnos nem nyithat meg!"); Ha az fopen() true rtkkel tr vissza, a die() nem hajtdik vgre, klnben a kifejezs jobb oldaln a die() kirja a paramterben szerepl karakterlncot s megszaktja a program futst. Amikor befejeztk a munkt egy fjllal, mindig be kell zrnunk azt. Ezt az fclose() fggvnnyel tehetjk meg, amelynek paramterben azt a fjlazonostt kell megadnunk, amelyet egy sikeres fopen() vgrehajtsa sorn kaptunk: fclose( $fa );

181

10

Olvass fjlbl
A PHP-ben egy fjlbl klnbz fggvnyek segtsgvel bjtonknt, soronknt vagy karakterenknt olvashatunk.

Sorok olvassa fjlbl az fgets() s feof() fggvnyekkel


Miutn megnyitottunk egy fjlt, beolvashatjuk a tartalmt sorrl sorra, az fgets() fggvnnyel. A fggvny paramterben meg kell adni az olvasand fjl azonostjt (amit az fopen() fggvny ad a megnyitskor), tovbb msodik paramterknt kell adnunk egy egsz szmot is, amely meghatrozza, hogy legfeljebb hny bjtot olvasson ki a PHP, amg sorvge vagy fjlvge jelet nem tall. Az fgets() fggvny addig olvas a fjlbl, amg jsor karakterhez ("\n") nem r, a megadott bjtnyi adatot ki nem olvassa vagy a fjl vgt el nem ri. $sor = fgets( $fa, 1024 ); // ahol az $fa az fopen() ltal visszaadott fjlazonost Tudnunk kell teht, mikor rnk a fjl vgre. Ezt az feof() fggvny adja meg, melynek visszatrsi rtke true, ha a fjl vgre rtnk, egybknt false. A fggvny paramterben egy fjlazonostt kell megadni. feof( $fa ); // ahol az $fa az fopen() ltal visszaadott fjlazonost A 10.9. pldban lthatjuk, hogyan kell egy fjlt sorrl sorra beolvasni.

182

10. ra

10.9. program Fjl megnyitsa s sorrl sorra olvassa


1: <html> 2: <head> 3: <title>10.9. program Fjl megnyitsa s sorrl sorra olvassa</title> 4: </head> 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: $sor = fgets( $fa, 1024 ); 12: print "$sor<br>"; 13: } 14: fclose($fa); 15: ?> 16: </body> 17: </html>

Az fopen() fggvnnyel prbljuk olvassra megnyitni a fjlt. Ha a ksrlet sikertelen, a die() fggvnnyel megszaktjuk a program futst. Ez legtbbszr akkor trtnik meg, ha a fjl nem ltezik vagy (UNIX rendszerben) nincs megfelel jogosultsgunk a megnyitsra. Az olvass a while ciklusban trtnik. A while ciklus minden ismtls alkalmval megnzi az feof() fggvnnyel, hogy az olvass elrt-e a fjl vghez, teht a ciklus addig olvas, amg el nem ri a fjl vgt. Az fgets() minden ismtlsnl kiolvas egy sort vagy 1024 bjtot. A kiolvasott karaktersorozatot a $sor vltozba mentjk s kirjuk a bngszbe. Minden kirsnl megadunk egy <br> cmkt, hogy a szveg olvashatbb legyen, vgl bezrjuk a megnyitott llomnyt.

Tetszleges mennyisg adat olvassa fjlbl


A fjlokbl nem csak soronknt, hanem elre meghatrozott mret darabokat is olvashatunk. Az fread() fggvny paramterben meg kell adni egy fjlazonostt s az egyszerre kiolvasand adatok mennyisgt, bjtban. A fggvny visszatrsi rtke a megadott mennyisg adat lesz, kivve, ha elrte a fjl vgt. $reszlet = fread( $fa, 16 );

Fjlok hasznlata A 10.10. pldaprogram 16 bjtonknt olvassa be a fjlt.

183

10.10. program Fjl beolvassa az fread() fggvnnyel


1: <html> 2: <head> 3: <title>10.10. program Fjl beolvassa az fread() fggvnnyel</title> 4: </head> 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>

10

Br az fread() fggvnynek megadjuk, mennyi adatot olvasson ki, azt nem tudjuk meghatrozni, hogy honnan kezdje az olvasst. Erre az fseek() ad lehetsget, ezzel a fggvnnyel llthat be az olvass helye. Paramterknt egy fjlazonostt s egy egsz szmot kell megadnunk, amely a fjl elejtl bjtban mrve meghatrozza az j olvassi helyet: fseek( $fa, 64 ); A 10.11. pldban az fseek() s fread() fggvnyekkel a fjl tartalmnak msodik felt jelentjk meg a bngszben.

10.11. program Az fseek() hasznlata


1: 2: 3: 4: <html> <head> <title>10.11. program Az fseek() hasznlata</title> </head>

184

10. ra

10.11. program (folytats)


5: <body> 6: <?php 7: $fajlnev = "proba.txt"; 8: $fa = fopen( $fajlnev, "r" ) or die("$fajlnev nem nyithat meg"); 9: $fajlmeret = filesize($fajlnev); 10: $felmeret = (int)( $fajlmeret / 2 ); 11: print "A fjl felnek mrete: $felmeret <br>\n" 12: fseek( $fa, $felmeret ); 13: $reszlet = fread( $fa, ($fajlmeret - $felmeret) ); 14: print $reszlet; 15: fclose($fa); 16: ?> 17: </body> 18: </html> A felezpontot gy szmoltuk ki, hogy a filesize() fggvnnyel lekrtk a fjl mrett s elosztottuk kettvel. Ezt az rtket hasznltuk az fseek() msodik paramtereknt. Vgl az fread() segtsgvel kiolvastuk a fjl msodik felt s kirtuk a bngszbe.

Fjl karakterenknti olvassa az fgetc() fggvnnyel


Az fgetc() fggvny hasonlt az fgets() fggvnyhez, de minden alkalommal, amikor meghvjuk, csak egyetlen karaktert olvas ki a fjlbl. Mivel egy karakter mindig egy bjt mret, ms paramtert nem kell megadnunk, csak a mr megszokott fjlazonostt: $karakter = fgetc( $fa ); A 10.12. pldaprogram egy ciklus segtsgvel karakterenknt kiolvassa a "proba.txt" tartalmt s minden karaktert kln sorba r ki a bngszbe.

10.12. program Az fgetc() hasznlata


1: 2: 3: 4: 5: <html> <head> <title>10.12. program Az fgetc() hasznlata</title> </head> <body>

Fjlok hasznlata

185

10.12. program (folytats)

6: <?php 7: $fajlnev = "program.txt"; 8: $fa = fopen( $fajlnev, "r" ) or die("$fajlnev nem nyithat meg"); 9: while ( ! feof( $fa ) ) 10: { 11: $karakter = fgetc( $fa ); 12: print "$karakter<br>"; 13: } 14: fclose($fa); 15: ?> 16: </body> 17: </html>

10

Fjlba rs s hozzfzs
A fjlba rs s a hozzfzs nagyon hasonltanak egymshoz. Az egyetlen klnbsg az fopen() hvsban rejlik. Amikor rsra nyitjuk meg a fjlt, akkor az fopen() msodik paramtereknt a "w" karaktert kell megadnunk: $fa = fopen( "proba.txt", "w" ); Minden rsi prblkozs a fjl elejn trtnik. Ha a fjl mg nem ltezne, a rendszer ltrehozza azt. Ha a fjl ltezik, tartalma fellrdik a megadott adatokkal. Ha a fjlt hozzfzsre nyitjuk meg, az fopen() msodik paramtereknt az "a" karaktert kell megadnunk: $fa = fopen( "proba.txt", "a" ); Hozzfzsnl minden adat a fjl vgre rdik, megtartva az elz tartalmat.

Fjlba rs az fwrite() s fputs() fggvnyekkel


Az fwrite() fggvny paramtereknt egy fjlazonostt s egy karakterlncot kell megadni. A karakterlnc a megadott fjlba rdik. Az fputs() ugyangy mkdik. fwrite( $fa, "hello vilg" ); fputs( $fa, "hello vilg" );

186

10. ra A 10.13. pldban elszr az fwrite() fggvny hasznlatval egy fjlba runk, majd az fputs() fggvnnyel adatokat fznk hozz.

10.13. program Fjlba rs s hozzfzs


1: <html> 2: <head> 3: <title>10.11. program Fjlba rs s hozzfzs</title> 4: </head> 5: <body> 6: <?php 7: $fajlnev = "proba.txt"; 8: print "$fajlnev fjlba rs"; 9: $fa = fopen( $fajlnev, "w" ) or die("$fajlnev nem nyithat meg"); 10: fwrite ( $fa, "Hello vilg\n"); 11: fclose( $fa ); 12: print "$fajlnev fjlhoz hozzfzs"; 13: $fa = fopen( $fajlnev, "a" ) or die("$fajlnev nem nyithat meg"); 14: fputs ( $fa, "s ms dolgok"); 15: fclose( $fa ); 16: ?> 17: </body> 18: </html>

Fjlok zrolsa az flock() fggvnnyel


Az eddig megtanultak igen jl hasznlhatk, ha programjaink csak egyetlen felhasznlt szolglnak ki. A valsgban azonban egy alkalmazs oldalait ltalban tbben is el szeretnk rni egyidben. Kpzeljk el, mi trtnne, ha egyszerre kt felhasznl rna ugyanabba a fjlba. A fjl hasznlhatatlann vlna. Az flock() fggvny hasznlatval kizrhatjuk ezt a lehetsget. Az flock() fggvnnyel zrolt fjlt nem olvashatja vagy rhatja ms folyamat, amg a zrols rvnyben van. Az flock() fggvny paramtereknt egy fjlazonostt s egy egsz szmot kell megadni. Ez utbbi a zrols tpust hatrozza meg. A lehetsges zrolsokat a 10.1. tblzat mutatja.

Fjlok hasznlata

187

10.1. tblzat Az flock() fggvny msodik paramternek lehetsges rtkei


Egsz 1 Lezrs tpusa Megosztott Lers Ms folyamatok olvashatjk a fjlt,
de nem rhatnak bele (akkor hasznljuk, amikor olvassuk a fjlt) 2 Kizr Ms folyamatok nem olvashatjk s nem rhatjk a fjlt (akkor hasznljuk, amikor runk a fjlba) A fjl zrolsnak megszntetse

10

Felszabadts

Az flock() fggvnyt a fjl megnyitsa utn alkalmazzuk zrolsra s az fclose() eltt oldjuk fel vele a zrat. $fa = fopen( "proba.txt", "a" ); flock( $fa, 2 ); // kizr lefoglals // fjlba rs flock( $fa, 3 ); // zrols feloldsa fclose( $fa ); Az flock() a PHP zrolsi megoldsa. Csak azok a programok veszik figyelembe ezt a fajta zrolst, ahol ugyanezt a mdszert alkalmazzuk, ezrt elfordulhat, hogy a nem-PHP programok megnyitjk a fjlunkat, akr rs kzben is.

Munka knyvtrakkal
Az elzekben ttekintettk, hogyan kezelhetjk a fjlokat, most megnzzk, hogyan hozhatunk ltre, trlhetnk s olvashatunk knyvtrakat a PHP-ben.

Knyvtr ltrehozsa az mkdir() fggvnnyel


Knyvtrat az mkdir() fggvnnyel hozhatunk ltre. Az mkdir() paramterben meg kell adni egy karakterlncot, amely a ltrehozand knyvtr elrsi tja, valamint egy oktlis (nyolcas szmrendszer) szmot, amely a jogosultsgokat hatrozza meg. Az oktlis szmok el mindig 0-t kell rni. A jogosultsg megadsnak csak UNIX rendszerekben van hatsa. A jogosultsgi md hrom 0 s 7 kz es szmot tartalmaz, amelyek sorban a tulajdonos, a csoport, s mindenki ms

188

10. ra jogait adjk meg. A fggvny visszatrsi rtke true, ha a knyvtrat sikerlt ltrehozni, egybknt false. A knyvtr ltrehozsa ltalban akkor nem sikeres, ha a megadott elrsi ton nincs jogosultsgunk knyvtrat ltrehozni, azaz nincs jogosultsgunk rsra. mkdir( "proba_konyvtar", 0777 ); // teljes rs/olvass/vgrehajts jogok

Knyvtr trlse az rmdir() fggvnnyel


A rendszerbl knyvtrat az rmdir() fggvnnyel trlhetnk. A sikeres trlshez megfelel jogosultsggal kell rendelkeznnk s a knyvtrnak resnek kell lennie. A fggvny paramterben a trlend knyvtr elrsi tjt kell megadni. rmdir( "proba_konyvtar" );

Knyvtr megnyitsa olvassra


Mieltt be tudnnk olvasni egy knyvtr tartalmt, szksgnk van egy knyvtrazonostra. Ezt az azonostt az opendir() fggvny adja meg. A fggvny paramterben annak a knyvtrnak az elrsi tjt kell tadni, amelyet olvasni szeretnnk. A fggvny visszatrsi rtke a knyvtr azonostja, kivve, ha a knyvtr nem ltezik vagy nincs jogosultsgunk az olvassra. Ezekben az estekben a visszatrsi rtk false. $kvt = opendir( "proba_konyvtar" );

Knyvtr tartalmnak olvassa


Ahogy az fgets() fggvnnyel fjlbl olvastunk, ugyangy hasznlhatjuk a readdir() fggvnyt, hogy fjl vagy knyvtrnevet olvassunk ki egy megnyitott knyvtrbl. A readdir() paramterben meg kell adni az olvasand knyvtr azonostjt. A fggvny visszatrsi rtke a knyvtr kvetkez elemnek neve. Ha a knyvtr vgre rtnk, a visszatrsi rtk false. A readdir() csak az elem nevt s nem annak elrsi tjt adja meg. A 10.4. pldban a readdir() fggvny hasznlati mdjt lthatjuk.

10.14. program Knyvtr tartalmnak kiratsa


1: <html> 2: <head> 3: <title>10.14. program Knyvtr tartalmnak kiratsa</title> 4: </head>

Fjlok hasznlata

189

10.14. program (folytats)


5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: <body> <?php $kvtnev = "proba_konyvtar"; $kvt = opendir( $kvtnev ); while ( gettype( $fajl = readdir( $kvt )) != boolean ) { if ( is_dir( "$kvtnev/$fajl" ) ) print "(D)"; print "$fajl<br>"; } closedir( $kvt ); ?> </body> </html>

10

A knyvtrat megnyitjuk az opendir() fggvnnyel, majd egy while ciklussal vgiglpkednk annak sszes elemn. A while ciklus feltteles kifejezsben meghvjuk a readdir() fggvnyt s a visszaadott rtket hozzrendeljk a $fajl vltozhoz. A ciklus trzsben az is_dir() fggvnnyel vizsgljuk, hogy a $kvtnev s a $fajl vltozkbl ksztett elrsi t knyvtrat jell-e. Ha igen, neve el tesznk egy "(D)" jelet. gy kirjuk a bngszbe a knyvtr tartalmt. A while ciklus feltteles kifejezsnek megrsakor igen elvigyzatosak voltunk. Sok PHP programoz a kvetkezt hasznlta volna: while ( $fajl = readdir( $kvt ) ) { print "$fajl<br>\n"; } Itt a readdir() visszatrsi rtkt vizsgljuk. Minden "0"-tl klnbz karakterlnc true-knt viselkedik, teht ebbl nem lehet problma. Mi trtnik, ha knyvtrunk ngy fjlt tartalmaz, melyek nevei "0", "1", "2", "3". Az elbbi kd a kvetkez vgeredmnyt adja: . .. Amikor a ciklus elri a "0" nev fjlt, a readdir() false rtknek veszi s a ciklus lell. A 10.14. pldban a readdir() fggvny visszatrsi rtknek tpust vizsgljuk s ezzel oldjuk meg a problmt.

190

10. ra

sszefoglals
Ebben az rban megtanultuk, hogyan gyazhatunk be a dokumentumokba kls fjlban trolt PHP kdot. ttekintettk a fjlok klnbz tulajdonsgainak ellenrzst, megnztnk, hogyan olvashatunk fjlokat sorrl sorra, karakterenknt, vagy meghatrozott rszletekben. Megtanultuk, hogyan rhatunk fjlba s hogyan fzhetnk karakterlncokat hozz. Vgl ttekintettk, hogyan hozhatunk ltre, trlhetnk, vagy listzhatunk ki knyvtrakat.

Krdsek s vlaszok
Az include() fggvny lasstja a programok futst? Mivel a begyazott fjlt meg kell nyitni s a tartalmt be kell olvasni, ezrt azt kell mondjuk, hogy igen, a lassuls azonban nem szmottev. Mindig le kell lltani a program futst, ha egy fjlt nem sikerlt megnyitni rsra vagy olvassra? Ha a program futshoz elengedhetetlen a fjl, akkor a die() fggvnnyel rdemes lelltani. Ms esetben a program futst nem fontos megszaktani, de rdemes figyelmeztetni a felhasznlt a hibra vagy feljegyezni a sikertelen megnyitsi ksrletet egy naplllomnyba. A huszonkettedik rban tbbet olvashatunk errl a megoldsrl.

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Melyik fggvnnyel adhat programunkhoz kls kdot tartalmaz fjl? 2. Melyik fggvnnyel tudjuk meg, hogy rendszernkben megtallhat-e egy fjl? 3. Hogyan kaphat meg egy fjl mrete? 4. Melyik fggvnnyel nyithat meg egy fjl rsra vagy olvassra? 5. Melyik fggvnnyel olvashatunk ki egy sort egy fjlbl? 6. Honnan tudhatjuk meg, hogy elrtk a fjl vgt?

Fjlok hasznlata 7. Melyik fggvnyt hasznljuk, hogy egy sort rjunk egy fjlba? 8. Hogyan nyitunk meg egy knyvtrt olvassra? 9. Melyik fggvnyt hasznljuk, hogy egy knyvtr elemeinek nevt megkapjuk, miutn megnyitottuk azt?

191

Feladatok
1. Ksztsnk egy oldalt, amely bekri a felhasznl vezetk- s keresztnevt. Ksztsnk programot, amely ezen adatokat fjlba menti. 2. Ksztsnk programot, amely az elbbi feladatban mentett adatokat kiolvassa a fjlbl. rjuk ki azokat a bngszbe (minden sor vgn hasznljunk <BR> cmkt). rjuk ki, hny sort tartalmaz a fjl, illetve a fjl mrett.

10

11. RA
A DBM fggvnyek hasznlata
Ha nem is frnk hozz valamilyen SQL adatbziskezelhz (mint a MySQL vagy az Oracle), majdnem biztos, hogy valamilyen DBM-szer adatbzisrendszer rendelkezsnkre ll. Ha mgsem, a PHP akkor is kpes utnozni szmunkra egy ilyen rendszer mkdst. A DBM fggvnyek segtsgvel lnyegben nvrtk prokat trolhatunk s kezelhetnk. Noha ezek a fggvnyek nem biztostjk szmunkra egy SQL adatbzis erejt, rugalmasak s knnyen hasznlhatk. Mivel a formtum igen elterjedt, az e fggvnyekre pl kd ltalban hordozhat, noha maguk a DBM adatokat tartalmaz llomnyok nem azok. Ebben az rban a kvetkez tmkkal foglalkozunk: Megtanuljuk a DBM adatbzisok kezelst. Adatokkal tltnk fel egy adatbzist. Visszanyerjk adatainkat egy adatbzisbl. Elemeket mdostunk. Megtanuljuk, hogyan troljunk bonyolultabb adatokat egy DBM adatbzisban.

194

11. ra

DBM adatbzis megnyitsa


A DBM adatbzisokat a dbmopen() fggvnnyel nyithatjuk meg, amelynek kt paramtert kell tadnunk: a DBM fjl elrsi tvonalt s a megnyits mdjra vonatkoz kapcsolkat. A fggvny egy klnleges DBM azonostval tr vissza, amelyet aztn a klnbz egyb DBM fggvnyekkel az adatbzis elrsre s mdostsra hasznlhatunk fel. Mivel a dbmopen()egy fjlt nyit meg rsra vagy olvassra, a PHP-nek joga kell, hogy legyen az adatbzist tartalmaz knyvtr elrsre. A dbmopen() fggvnynek a 11.1. tblzatban felsorolt kapcsolkkal adhatjuk meg, milyen mveleteket kvnunk vgrehajtani az adatbzison.

11.1. tblzat A dbmopen() kapcsoli


Kapcsol r
w c n

Jelents Az adatbzist csak olvassra nyitja meg.


Az adatbzist rsra s olvassra nyitja meg. Ltrehozza az adatbzist (ha ltezik, akkor rsra/olvassra nyitja meg). Ltrehozza az adatbzist (ha mr ltezik ilyen nev, trli az elz vltozatot).

A kvetkez kdrszlet megnyit egy adatbzist, ha pedig nem ltezne a megadott nven, jat hoz ltre: $dbm = dbmopen( "./adat/termekek", "c" ) or die( "Nem lehet megnyitni a DBM adatbzist." ); Vegyk szre, hogy ha nem sikerlne az adatbzis megnyitsa, a program futst a die() fggvnnyel fejezzk be. Ha befejeztk a munkt, zrjuk be az adatbzist a dbmclose() fggvnnyel. Ez azrt szksges, mert a PHP automatikusan zrolja a megnyitott DBM adatbzist, hogy ms folyamatok ne frhessenek hozz a fjlhoz, mialatt a tartalmt olvassuk vagy rjuk. Ha az adatbzist nem zrjuk be, a vrakoz folyamatok azutn sem rhetik el az adatbzist, amikor mr befejeztk a munkt. A dbmclose() fggvny paramtere egy rvnyes DBM azonost: dbmclose ( $dbm );

A DBM fggvnyek hasznlata

195

Adatok felvtele az adatbzisba


j nvrtk prt a dbminsert() fggvnnyel vehetnk fel az adatbzisba. A fggvnynek hrom paramtere van: egy rvnyes DBM azonost (amelyet a dbmopen() adott vissza), a kulcs s a troland rtk. A visszatrsi rtk 0, ha sikeres volt a mvelet; 1, ha az elem mr szerepel az adatbzisban; s -1 brmilyen ms hiba esetn (pldul rsi ksrlet egy csak olvassra megnyitott adatbzisba). A dbminsert()mr ltez elemet nem r fell. A 11.1. programban ltrehozzuk s megnyitjuk a termekek nev adatbzist s feltltjk adatokkal.

11.1. program Adatok felvtele DBM adatbzisba.


1: <html> 2: <head> 3: <title>11.1. program Adatok felvtele DBM adatbzisba</title> 4: </head> 5: <body> 6: Termkek hozzadsa... 7: 8: <?php 9: $dbm = dbmopen( "./adat/termekek", "c" ) or die( "Nem lehet megnyitni a DBM adatbzist." ); 10: 11: dbminsert( $dbm, "Ultrahangos csavarhz", "23.20" ); 12: dbminsert( $dbm, "Tricorder", "55.50" ); 13: dbminsert( $dbm, "ORAC AI", "2200.50" ); 14: dbminsert( $dbm, "HAL 2000", "4500.50" ); 15: 16: dbmclose( $dbm ); 17: ?> 18: </body> 19: </html>

11

Az adatbzisba illeszts sorn az sszes rtk karakterlncc alakul, gy a termkek rainak megadsakor idzjeleket kell hasznlnunk. Termszetesen az adatbzisbl kiolvass utn ezeket az rtkeket lebegpontos szmokknt is kezelhetjk, amennyiben szksges. Vegyk szre, hogy nem csak egyszavas kulcsokat hasznlhatunk.

196

11. ra Ha ezek utn meghvjuk a dbminsert() fggvnyt egy olyan kulcsrtkkel, amely mr ltezik az adatbzisban, a fggvny az 1 rtket adja vissza s nem mdostja az adatbzist. Bizonyos krlmnyek kztt pontosan erre van szksg, de elfordulhat olyan eset is, amikor mdostani szeretnnk egy meglv adatot, vagy ha nem tallhat ilyen kulcs az adatbzisban, j adatot szeretnnk felvinni.

Adatok mdostsa az adatbzisban


A DBM adatbzisban a bejegyzseket a dbmreplace() fggvnnyel mdosthatjuk. A fggvny paramterei: egy rvnyes DBM azonost, a kulcs neve s az j rtk. A visszatrsi rtk a hibakd: 0, ha minden rendben volt s 1, ha valamilyen hiba lpett fel. A 11.2. pldban az elz program egy j vltozata lthat, amely a kulcsokat korbbi megltktl fggetlenl felveszi az adatbzisba.

11.2. program Elemek felvtele vagy mdostsa DBM adatbzisban


1: <html> 2: <head> 3: <title>11.2. program Elemek felvtele vagy mdostsa DBM adatbzisban</title> 4: </head> 5: <body> 6: Termkek hozzadsa... 7: <?php 8: $dbm = dbmopen( "./adat/termekek", "c" ) 9: or die( "Nem lehet megnyitni a DMB adatbzist." ); 10: dbmreplace( $dbm, "Ultrahangos csavarhz", "25.20" ); 11: dbmreplace( $dbm, "Tricorder", "56.50" ); 12: dbmreplace( $dbm, "ORAC AI", "2209.50" ); 13: dbmreplace( $dbm, "HAL 2000", "4535.50" ); 14: dbmclose( $dbm ); 15: ?> 16: </body> 17: </html>

A program mkdsnek mdostshoz mindssze t kell rnunk a dbminsert() fggvnyhvst dbmreplace()-re.

A DBM fggvnyek hasznlata

197

Adatok kiolvassa DBM adatbzisbl


Egyetlen elemet a dbmfetch() fggvny segtsgvel olvashatunk ki az adatbzisbl. Ebben az esetben kt paramtert kell tadnunk: egy ltez DBM azonostt s az elrni kvnt kulcs nevt. A fggvny visszatrsi rtke egy karakterlnc, a kulcshoz tartoz rtk lesz. A "Tricorder" elem rt pldul a kvetkez fggvnyhvssal krdezhetjk le: $ar = dbmfetch( $dbm, "Tricorder" ); Ha "Tricorder" elem nem tallhat az adatbzisban, a dbmfetch()egy res karakterlnccal tr vissza. Nem mindig ismerjk azonban az adatbzisban tallhat kulcsokat. Mit tennnk pldul akkor, ha ki kellene rni a bngszablakba az sszes termket s a hozzjuk tartoz rakat, anlkl, hogy belegetnnk a programba a termkek nevt? A PHP biztost egy mdszert, amellyel az adatbzisban szerepl sszes elemen vgiglpkedhetnk. Az adatbzis els kulcst a dbmfirstkey() fggvnnyel krdezhetjk le. A fggvny paramtere egy rvnyes DBM azonost, visszatrsi rtke pedig a legels kulcs. Termszetesen ez nem felttlenl egyezik meg az elsknt beillesztett adattal, ugyanis a DBM adatbziskezelk gyakran sajt rendezsi eljrst hasznlnak. Miutn megkaptuk a legels kulcsot, az sszes rkvetkez elemet a dbmnextkey() fggvny ismtelt hvsval krdezhetjk le. A fggvny paramterknt szintn egy rvnyes DBM azonostt vr, visszatrsi rtke pedig a kvetkez kulcs a sorban. Ha ezeket a fggvnyeket egytt hasznljuk a dbmfetch()-csel, az adatbzis teljes tartalmt kiolvashatjuk. A 11.3. pldaprogram a termekek adatbzis teljes tartalmt kirja a bngszbe.

11

11.3. program DBM adatbzis sszes bejegyzsnek kiolvassa


1: 2: 3: 4: 5: 6: 7: 8: 9: <html> <head> <title>11.3. program DBM adatbzis sszes bejegyzsnek kiolvassa</title> </head> <body> A Hihetetlen Ktyk Boltja a kvetkez izgalmas termkeket knlja nnek:

198

11. ra

11.3. program (folytats)


10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: <p> <table border="1" cellpadding="5"> <tr> <td align="center"> <b>Termk</b> </td> <td align="center"> <b>r</b> </td> </tr> <?php $dbm = dbmopen( "./adat/termekek", "c" ) or die( "Nem lehet megnyitni a DBM adatbzist." ); $kulcs = dbmfirstkey( $dbm ); while ( $kulcs != "" ) { $ertek = dbmfetch( $dbm, $kulcs ); print "<tr><td align = \"left\"> $kulcs </td>"; print "<td align = \"right\"> \$$ertek </td></tr>"; $kulcs = dbmnextkey( $dbm, $kulcs ); } dbmclose( $dbm ); ?> </table> </body> </html>

A 11.1. brn a 11.3. program eredmnye lthat.

11.1. bra
A DBM adatbzis sszes bejegyzsnek lekrdezse.

A DBM fggvnyek hasznlata

199

Elemek megltnek lekrdezse


Mieltt kiolvasnnk vagy mdostannk egy elemet, hasznos lehet tudni, hogy ltezik-e egyltaln ilyen kulcs elem az adatbzisban vagy sem. Erre a clra a dbmexists() fggvny szolgl, amely paramterknt egy rvnyes DBM azonostt vr, illetve az ellenrizend elem nevt. A visszatrsi rtk true, ha az elem ltezik. if ( dbmexists( $dbm, "Tricorder" ) ) print dbmfetch( $dbm, "Tricorder" );

Elem trlse az adatbzisbl


Az adatbzisbl elemeket a dbmdelete() fggvnnyel trlhetnk. A fggvny bemen paramtere egy rvnyes DBM azonost s a trlend elem neve. Sikeres trls esetn a visszatrsi rtk true, egyb esetben (pldul ha az elem nem ltezik) false. dbmdelete( $dbm, "Tricorder" );

11

sszetett adatszerkezetek trolsa DBM adatbzisban


A DBM adatbzisban minden adat karaktersorozat formjban troldik, ezrt az egsz s lebegpontos szmokon, illetve karakterlncokon kvl minden egyb adattpus elvsz. Prbljunk meg pldul egy tmbt trolni: $tomb = array( 1, 2, 3, 4 ); $dbm = dbmopen( "./adat/proba", "c" ) or die("Nem lehet megnyitni a DBM adatbzist."); dbminsert( $dbm, "tombproba", $tomb ); print gettype( dbmfetch( $dbm, "tombproba" ) ); // A kimenet: "string" Itt ltrehozunk egy tmbt s a $tomb vltozba helyezzk. Ezutn megnyitjuk az adatbzist s beszrjuk a tmbt tombproba nven, majd megvizsgljuk a dbmfetch() fggvny visszatrsi tpust, amikor megprbljuk visszaolvasni a tombproba elemet lthatjuk, hogy karakterlncot kaptunk vissza. Ha kirattuk volna a tombproba elem rtkt, az "Array" karakterlncot kaptuk volna. gy ltszik, ezzel el is szott minden remnynk arra, hogy tmbket vagy ms sszetett adatszerkezetet troljunk a DBM adatbzisban.

200

11. ra Szerencsre a PHP rendelkezik egy olyan lehetsggel, amely segtsgvel a bonyolultabb szerkezeteket is egyszer karaktersorozatt alakthatjuk. Az gy kdolt szerkezetet mr trolhatjuk ksbbi hasznlatra, DBM adatbzisban vagy akr fjlban is. Az talaktst a serialize() fggvnnyel vgezhetjk el, amelynek bemen paramtere egy tetszleges tpus vltoz, a visszaadott rtk pedig egy karakterlnc: $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;}" A DBM adatbzisban ezt a karakterlncot trolhatjuk. Ha vissza akarjuk lltani eredeti formjra, az unserialize() fggvnyt kell hasznlnunk. Ezzel a mdszerrel lehetsgnk nylik sszetett adatszerkezetek trolsra a DBM adatbzisok ltal knlt egyszer eszkzkkel is. A 11.4. listban egy asszociatv tmb tartalmazza a termkekrl rendelkezsre ll informcikat ezt alaktjuk t karakterlncc s helyezzk egy DBM adatbzisba.

11.4. program sszetett adatszerkezetek trolsa DBM adatbzisban


1: <html> 2: <head> 3: <title>11.4. program sszetett adatszerkezetek trolsa DBM adatbzisban</title> 4: </head> 5: <body> 6: sszetett adatok trolsa 7: <?php 8: $termekek = array( 9: "Ultrahangos csavarhz" => array( "ar"=>"22.50", 10: "szallitas"=>"12.50", 11: "szin"=>"zld" ), 12: "Tricorder" => array( "ar"=>"55.50", 13: "szallitas"=>"7.50", 14: "szin"=>"vrs" ), 15: "ORAC AI" => array( "ar"=>"2200.50", 16: "szallitas"=>"34.50", 17: "szin"=>"kk" ), 18: "HAL 2000" => array( "ar"=>"4500.50", 19: "szallitas"=>"18.50", 20: "szin"=>"rzsaszn" ) 21: );

A DBM fggvnyek hasznlata

201

11.4. program (folytats)


22: 23: 24: 25: 26: 27: 28: 29: $dbm = dbmopen( "./adat/ujtermekek", "c" ) or die("Nem lehet megnyitni a DBM adatbzist."); foreach( $termekek as $kulcs => $ertek ) dbmreplace( $dbm, $kulcs, serialize( $ertek ) ); dbmclose( $dbm ); ?> </body> </html>

A listban egy tbbdimenzis tmbt ptnk fel, amely kulcsknt tartalmazza a termk nevt s hrom tmbelemben trolja a sznt, az rat s a szllts kltsgt. Ezutn egy ciklus segtsgvel feldolgozzuk az sszes elemet: a termk nevt s a karakterlncc alaktott tmbt tadjuk a dbmreplace() fggvnynek. Ezutn lezrjuk az adatbzist. A 11.5. program az adatok visszatltsre ad megoldst.

11

11.5. program sszetett adatszerkezetek visszaolvassa DBM adatbzisbl


1: <html> 2: <head> 3: <title>11.5. program sszetett adatszerkezetek visszaolvassa 4: DBM adatbzisbl</title> 5: </head> 6: <body> 7: A Hihetetlen Ktyk Boltja 8: a kvetkez izgalmas termkeket knlja 9: nnek: 10: <p> 11: <table border="1" cellpadding ="5"> 12: <tr> 13: <td align="center"> <b>Termk</b> </td> 14: <td align="center"> <b>Szn</b> </td> 15: <td align="center"> <b>Szllts</b> </td> 16: <td align="center"> <b>r</b> </td> 17: </tr> 18: <?php

202

11. ra

11.5. program (folytats)


19: $dbm = dbmopen( "./adat/ujtermekek", "c" ) 20: or die(Nem lehet megnyitni a DBM adatbzist."); 21: $kulcs = dbmfirstkey( $dbm ); 22: while ( $kulcs != "" ) 23: { 24: $termektomb = unserialize( dbmfetch( $dbm, $kulcs ) ); 25: print "<tr><td align=\"left\"> $kulcs </td>"; 26: print '<td align="left" $termektomb["szin"] "</td>"; 27: print '<td align="right"$ $termektomb["szallitas"] "</td>"; 28: print '<td align="right"$ $termektomb["ar"] "</td></tr>\n"; 29: $kulcs = dbmnextkey( $dbm, $kulcs ); 30: } 31: dbmclose( $dbm ); 32: ?> 33: </table> 34: </body> 35: </html> Ez a megolds hasonl a 11.3. pldban ltottakhoz, de ebben az esetben tbb mezt nyomtatunk ki. Megnyitjuk az adatbzist s a dbmfirstkey(), illetve a dbmnextkey() fggvnnyel beolvassuk az sszes adatot az adatbzisbl. A ciklusban az unserialize() fggvnnyel ltrehozzuk a termkeket tartalmaz tmbt. gy mr egyszer feladat kiratni az sszes elemet a bngszablakba. A 11.2. brn a 11.5. program kimenete lthat.

11.2. bra
sszetett adatszerkezetek visszaolvassa DBM adatbzisbl

A DBM fggvnyek hasznlata

203

Egy plda
Mr eleget tudunk ahhoz, hogy elksztsnk egy mkdkpes programot az ebben az rban tanult mdszerekkel. A feladat a kvetkez: ksztsnk egy karbantart oldalt, ahol a webhely szerkesztje megvltoztathatja a 11.2. pldaprogram ltal ltrehozott adatbzis termkeinek rt. Tegyk lehetv a rendszergazda szmra, hogy j elemekkel bvtse az adatbzist, illetve hogy a rgi elemeket trlje. Az oldalt nem tesszk nyilvnos kiszolgln elrhetv, ezrt a biztonsgi krdsekkel most nem foglalkozunk. Elszr is fel kell ptennk az rlapot, amely az adatbzis elemeit tartalmazza. A termkek rnak mdostshoz szksgnk lesz egy szvegmezre s minden elemhez tartozni fog egy jellngyzet is, melynek segtsgvel az adott elemet trlsre jellhetjk ki. A lapon el kell helyeznnk kt tovbbi szvegmezt is, az j elemek felvtelhez. A 11.6. pldban az oldalt elkszt program olvashat.

11

11.6. program HTML rlap ksztse DBM adatbzis alapjn


1: <? 2: $dbm = dbmopen( "./adat/termekek", "c" ) 3: or die("Nem lehet megnyitni a DBM adatbzist."); 4: ?> 5: <html> 6: <head> 7: <title>11.6. program HTML rlap ksztse 8: DBM adatbzis alapjn </title> 9: </head> 10: <body> 11: <form method="POST"> 12: <table border="1"> 13: <tr> 14: <td>Trls</td> 15: <td>Termk</td> 16: <td>r</td> 17: </tr> 18: <?php 19: $kulcs = dbmfirstkey( $dbm ); 20: while ( $kulcs != "" ) 21: { 22: $ar = dbmfetch( $dbm, $kulcs ); 23: print "<tr><td> <input type=\"checkbox"\ name=\"torles[]\" ";

204

11. ra

11.6. program (folytats)


24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: print "value=\"$kulcs\"> </td>"; print "<td> $kulcs </td>"; print "<td> <input type=\"text\" name=\"arak[$kulcs]\" "; print "value=\"$ar\"> </td></tr>"; $kulcs = dbmnextkey( $dbm, $kulcs ); } dbmclose( $dbm ); ?> <tr> <td>&nbsp;</td> <td><input type="text" name="uj_nev"></td> <td><input type="text" name="uj_ar"></td> </tr> <tr> <td colspan="3" align="right"> <input type="submit" value="Vltoztat"> </td> </tr> </table> </form> </body> </html>

Szoks szerint az els lps az adatbzis megnyitsa. Ezutn megkezdnk egy rlapot s mivel nem adunk meg cloldalt, feldolgoz programknt magt az oldalt jelljk ki. Elksztjk a tblzat fejlct, majd vgigolvassuk az adatbzist a dbmfirstkey() s dbmnextkey() fggvnyek segtsgvel, az rtkeket a dbmfetch() fggvnnyel olvasva ki. A tblzat els mezje minden sorban egy jellngyzetet tartalmaz. Vegyk szre, hogy mindegyik jellngyzet neve "torles[]". Ennek hatsra a PHP ltrehozza a $torles tmbt, amely az sszes bejellt elemet tartalmazza. A jellngyzetekhez tartoz rtkek, gy a $torles tmb elemei is azok az azonostk lesznek, amelyekkel a DBM adatbzis az adott termket nyilvntartja (ezt az rtket a $kulcs vltozban troljuk). gy, miutn a rendszergazda kitlttte s elkldte az rlapot, a program $torles tmbje azon adatbzis-elemek kulcsait fogja trolni, amelyeket trlnnk kell.

A DBM fggvnyek hasznlata Ezutn kirjuk a bngszablakba az elem nevt s ltrehozunk egy szveges mezt a termk rnak. A mezt ugyanolyan mdon nevezzk el, mint az elzt, ezttal azonban a szgletes zrjelek kz berjuk az azonostt, amely alapjn a DBM adatbzis az elemet trolja. A PHP ennek hatsra ltrehozza az $arak tmbt, amelyben a kulcsok a termkek azonosti. Lezrjuk az adatbzist s visszatrnk HTML mdba az j bejegyzs ltrehozsra szolgl uj_nev s uj_ar mezk megjelentshez. A 11.3. brn a 11.6. program kimenett lthatjuk.

205

11.3. bra
HTML rlap ksztse DBM adatbzis alapjn

11

Miutn elksztettk az rlapot, meg kell rnunk a kdot, amely a felhasznl ltal megadott adatokat kezeli. A feladat nem olyan nehz, mint amilyennek ltszik. Elszr trljk a kijellt elemeket az adatbzisbl, majd mdostjuk az rakat, vgl felvesszk az j elemet az adatbzisba. Miutn a karbantart kitlttte s elkldte az rlapot, a trlend elemek listja a $torles tmbben ll rendelkezsnkre. Mindssze annyi a dolgunk, hogy vgigolvassuk a tmbt, s az sszes elemt trljk az adatbzisbl. if ( isset ( $torles ) ) { foreach ( $torles as $kulcs => $ertek ) { unset( $arak[$ertek]); dbmdelete( $dbm, $ertek ); } }

206

11. ra Elszr is megvizsgljuk, hogy ltezik-e a $torles vltoz. Ha a felhasznl csak most rkezett az oldalra vagy nem jellt ki trlse egyetlen termket sem, a vltoz nem ltezik. Ellenkez esetben egy ciklus segtsgvel vgigolvassuk s minden elemre meghvjuk a dbmdelete() fggvnyt, amely eltvoltja a DBM adatbzisbl a paramterknt megadott elemet. Hasonlan jrunk el az $arak tmb esetben is, itt azonban a PHP unset() fggvnyt kell hasznlnunk a tmbelem trlsre. Az $arak tmb a felhasznltl rkezett, felteheten rszben mdostott rakat tartalmazza. Ha nem trlnnk az $arak tmbbl a megfelel elemet, a kvetkez kd jra beilleszten. Az adatbzis elemeinek frisstse sorn kt vlasztsi lehetsgnk van. Az els vltozatot akkor alkalmazzuk, ha az adatbzis karbantartst nem egyetlen szerkeszt fogja vgezni, teht felttelezhet, hogy a programot egyidben tbb felhasznl is futtatni fogja eszerint csak azokat az elemeket vltoztatjuk meg, amelyeket a felhasznl kijellt. A msik vltozat, amely az sszes elemet megvltoztatja, akkor alkalmazhat, ha a program csak egyetlen pldnyban futhat: if ( isset ( $arak ) ) { foreach ( $arak as $kulcs => $ertek ) dbmreplace( $dbm, $kulcs, $ertek ); } Elszr is ellenriznnk kell az $arak tmb megltt. Ebben a tmbben az adatbzis egy teljesen j vltozata lehet. Egy ciklus segtsgvel teht vgigolvassuk az sszes elemet s egyesvel frisstjk az adatbzisban. Vgl ellenriznnk kell, hogy a felhasznl kezdemnyezte-e j elem felvtelt az adatbzisba: if ( ! empty( $uj_nev ) && ! empty( $uj_ar ) ) dbminsert( $dbm, "$uj_nev", "$uj_ar" ); Ahelyett, hogy az $uj_nev s $uj_ar megltt ellenriznnk, azt kell ellenriznnk, hogy rtkk nem res-e. Ez apr, de lnyeges klnbsg. Amikor a felhasznl elkldi az rlapot, a vltozk mindenkppen ltrejnnek, de ha a szvegmezk nem kaptak rtket, a megfelel vltozk res karakterlncot tartalmaznak. Mivel nem akarunk res elemeket trolni az adatbzisban, fontos ellenrizni, hogy nem resek-e a vltozk. Azrt hasznljuk a dbminsert() fggvnyt a dbmreplace() helyett, hogy elkerljk a mr bevitt termkek vletlen fellrst. A teljes kdot a 11.7. plda tartalmazza.

A DBM fggvnyek hasznlata

207

11.7. program A teljes adatbzis-karbantart program


1: <?php 2: $dbm = dbmopen( "./adat/termekek", "c" ) 3: or die("Nem lehet megnyitni a DBM adatbzist.); 4: 5: if ( isset ( $torles ) ) 6: { 7: foreach ( $torles as $kulcs => $ertek ) 8: { 9: unset( $arak[$ertek]); 10: dbmdelete( $dbm, $ertek ); 11: } 12: } 13: 14: if ( isset ( $arak ) ) 15: { 16: foreach ( $arak as $kulcs => $ertek ) 17: dbmreplace( $dbm, $kulcs, $ertek ); 18: } 19: 20: if ( ! empty( $uj_nev ) && ! empty( $uj_ar ) ) 21: dbminsert( $dbm, "$uj_nev", "$uj_ar" ); 22: ?> 23: 24: <html> 25: <head> 26: <title>11.7. program A teljes adatbzis-karbantart program </title> 27: </head> 28: <body> 29: 30: <form method="POST"> 31: 32: <table border="1"> 33: <tr> 34: <td>Trls</td> 35: <td>Termk</td> 36: <td>r</td> 37: </tr> 38: 39: <?php

11

208

11. ra

11.7. program (folytats)


40: $kulcs = dbmfirstkey( $dbm ); 41: while ( $kulcs != "" ) 42: { 43: $ar = dbmfetch( $dbm, $kulcs ); 44: print "<tr><td> <input type=\"checkbox"\ name=\"torles[]\" "; 45: print "value=\"$kulcs\"> </td>"; 46: print "<td> $kulcs </td>"; 47: print "<td> <input type=\"text\" name=\"arak[$kulcs]\" "; 48: print "value=\"$ar\"> </td></tr>"; 49: $kulcs = dbmnextkey( $dbm, $kulcs ); 50: } 51: 52: dbmclose( $dbm ); 53: ?> 54: 55: <tr> 56: <td>&nbsp;</td> 57: <td><input type="text" name="uj_nev"></td> 58: <td><input type="text" name="uj_ar"></td> 59: </tr> 60: 61: <tr> 62: <td colspan="3" align="right"> 63: <input type="submit" value="Vltoztat"> 64: </td> 65: </tr> 66: 67: </table> 68: </form> 69: 70: </body> 71: </html>

A DBM fggvnyek hasznlata

209

sszefoglals
Ebben az rban megtanultuk, hogyan hasznljuk a PHP hatkony DBM fggvnyeit adatok trolsra s visszaolvassra. Megtanultuk a dbmopen() hasznlatt egy j DBM azonost ltrehozsra. Ezt az azonostt hasznltuk az sszes tbbi DBM fggvnynl is. j adatokat adtunk az adatbzishoz a dbminsert() fggvnnyel, mdostottunk meglevket a dbmreplace()-szel s trltnk a dbmdelete() hasznlatval. Megtanultuk, hogyan hasznlhatjuk a dbmfetch() fggvnyt az adatok visszaolvassra. A serialize() s unserialize() fggvnyekkel sszetett adatszerkezeteket troltunk DBM adatbzisban, vgl egy gyakorlati pldn keresztl megnztk, hogyan is hasznlhatk fel e mdszerek a vals problmk megoldsra.

Krdsek s vlaszok
Mikor hasznljak DBM adatbzist SQL adatbzis helyett? A DBM j vlaszts, ha kis mennyisg s viszonylag egyszer szerkezet adatot szeretnnk trolni (nvrtk prokat). A DBM adatbzist hasznl programok rendelkeznek a hordozhatsg nagyon fontos elnyvel, de ha nagyobb mennyisg adatot kell trolnunk, vlasszunk inkbb egy SQL adatbziskezelt, pldul a MySQL-t.

11

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Melyik fggvnyt hasznlhatjuk egy DBM adatbzis megnyitshoz? 2. Melyik fggvnnyel szrhatunk be j elemet egy DBM adatbzisba? 3. Melyik fggvnnyel mdosthatunk egy elemet? 4. Hogyan rnk el egy elemet az adatbzisban, ha ismerjk a nevt? 5. Hogyan olvasnnk ki egy DBM adatbzisbl a legels elem nevt (nem az rtkt)? 6. Hogyan rjk el a tovbbi neveket? 7. Hogyan trlnk egy elemet a DBM adatbzisbl, ha ismerjk a nevt?

210

11. ra

Feladatok
1 Hozzunk ltre egy DBM adatbzist a felhasznlk azonostinak s jelszavainak trolsra. Ksztsnk egy programot, amellyel a felhasznlk ltrehozhatjk a rjuk vonatkoz bejegyzst. Ne feledjk, hogy kt azonos nev elem nem kerlhet az adatbzisba. 2 Ksztsnk egy bejelentkez programot, amely ellenrzi a felhasznl azonostjt s jelszavt. Ha a felhasznli bemenet egyezik valamelyik bejegyzssel az adatbzisban, akkor dvzljk a felhasznlt valamilyen klnleges zenettel. Egybknt jelentsk meg jra a bejelentkez rlapot.

12. RA
Adatbzisok kezelse MySQL
A PHP nyelv egyik meghatroz tulajdonsga, hogy nagyon knnyen kpes adatbzisokhoz csatlakozni s azokat kezelni. Ebben az rban elssorban a MySQL adatbzisokkal foglalkozunk, de amint majd szre fogjuk venni, a PHP ltal tmogatott sszes adatbzist hasonl fggvnyek segtsgvel rhetjk el. Mirt esett a vlaszts ppen a MySQL-re? Mert ingyenes, ugyanakkor nagyon hatkony eszkz, amely kpes megfelelni a vals feladatok ltal tmasztott ignyeknek is. Az sem elhanyagolhat szempont, hogy tbbfle rendszerhez is elrhet. A MySQL adatbziskiszolglt a http://www.mysql.com cmrl tlthetjk le. Ebben az rban a kvetkez tmkkal foglalkozunk: Megnznk nhny SQL pldt. Csatlakozunk egy MySQL adatbziskiszolglhoz. Kivlasztunk egy adatbzist. Tanulunk a hibakezelsrl. Adatokat visznk fel egy tblba.

212

12. ra Adatokat nyernk ki egy tblbl. Megvltoztatjuk egy adattbla tartalmt. Megjelentjk az adatbzis szerkezett.

(Nagyon) rvid bevezets az SQL nyelvbe


JDONSG Az SQL jelentse Structured Query Language, vagyis strukturlt lekrdez nyelv. Az SQL szabvnyostott nyelvezete segtsgvel a klnbz tpus adatbzisokat azonos mdon kezelhetjk. A legtbb SQL termk sajt bvtsekkel ltja el a nyelvet, ahogy a legtbb bngsz is sajt HTML nyelvjrst beszl. Mindazonltal SQL ismeretek birtokban nagyon sokfle adatbzist fogunk tudni hasznlni, a legklnbzbb opercis rendszereken. A knyvben terjedelmi okok miatt mg bevezet szinten sem trgyalhatjuk az SQL-t, de megprblunk megvilgtani egy-kt dolgot a MySQL-lel s ltalban az SQL-lel kapcsolatban. A MySQL kiszolgl dmonknt fut a szmtgpen, gy a helyi vagy akr tvoli gpek felhasznli brmikor csatlakozhatnak hozz. Miutn a csatlakozs megtrtnt, ki kell vlasztanunk a megfelel adatbzist, ha van jogunk hozz. Egy adatbzison bell tbb adattblnk is lehet. Minden tbla oszlopokbl s sorokbl ll. A sorok s oszlopok metszspontjban troljuk az adatokat. Minden oszlopba csak elre megadott tpus adatot tlthetnk, az INT tpus pldul egsz szmot, mg a VARCHAR vltoz hosszsg, de egy adott rtknl nem hosszabb karakterlncot jelent. A kivlasztott adatbzisban a kvetkez SQL utastssal hozhatunk ltre j tblt: CREATE TABLE entablam ( keresztnev VARCHAR(30), vezeteknev VARCHAR(30), kor INT ); Ez a tbla hrom oszlopot tartalmaz. A keresztnev s vezeteknev oszlopokba legfeljebb 30 karaktert rhatunk, mg a kor oszlopba egy egsz szmot. A tblba j sort az INSERT paranccsal vehetnk fel: INSERT INTO entablam ( keresztnev, vezeteknev, kor ) VALUES ( 'Jnos', 'Kovcs', 36 );

Adatbzisok kezelse MySQL A mezneveket az els, zrjelek kzti kifejezssel adjuk meg, mg az rtkeket a megfelel sorrendben a msodik zrjelpr kztt soroljuk fel. A tblbl az sszes adatot a SELECT paranccsal kaphatjuk meg: SELECT * FROM entablam; A * szoksos helyettest karakter, jelentse az sszes mez. Ha nem az sszes mez tartalmt akarjuk lekrdezni, rjuk be az rintett mezk neveit a csillag helyre: SELECT kor, keresztnev FROM entablam; Mr ltez bejegyzst az UPDATE paranccsal mdosthatunk. UPDATE entablam SET keresztnev = 'Gbor'; Az utasts az sszes sorban "Gbor"-ra mdostja a keresztnev mez tartalmt. A WHERE zradkkal leszkthetjk a SELECT s UPDATE parancsok hatskrt. Pldul: SELECT * FROM entablam WHERE keresztnev = 'Gbor'; Ez az utasts csak azokat a sorokat rja ki, amelyekben a keresztnev mez rtke "Gbor". A kvetkez plda csak azokban a sorokban vltoztatja "Gbor"-ra a keresztnev mez rtkt, ahol a vezeteknev mez a "Szakcs" karakterlncot tartalmazza. UPDATE entablam SET keresztnev = "Gbor" WHERE vezeteknev = = "Szakcs"; Az SQL-rl tovbbi informcikat tallunk Ryan K. Stephens s szerztrsai Teach Yourself SQL in 21 Days cm knyvben.

213

12

Csatlakozs a kiszolglhoz
Mieltt elkezdhetnnk dolgozni az adatbzissal, csatlakoznunk kell a kiszolglhoz. A PHP-ben erre a mysql_connect() fggvny szolgl. A fggvny hrom karakterlncot vr paramterknt: a gazdagp nevt, a felhasznl nevt s a jelszt. Ha ezek egyikt sem adjuk meg, a fggvny felttelezi, hogy a krs a localhost-ra (azaz a helyi gpre) vonatkozik s felhasznlknt a PHP-t futtat felhasznlt, jelszknt pedig egy res karakterlncot ad t. Az alaprtelmezs

214

12. ra a php.ini fjlban fellbrlhat, de egy prblkozsra sznt kiszolglt kivve nem blcs dolog ezzel prblkozni, ezrt a pldkban mindig hasznlni fogjuk a felhasznlnevet s a jelszt. A mysql_connect() fggvny siker esetn egy kapcsolatazonostt ad vissza, amelyet egy vltozba mentnk, hogy a ksbbiekben folytathassuk a munkt az adatbziskiszolglval. Az albbi kdrszlet a mysql_connect() fggvny segtsgvel kapcsoldik a MySQL adatbziskiszolglhoz. $kapcsolat = mysql_connect( "localhost", "root", "jelszo" ); if ( ! $kapcsolat ) die( "Nem lehet csatlakozni a MySQL kiszolgalohoz!" ); Ha a PHP-t az Apache kiszolgl moduljaknt hasznljuk, a mysql_pconnect() fggvnyt is hasznlhatjuk az elzekben megadott paramterekkel. Fontos klnbsg a kt fggvny kztt, hogy a mysql_pconnect()-tel megnyitott adatbziskapcsolat nem sznik meg a PHP program lefutsval vagy a mysql_close() fggvny hatsra (amely egy szoksos MySQL kiszolglkapcsolat bontsra szolgl) , hanem tovbbra is aktv marad s olyan programokra vrakozik, amelyek a mysql_pconnect() fggvnyt hvjk. Ms szval a mysql_pconnect() fggvny hasznlatval megtakarthatjuk azt az idt, ami egy kapcsolat felptshez szksges s egy elzleg lefutott program ltal hagyott azonostt hasznlhatunk.

Az adatbzis kivlasztsa
Miutn kialaktottuk a kapcsolatot a MySQL dmonnal, ki kell vlasztanunk, melyik adatbzissal szeretnnk dolgozni. Erre a clra a mysql_select_db() fggvny szolgl, amelynek meg kell adnunk a kivlasztott adatbzis nevt s szksg szerint egy kapcsolatazonost rtket. Ha ez utbbit elhagyjuk, automatikusan a legutoljra ltrehozott kapcsolat helyettestdik be. A mysql_select_db() fggvny igaz rtket ad vissza, ha az adatbzis ltezik s jogunk van a hasznlatra. A kvetkez kdrszlet a pelda nev adatbzist vlasztja ki. $adatbazis = "pelda"; mysql_select_db( $adatbazis ) or die ( "Nem lehet megnyitni a kvetkez adatbzist: $adatbazis" );

Adatbzisok kezelse MySQL

215

Hibakezels
Eddig ellenriztk a MySQL fggvnyek visszatrsi rtkt s hiba esetn a die() fggvnnyel kilptnk a programbl. A hibakezelshez azonban hasznosabb lenne, ha a hibazenetek valamivel tbb informcit tartalmaznnak. Ha valamilyen mvelet nem sikerl, a MySQL bellt egy hibakdot s egy hibazenetet. A hibakdhoz a mysql_errno(), mg a hibazenethez a mysql_error() fggvnnyel frhetnk hozz. A 12.1 plda az eddigi kdrszleteinket teljes programm kapcsolja ssze, amely kapcsoldik az adatbziskezelhz s kivlasztja az adatbzist. A hibazenetet a mysql_error() fggvnnyel tesszk hasznlhatbb.

12.1. program Kapcsolat megnyitsa s az adatbzis kivlasztsa


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: <html> <head> <title>12.1. program Kapcsolat megnyitsa s adatbzis kivlasztsa</title> </head> <body> <?php $felhasznalo = "jozsi"; $jelszo = "bubosvocsok"; $adatbazis = "pelda"; $kapcsolat = mysql_connect( "localhost", $felhasznalo, $jelszo ); if ( ! $kapcsolat ) die( "Nem lehet kapcsoldni a MySQL kiszolglhoz!" ); print "Sikerlt a kapcsolatfelvtel<P>"; mysql_select_db( $adatbazis ) or die ( "Nem lehet megnyitni a $adatbzist: " .mysql_error() ); print "Sikeresen kivlasztott adatbzis: \" $adatbazis\"<P>"; mysql_close( $kapcsolat ); ?> </body> </html>

12

216

12. ra Ha az $adatbazis vltoz rtkt mondjuk "nincsmeg"-re mdostjuk, a program egy nem ltez adatbzist prbl meg elrni. Ekkor a die() kimenete valami ilyesmi lesz: Nem lehet megnyitni a nincsmeg adatbzist: Access denied for user: 'jozsi@localhost' to database 'nincsmeg'

Adatok hozzadsa tblhoz


Mr sikerlt hozzfrst szerezni az adatbzishoz, gy ideje nmi adatot is bevinni a tblkba. A kvetkez pldkhoz kpzeljk el, hogy az ltalunk ksztend oldalon a ltogatknak lehetsgk lesz tartomnyneveket vsrolni. A pelda adatbzisban ksztsk el az t oszlopot tartalmaz tartomanyok tblt. Az azonosito mez lesz az elsdleges kulcs, amely automatikusan nvel egy egsz rtket, ahogy jabb bejegyzsek kerlnek a tblba, a tartomany mez vltoz szm karaktert tartalmazhat (VARCHAR), a nem mez egyetlen karaktert, az email mez pedig a felhasznl elektronikus levlcmt. A tblt a kvetkez SQL paranccsal kszthetjk el: CREATE TABLE tartomanyok ( azonosito INT NOT NULL AUTO_INCREMENT, PRIMARY KEY( azonosito ), tartomany VARCHAR( 20 ), nem CHAR( 1 ), email VARCHAR( 20 ) ); Az adatok felvitelhez ssze kell lltanunk s le kell futtatnunk egy SQL parancsot, erre a clra a PHP-ben a mysql_query() fggvny szolgl. A fggvny paramterknt egy SQL parancsot tartalmaz karakterlncot s szksg szerint egy kapcsolatazonostt vr. Ha ez utbbit elhagyjuk, a fggvny automatikusan az utoljra megnyitott kapcsolaton keresztl prblja meg kiadni az SQL parancsot. Ha a program sikeresen lefutott, a mysql_query()pozitv rtket ad vissza, ha azonban formai hibt tartalmaz vagy nincs jogunk elrni a kvnt adatbzist, a visszatrsi rtk hamis lesz. Meg kell jegyeznnk, hogy egy sikeresen lefutott SQL program nem felttlenl okoz vltozst az adatbzisban vagy tr vissza valamilyen eredmnnyel. A 12.2 pldban kibvtjk a korbbi programot s a mysql_query() fggvnnyel kiadunk egy INSERT utastst a pelda adatbzis tartomanyok tbljn.

Adatbzisok kezelse MySQL

217

12.2. program j sor hozzadsa tblhoz


1: <html> 2: <head> 3: <title>12.2. program j sor hozzadsa tblhoz</title> 4: </head> 5: <body> 6: <?php 7: $felhasznalo = "jozsi"; 8: $jelszo = "bubosvocsok"; 9: $adatbazis = "pelda"; 10: $kapcsolat = mysql_connect( "localhost", $felhasznalo, $jelszo ); 11: if ( ! $kapcsolat ) 12: die( "Nem lehet kapcsoldni a MySQL kiszolglhoz!" ); 13: mysql_select_db( $adatbazis, $kapcsolat ) 14: or die ( "Nem lehet megnyitni a $adatbzist: ".mysql_error() ); 15: $parancs = "INSERT INTO tartomanyok ( tartomany, nem, email ) 16: VALUES ( '123xyz.com', 'F', 'okoska@tartomany.hu' )"; 17: mysql_query( $parancs, $kapcsolat ) 18: or die ( "Nem lehet adatot hozzadni a \"tartomanyok\" tblhoz: " 19: .mysql_error() ); 20: mysql_close( $kapcsolat ); 21: ?> 22: </body> 23: </html>

12

Vegyk szre, hogy nem adtunk rtket az azonosito meznek. A mez rtke automatikusan nvekszik az INSERT hatsra. Termszetesen minden esetben, amikor a bngszben jratltjk a 12.2 pldaprogramot, ugyanaz a sor addik hozz a tblhoz. A 12.3 plda a felhasznl ltal bevitt adatot tlti be a tblba.

218

12. ra

12.3.program A felhasznl ltal megadott adatok beszrsa a tblba


1: <html> 2: <head> 3: <title>12.3. program A felhasznl ltal megadott adatok beszrsa a tblba</title> 4: </head> 5: <body> 6: <?php 7: if ( isset( $tartomany ) && isset( $nem ) && isset( $email ) ) 8: { 9: // Ne feledjk ellenrizni a felhasznl ltal megadott adatokat! 10: $dbhiba = ""; 11: $vissza = adatbazis_bovit( $tartomany, $nem, $email, $dbhiba ); 12: if ( ! $vissza ) 13: print "Hiba: $dbhiba<BR>"; 14: else 15: print "Ksznjk!"; 16: } 17: else { 18: urlap_keszit(); 19: } 20: 21: function adatbazis_bovit( $tartomany, $nem, $email, &$dbhiba ) 22: { 23: $felhasznalo = "jozsi"; 24: $jelszo = "bubosvocsok"; 25: $adatbazis = "pelda"; 26: $kapcsolat = mysql_pconnect( "localhost", $felhasznalo, $jelszo ); 27: if ( ! $kapcsolat ) 28: { 29: $dbhiba = "Nem lehet kapcsoldni a MySQL kiszolglhoz!"; 30: return false; 31: } 32: if ( ! mysql_select_db( $adatbazis, $kapcsolat ) ) 33: { 34: $dbhiba = mysql_error();

Adatbzisok kezelse MySQL

219

12.3.program (folytats)
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; 50: print "<form action=\"$PHP_SELF\" method=\"POST\">\n"; 51: print "A kvnt tartomny<p>\n"; 52: print "<input type=\"text\" name=\"tartomany\"> "; 53: print "Email cm<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\"> Frfi\n"; 58: print "</select>\n"; 59: print "<input type=\"submit\" value=\"Elkld\">\n</form>\n"; 60: } 61: ?> 62: </body> 63: </html>

12

A tmrsg rdekben a 12.3. pldbl kihagytunk egy fontos rszt. Megbztunk a felhasznlkban: semmilyen formban nem ellenriztk a felhasznl ltal bevitt adatokat. Ezt a feladatot a 17. rban trgyalt karakterlnckezel fggvnyekkel vgezhetjk el. Meg kell jegyeznnk, hogy a berkez adatok ellenrzse mindig fontos feladat, itt csak azrt maradt el, mivel gy jobban sszpontosthattunk az ra tmjra.

220

12. ra Ellenrizzk a $tartomany, $nem s $email vltozkat. Ha megvannak, nyugodtan feltehetjk, hogy a felhasznl adatokat kldtt az rlap kitltsvel, gy meghvjuk az adatbazis_bovit() fggvnyt. Az adatbazis_bovit()-nek ngy paramtere van: a $tartomany, a $nem s az $email vltozk, illetve a $dbhiba karakterlnc. Ez utbbiba fogjuk betlteni az esetlegesen felbukkan hibazeneteket, gy hivatkozsknt kell tadnunk. Ennek hatsra ha a fggvnytrzsn bell megvltoztatjuk a $dbhiba rtkt, a msolat helyett tulajdonkppen az eredeti paramter rtkt mdostjuk. Elszr megksrlnk megnyitni egy kapcsolatot a MySQL kiszolglhoz. Ha ez nem sikerl, akkor hozzrendelnk egy hibaszveget a $dbhiba vltozhoz s false rtket visszaadva befejezzk a fggvny futst. Ha a csatlakozs sikeres volt, kivlasztjuk a tartomany tblt tartalmaz adatbzist s sszelltunk egy SQL utastst a felhasznl ltal kldtt rtkek felhasznlsval, majd az utastst tadjuk a mysql_query() fggvnynek, amely elvgzi az adatbzisban a kvnt mveletet. Ha a mysql_select_db() vagy a mysql_query() fggvny nem sikeres, a $dbhiba vltozba betltjk a mysql_error() fggvny ltal visszaadott rtket s false rtkkel trnk vissza. Minden egyb esetben, vagyis ha a mvelet sikeres volt, true rtket adunk vissza. Miutn az adatbazis_bovit() lefutott, megvizsgljuk a visszatrsi rtket. Ha true, az adatok bekerltek az adatbzisba, gy zenetet kldhetnk a felhasznlnak. Egybknt ki kell rnunk a bngszbe a hibazenetet. Az adatbazis_bovit() fggvny ltal visszaadott $dbhiba vltoz most mr hasznos adatokat tartalmaz a hiba termszett illeten, gy ezt a szveget is belefoglaljuk a hibazenetbe. Ha a kezdeti if kifejezs nem tallja meg a $tartomany, $nem vagy $email valamelyikt, feltehetjk, hogy a felhasznl nem kldtt el semmilyen adatot, ezrt meghvunk egy msik ltalunk rt fggvnyt, az urlap_keszit()-et, amely egy HTML rlapot jelent meg a bngszben.

Automatikusan nvekv mez rtknek lekrdezse


Az elz pldkban gy adtuk hozz a sorokat a tblhoz, hogy nem foglalkoztunk az azonosito oszlop rtkvel, hiszen az adatok beszrsval az folyamatosan nvekedett, rtkre pedig nem volt szksgnk. Ha mgis szksgnk lenne r, egy SQL lekrdezssel brmikor lekrdezhetjk az adatbzisbl. De mi van akkor, ha azonnal szksgnk van az rtkre? Flsleges kln lekrdezst vgrehajtani, hiszen a PHP tartalmazza a mysql_insert_id() fggvnyt, amely a legutbbi INSERT kifejezs sorn belltott automatikusan nvelt mez rtkt adja vissza. A mysql_insert_id() fggvnynek szksg esetn tadhatunk

Adatbzisok kezelse MySQL egy kapcsolatazonost paramtert, amelyet elhagyva a fggvny alaprtelmezs szerint a legutoljra ltrejtt MySQL kapcsolat azonostjt hasznlja. gy ha meg akarjuk mondani a felhasznlnak, hogy milyen azonost alatt rgztettk az adatait, az adatok rgztse utn kzvetlenl hvjuk meg a mysql_insert_id() fggvnyt. $parancs = "INSERT INTO tartomanyok ( tartomany, nem, email ) VALUES ( '$tartomany', '$nem', '$email' )"; mysql_query( $parancs, $kapcsolat ); $azonosito = mysql_insert_id(); print "Ksznjk. Az n tranzakci-azonostja: $azonosito. Krjk jegyezze meg ezt a kdot.";

221

Adatok lekrdezse
Miutn adatainkat mr kpesek vagyunk az adatbzisban trolni, megismerkedhetnk azokkal a mdszerekkel, amelyek az adatok visszanyersre szolglnak. Mint bizonyra mr nyilvnval, a mysql_query() fggvny hasznlatval ki kell adnunk egy SELECT utastst. Az azonban mr korntsem ilyen egyszer, hogyan jutunk hozz a lekrdezs eredmnyhez. Nos, miutn vgrehajtottunk egy sikeres SELECT-et, a mysql_query() visszaad egy gynevezett eredmnyazonostt, melynek felhasznlsval elrhetjk az eredmnytblt s informcikat nyerhetnk rla.

12

Az eredmnytbla sorainak szma


A SELECT utasts eredmnyeknt kapott tbla sorainak szmt a mysql_num_rows() fggvny segtsgvel krdezhetjk le. A fggvny paramtere a krdses eredmny azonostja, visszatrsi rtke pedig a sorok szma a tblban. A 12.4. pldaprogramban lekrdezzk a tartomany tbla sszes sort s a mysql_num_rows() fggvnnyel megkapjuk a teljes tbla mrett.

12.4. program Sorok szma a SELECT utasts eredmnyben.


1: <html> 2: <head> 3: <title>12.4. program A mysql_num_rows() fggvny hasznlata</title> 4: </head> 5: <body> 6: <?php

222

12. ra

12.4. program (folytats)


7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: $felhasznalo = "jozsi"; $jelszo = "bubosvocsok"; $adatbazis = "pelda"; $kapcsolat = mysql_connect( "localhost", $felhasznalo, $jelszo ); if ( ! $kapcsolat ) die( "Nem lehet kapcsoldni a MySQL kiszolglhoz!" ); mysql_select_db( $adatbazis, $kapcsolat ) or die ( "Nem lehet megnyitni a $adatbazis adatbzist: ".mysql_error() ); $eredmeny = mysql_query( "SELECT * FROM tartomanyok" ); $sorok_szama = mysql_num_rows( $eredmeny ); print "Jelenleg $sorok_szama sor van a tblban<P>"; mysql_close( $kapcsolat ); ?> </body> </html>

A mysql_query() fggvny egy eredmnyazonostt ad vissza. Ezt tadjuk a mysql_num_rows() fggvnynek, amely megadja a sorok szmt.

Az eredmnytbla elrse
Miutn vgrehajtottuk a SELECT lekrdezst s az eredmnyazonostt troltuk, egy ciklus segtsgvel frhetnk hozz az eredmnytbla soraihoz. A PHP egy bels mutat segtsgvel tartja nyilvn, hogy melyik sort olvastuk utoljra. Ha kiolvasunk egy eredmnysort, a program automatikusan a kvetkezre ugrik. A mysql_fetch_row() fggvnnyel kiolvashatjuk a bels mutat ltal hivatkozott sort az eredmnytblbl. A fggvny paramtere egy eredmnyazonost, visszatrsi rtke pedig egy tmb, amely a sor sszes mezjt tartalmazza. Ha elrtk az eredmnykszlet vgt, a mysql_fetch_row() fggvny false rtkkel tr vissza. A 12.5. plda a teljes tartomany tblt megjelenti a bngszben.

Adatbzisok kezelse MySQL

223

12.5. program Tbla sszes sornak s oszlopnak megjelentse


1: <html> 2: <head> 3: <title>12.5. program Tbla sszes sornak s oszlopnak megjelentse</title> 4: </head> 5: <body> 6: <?php 7: $felhasznalo = "jozsi"; 8: $jelszo = "bubosvocsok"; 9: $adatbazis = "pelda"; 10: $kapcsolat = mysql_connect( "localhost", $felhasznalo, $jelszo ); 11: if ( ! $kapcsolat ) 12: die( "Nem lehet kapcsoldni a MySQL kiszolglhoz!" ); 13: mysql_select_db( $db, $kapcsolat ) 14: or die ( "Nem lehet megnyitni a $adatbazis adatbzist: ".mysql_error() ); 15: $eredmeny = mysql_query( "SELECT * FROM tartomanyok" ); 16: $sorok_szama = mysql_num_rows( $eredmeny ); 17: print "Jelenleg $sorok_szama sor van a tblban<P>"; 18: print "<table border=1>\n"; 19: while ( $egy_sor = mysql_fetch_row( $eredmeny ) ) 20: { 21: print "<tr>\n"; 22: foreach ( $egy_sor as $mezo ) 23: print "\t<td>$mezo</td>\n"; 24: print "</tr>\n"; 25: } 26: print "</table>\n"; 27: mysql_close( $kapcsolat ); 28: ?> 29: </body> 30: </html> Kapcsoldunk a kiszolglhoz s kivlasztjuk az adatbzist, majd a mysql_query() fggvnnyel egy SELECT lekrdezst kldnk az adatbzis kiszolgljhoz. Az eredmnyt az $eredmeny vltozban troljuk, amit az eredmnysorok szmnak lekrdezshez hasznlunk, ahogy korbban lttuk.

12

224

12. ra A while kifejezsben a mysql_fetch_row() fggvny visszatrsi rtkt az $egy_sor vltozba tltjk. Ne feledjk, hogy az rtkad kifejezs rtke megegyezik a jobb oldal rtkvel, ezrt a kirtkels sorn a kifejezs rtke mindig igaz lesz, amg a mysql_fetch_row() fggvny nem nulla rtkkel tr vissza. A ciklusmagban kiolvassuk az $egy_sor vltozban trolt elemeket s egy tblzat celliknt jelentjk meg azokat a bngszben. A mezket nv szerint is elrhetjk, mghozz ktfle mdon. A mysql_fetch_array() fggvny egy asszociatv tmbt ad vissza, ahol a kulcsok a mezk nevei. A kvetkez kdrszletben mdostottuk a 12.5. plda while ciklust, a mysql_fetch_array() fggvny felhasznlsval: print "<table border=1>\n"; while ( $egy_sor = mysql_fetch_array( $eredmeny ) ) { print "<tr>\n"; print "<td>".$egy_sor["email"]."</td><td>".$egy_sor["tartomany"]. "</td>\n"; print "</tr>\n"; } print "</table>\n"; A mysql_fetch_object() fggvny segtsgvel egy objektum tulajdonsgaiknt frhetnk hozz a mezkhz. A meznevek lesznek a tulajdonsgok nevei. A kvetkez kdrszletben ismt mdostottuk a krdses rszt, ezttal a mysql_fetch_object() fggvnyt hasznltuk. print "<table border=1>\n"; while ( $egy_sor = mysql_fetch_object( $eredmeny ) ) { print "<tr>\n"; print "<td>".$egy_sor->email."</td><td>".$egy_sor-> tartomany."</td>\n"; print "</tr>\n"; } print "</table>\n"; A mysql_fetch_array() s mysql_fetch_object() fggvnyek lehetv teszik szmunkra, hogy a sorbl kinyert informcikat szrjk s vgrehajtsuk sem kerl sokkal tbb idbe, mint a mysql_fetch_row() fggvny.

Adatbzisok kezelse MySQL

225

Adatok frisstse
Az adatokat az UPDATE utastssal frissthetjk, amelyet termszetesen a mysql_query() fggvnnyel kell tadnunk az adatbzis kiszolgljnak. Itt is igazak a korbban elmondottak, azaz egy sikeres UPDATE utasts nem felttlenl jelent vltozst az adatokban. A megvltozott sorok szmt a mysql_affected_rows() fggvnnyel krdezhetjk le, amelynek szksg szerint egy kapcsolatazonostt kell tadnunk. Ennek hinyban a fggvny mint azt mr megszokhattuk a legfrissebb kapcsolatra rtelmezi a mveletet. A mysql_affected_rows() fggvnyt brmely olyan SQL lekrdezs utn hasznlhatjuk, amely felteheten mdostott egy vagy tbb sort az adattblban. A 12.6. plda egy olyan programot tartalmaz, amely lehetv teszi az adatbzis karbantartja szmra, hogy brmelyik sor tartomany mezjt megvltoztassa.

12.6. program Sorok frisstse az adatbzisban


1: <html> 2: <head> 3: <title>12.6. program Sorok frisstse az adatbzisban 4: </title> 5: </head> 6: <body> 7: <?php 8: $felhasznalo = "jozsi"; 9: $jelszo = "bubosvocsok"; 10: $adatbazis = "pelda"; 11: $kapcsolat = mysql_connect( "localhost", $felhasznalo, $jelszo ); 12: if ( ! $kapcsolat ) 13: die( "Nem lehet kapcsoldni a MySQL kiszolglhoz! ); 14: mysql_select_db( $adatbazis, $kapcsolat ) 15: or die ( "Nem lehet megnyitni a $adatbazis adatbzist: ".mysql_error() ); 16: if ( isset( $tartomany ) && isset( $azonosito ) ) 17: { 18: $parancs = "UPDATE tartomanyok SET tartomany = '$tartomany' WHERE azonosito=$azonosito"; 19: $eredmeny = mysql_query( $parancs );

12

226

12. ra

12.6. program (folytats)


20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: if ( ! $eredmeny ) die ("Nem sikerlt a mdosts: " .mysql_error()); print "<h1>A tbla mdostva, ". mysql_affected_rows() . " sor vltozott</h1><p>"; } ?> <form action="<? print $PHP_SELF ?>" method="POST"> <select name="azonosito"> <? $eredmeny = mysql_query( "SELECT tartomany, azonosito FROM tartomanyok" ); while( $egy_sor = mysql_fetch_object( $eredmeny ) ) { print "<option value=\"$egy_sor->azonosito\""; if ( isset($azonosito) && $azonosito == $egy_sor->azonosito ) print " selected"; print "> $egy_sor->tartomany\n"; } mysql_close( $kapcsolat ); ?> </select> <input type="text" name="tartomany"> <input type="submit" value="Frissts"> </form> </body> </html>

A mvelet a szoksos mdon indul: kapcsoldunk az adatbzis kiszolgljhoz s kivlasztjuk az adatbzist. Ezek utn megvizsgljuk a $tartomany s az $azonosito vltozk megltt. Ha mindent rendben tallunk, sszelltjuk az SQL utastst, amely a $tartomany vltoz rtknek megfelelen frissti azt a sort, ahol az azonosito mez tartalma megegyezik az $azonosito vltoz rtkvel. Ha nem ltez azonosito rtkre hivatkozunk vagy a krdses sorban a $tartomany vltoz rtke megegyezik a tartomany mez tartalmval, nem kapunk hibazenetet, de a mysql_affected_rows() fggvny visszatrsi rtke 0 lesz. A mdostott sorok szmt kirjuk a bngszbe.

Adatbzisok kezelse MySQL A karbantart szmra ksztnk egy HTML rlapot, amelyen keresztl elvgezheti a vltoztatsokat. Ehhez ismt a mysql_query() fggvnyt kell hasznlnunk: lekrdezzk az azonosito s tartomany oszlopok sszes elemt s beillesztjk azokat egy HTML SELECT listba. A karbantart ezltal egy lenyl menbl vlaszthatja ki, melyik bejegyzst kvnja mdostani. Ha a karbantart mr elkldte egyszer az rlapot, akkor az utoljra hivatkozott azonosito rtk mell a SELECTED mdostt is kitesszk, gy a mdostsok azonnal ltszdni fognak a menben.

227

Informcik az adatbzisokrl
Mindezidig egyetlen adatbzisra sszpontostottunk, megtanulva, hogyan lehet adatokkal feltlteni egy tblt s az adatokat lekrdezni. A PHP azonban szmos olyan eszkzzel szolgl, amelyek segtsgvel megllapthatjuk, hny adatbzis hozzfrhet az adott kapcsolaton keresztl s milyen ezek szerkezete.

Az elrhet adatbzisok kiratsa


A mysql_list_dbs() fggvny segtsgvel listt krhetnk az sszes adatbzisrl, melyek az adott kapcsolaton keresztl hozzfrhetk. A fggvny paramtere szksg szerint egy kapcsolatazonost, visszatrsi rtke pedig egy eredmnyazonost. Az adatbzisok neveit a mysql_tablename() fggvnnyel krdezhetjk le, amelynek paramtere ez az eredmnyazonost s az adatbzis sorszma, visszatrsi rtke pedig az adatbzis neve. Az adatbzisok sorszmozsa 0-val kezddik. Az sszes adatbzis szmt a mysql_list_dbs() fggvny utn meghvott mysql_num_rows() fggvny adja meg.

12

12.7. program Adott kapcsolaton keresztl elrhet adatbzisok


1: <html> 2: <head> 3: <title>12.7. program Adott kapcsolaton keresztl elrhet adatbzisok 4: </title> 5: </head> 6: <body> 7: <?php 8: $felhasznalo = "jozsi"; 9: $jelszo = "bubosvocsok"; 10: $kapcsolat = mysql_connect( "localhost", $felhasznalo, $jelszo );

228

12. ra

12.7. program (folytats)


11: if ( ! $kapcsolat ) 12: die( "Nem lehet kapcsoldni a MySQL kiszolglhoz!" ); 13: $adatbazis_lista = mysql_list_dbs( $kapcsolat ); 14: $szam = mysql_num_rows( $adatbazis_lista ); 15: for( $x = 0; $x < $szam; $x++ ) 16: print mysql_tablename( $adatbazis_lista, $x )."<br>"; 17: mysql_close( $kapcsolat ); 18: ?> 19: </body> 20: </html>

A mysql_list_dbs() fggvny visszaad egy eredmnyazonostt, amelyet paramterknt tadunk a mysql_num_rows() fggvnynek. Az gy megkapott adatbzisok szmt a $szam vltozba tltjk s felhasznljuk a for ciklusban. Az $x indexet minden lpsben eggyel nveljk, 0-tl a tallt adatbzisok szmig, majd az eredmnyazonostval egytt tadjuk a mysql_tablename() fggvnynek az adatbzis nevnek lekrdezshez. A 12.1 brn a 12.7 program eredmnye lthat egy bngszablakban.

12.1. bra
Az elrhet adatbzisok listja

Adatbzisok kezelse MySQL A mysql_list_dbs() fggvny ltal visszaadott eredmnyazonostt a mysql_query() eredmnyhez hasonlan is felhasznlhatnnk, vagyis a tnyleges neveket a mysql_fetch_row() fggvnnyel is lekrdezhetnnk. Ekkor eredmnyl egy tmbt kapnnk, melynek els eleme tartalmazn az adatbzis nevt.

229

Adatbzistblk listzsa
A mysql_list_tables() fggvnnyel egy adott adatbzis tblinak nevt soroltathatjuk fel. A fggvny paramterei az adatbzis neve s szksg szerint a kapcsolat azonostja. A visszatrsi rtk egy eredmnyazonost, ha az adatbzis ltezik s jogunk van hozzfrni. Az eredmnyazonostt mysql_tablename() vagy mysql_fetch_row() hvsokhoz hasznlhatjuk fel, a fent ltott mdon. A kvetkez kdrszlet a mysql_list_tables() fggvny segtsgvel az adatbzis sszes tbljt kirja. $eredmeny = mysql_list_tables( "pelda", $kapcsolat ); while ( $tabla_sor = mysql_fetch_row( $eredmeny ) ) print $tabla_sor[0]."<BR>\n";

12

Informcik a mezkrl
A SELECT lekrdezs utn az eredmnytbla mezinek szmt a mysql_num_fields() fggvnnyel kaphatjuk meg. A fggvny paramtere egy eredmnyazonost, visszatrsi rtke pedig egy egsz szm, amely a mezk szmt adja meg. $eredmeny = mysql_query( "SELECT * from tartomanyok" ); $mezok_szama = mysql_num_fields( $eredmeny ); A mezkhz sorszmokat rendelnk, a szmozs 0-val kezddik. A sorszm s az eredmnyazonost alapjn szmos informcit lekrdezhetnk a mezrl, belertve a nevt, tpust, legnagyobb hosszt s egyb jellemzit is. A mez nevnek lekrdezsre a mysql_field_name() fggvny szolgl. $eredmeny = mysql_query( "SELECT * from tartomanyok" ); $mezok_szama = mysql_num_fields( $eredmeny ); for ( $x=0; $x<$mezok_szama; $x++ ) mysql_field_name( $eredmeny, $x ) . "<br>\n";

230

12. ra A mez legnagyobb hosszt a mysql_field_len() fggvnnyel kaphatjuk meg. $eredmeny = mysql_query( "SELECT * from tartomanyok" ); $mezok_szama = mysql_num_fields( $eredmeny ); for ( $x=0; $x<$mezok_szama; $x++ ) mysql_field_len( $eredmeny, $x ) . "<BR>\n"; A mez egyb jellemzit a mysql_field_flags() fggvnnyel olvashatjuk ki: $eredmeny = mysql_query( "SELECT * from tartomanyok" ); $mezok_szama = mysql_num_fields( $eredmeny ); for ( $x=0; $x<$mezok_szama; $x++ ) mysql_field_flags( $eredmeny, $x ) . "<BR>\n"; Lehetsgnk van mg a mez tpusnak megllaptsra, a mysql_field_type() fggvnnyel: $eredmeny = mysql_query( "SELECT * from tartomanyok" ); $mezok_szama = mysql_num_fields( $eredmeny ); for ( $x=0; $x<$mezok_szama; $x++ ) mysql_field_type( $eredmeny, $x ) . "<BR>\n";

Az adatbzis szerkezete sszell a kp


A 12.8 plda egyesti a fenti eljrsokat s megjelent minden elrhet adatbzist, tblt s mezt.

12.8 program Minden adatbzis, tbla s mez megjelentse


1: <html> 2: <head> 3: <title>12.8. program Minden adatbzis, tbla s mez megjelentse</title> 4: </head> 5: <body> 6: <?php 7: $felhasznalo = "root"; 8: $jelszo = "titkos"; 9: $kapcsolat = mysql_connect( "localhost", $felhasznalo, $jelszo );

Adatbzisok kezelse MySQL

231

12.8 program (folytats)


10: if ( ! $kapcsolat ) 11: die( "Nem lehet kapcsoldni a MySQL kiszolglhoz!" ); 12: $adatbazis_lista = mysql_list_dbs( $kapcsolat ); 13: while ( $adatbazisok = mysql_fetch_row ( $adatbazis_lista ) ) 14: { 15: print "<b>".$adatbazisok[0]."</b>\n"; 16: if ( !@mysql_select_db( $adatbazisok[0], $kapcsolat ) ) 17: { 18: print "<dl><dd>Nem lehet kivlasztani " . mysql_error() ." </dl>"; 19: continue; 20: } 21: $tablak = mysql_list_tables( $adatbazisok[0], $kapcsolat ); 22: print "\t<dl><dd>\n"; 23: while ( $tabla_sor = mysql_fetch_row( $tablak ) ) 24: { 25: print "\t<b>$tabla_sor[0]</b>\n"; 26: $eredmeny = mysql_query( "SELECT * from " .$tabla_sor[0] ); 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: $mezok_szama = mysql_num_fields( $eredmeny ); print "\t\t<dl><dd>\n"; for ( $x=0; $x<$mezok_szama; $x++ ) { print "\t\t<i>"; print mysql_field_type( $eredmeny, $x ); print "</i> <i>"; print mysql_field_len( $eredmeny, $x ); print "</i> <b>"; print mysql_field_name( $eredmeny, $x ); print "</b> <i>"; print mysql_field_flags( $eredmeny, $x ); print "</i><br>\n"; } print "\t\t</dl>\n"; }

12

232

12. ra

12.8 program (folytats)


43: 44: 45: 46: 47: 48: print "\t</dl>\n"; } mysql_close( $kapcsolat ); ?> </body> </html>

Elszr is a szoksos mdon a MySQL kiszolglhoz kapcsoldunk, majd meghvjuk a mysql_list_dbs() fggvnyt. A kapott eredmnyazonostt tadjuk a mysql_fetch_row() fggvnynek s az $adatbazisok tmb els elembe betltjk az aktulis adatbzis nevt. Ezutn megprbljuk kivlasztani az adatbzist a mysql_select_db() fggvnnyel. Ha nincs hozzfrsi jogunk, akkor megjelentjk a hibazenetet a bngszablakban, majd a continue utastssal tovbblpnk a kvetkez adatbzisra. Ha ki tudjuk vlasztani az adatbzist, a mveletet a tblanevek kirsval folytatjuk. Az adatbzis nevt tadjuk a mysql_list_tables() fggvnynek, troljuk az j eredmnyazonostt, majd a mysql_fetch_row() fggvnnyel kiolvassuk a tblk neveit. Minden tbln a kvetkez mveletsort hajtjuk vgre: kirjuk a tbla nevt, majd sszelltunk egy SQL utastst, amely az sszes oszlopot lekrdezi az adott tblban. A mysql_query() fggvnnyel vgrehajtjuk a lekrdezst, majd az eredmnyazonost alapjn a mysql_num_fields() fggvnnyel meghatrozzuk a mezk szmt. A for ciklusban minden mezn elvgezzk a kvetkez mveletsort: belltjuk az $x vltozt, hogy az aktulis mez sorszmt tartalmazza (ez kezdetben 0). Ezutn a sorszm ismeretben meghvjuk az elz rszben trgyalt sszes ellenrz fggvnyt, eredmnyket pedig tlthat formban, tblzatba rendezve elkldjk a bngsznek. Ezeket a mveleteket minden elrhet adatbzison elvgezzk. A program egy ttekinthet szerkezeti vzlatot jelent meg a bngszablakban, amely az adott kapcsolaton keresztl elrhet sszes adatbzist, adattblt s mezt tartalmazza. A 12.2. bra a program kimenett mutatja.

Adatbzisok kezelse MySQL

233

12.2. bra
Az sszes elrhet adatbzis, tbla s mez listja

sszefoglals
Ebben az rban a MySQL adatbziskezels alapjait tanultuk meg: az adatok trolst s visszanyerst. Megtanultuk, hogyan ptsk fel a kapcsolatot a MySQL kiszolglval a mysql_connect() s mysql_pconnect() fggvnyek segtsgvel. Az adatbzist a mysql_select_db() fggvnnyel vlasztottuk ki. Ha a kivlaszts nem sikerlt, lekrdeztk a hibt a mysql_error() fggvnnyel. SQL utastsokat adtunk ki a mysql_query() fggvny segtsgvel s a fggvny ltal visszaadott eredmnyazonost segtsgvel elrtk az adatokat vagy megtudtuk a mdostott sorok szmt. A PHP MySQL fggvnyeinek segtsgvel kirattuk az elrhet adatbzisokat, tblkat s mezket, s az egyes mezkrl is bvebb informcikat szereztnk.

12

234

12. ra

Krdsek s vlaszok
Ez az ra szigoran a MySQL-re vonatkozik. Hogyan ltethetjk t ezeket a fogalmakat ms adatbzissal mkd rendszerekre? Az mSQL-kezel fggvnyek pldul szinte teljesen megegyeznek a MySQL fggvnyekkel, de ms SQL kiszolglknak is megvannak a sajt PHP fggvnyeik. SQL utastsokat minden adatbziskiszolglnak kldhetnk. Ha szabvnyos ANSI SQL-lel dolgozunk, nem lesz klnsebb problmnk az adatbziskiszolglk kztti tllskor. Hogyan rhatunk olyan kdot, amelyet knny tltetni egy msik adatbzis kiszolgl krnyezetbe? Gyakran j tlet az adatbzis-lekrdez fggvnyeket egy egyszer osztlyba vagy knyvtrba csoportostani. gy ha fel kell kszteni a kdot egy msik adatbziskezelvel val egyttmkdsre, a kdnak csak kis rszt kell trni.

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Hogyan kell csatlakozni a MySQL adatbziskiszolglhoz? 2. Melyik fggvny szolgl az adatbzis kivlasztsra? 3. Melyik fggvnnyel kldhetnk SQL utastst a kiszolglnak? 4. Mit csinl a mysql_insert_id() fggvny? 5. Tegyk fel, hogy kldtnk egy SELECT lekrdezst a MySQL-nek. Nevezznk meg hrom fggvnyt, amelyekkel hozzfrhetnk az eredmnyhez. 6. Tegyk fel, hogy kldtnk egy UPDATE lekrdezst a MySQL-nek. Melyik fggvnnyel llapthatjuk meg, hny sort rintett a mdosts? 7. Melyik fggvnyt kellene hasznlnunk, ha az adatbziskapcsolaton keresztl elrhet adatbzisok nevt szeretnnk megtudni? 8. Melyik fggvnnyel krdezhetjk le az adatbzisban tallhat tblk neveit?

Adatbzisok kezelse MySQL

235

Feladatok
1. Hozzunk ltre egy adattblt hrom mezvel: email (legfeljebb 70 karakter), uzenet (legfeljebb 250 karakter) s datum (a UNIX idblyegzt tartalmaz egsz szm). Tegyk lehetv a felhasznlknak, hogy feltltsk az adatbzist. 2. Ksztsnk programot, amely megjelenti az 1. pontban elksztett tbla tartalmt.

12

13. RA
Kapcsolat a klvilggal
Ezen az rn olyan fggvnyekkel ismerkednk meg, amelyek a klvilggal val rintkezst teszik lehetv. Az ra sorn a kvetkezkrl tanulunk: Krnyezeti vltozk rszletesebben A HTTP kapcsolat felptse Tvoli kiszolgln lev dokumentumok elrse Sajt HTTP kapcsolat ltrehozsa Kapcsolds ms hlzati szolgltatsokhoz Levlklds programbl

238

13. ra

Krnyezeti vltozk
Mr tallkoztunk nhny krnyezeti vltozval; ezeket a PHP a kiszolgl segtsgvel bocstotta rendelkezsnkre. Nhny ilyen vltozval tbb dolgot is megtudhatunk weboldalunk ltogatirl, arra azonban gondoljunk, hogy lehet, hogy ezek a vltozk a mi rendszernkn nem elrhetk, esetleg a kiszolglprogram nem tmogatja azokat, gy hasznlatuk eltt rdemes ezt ellenrizni. A 13.1. tblzat ezek kzl a vltozk kzl mutat be nhnyat.

13.1. tblzat Nhny hasznos krnyezeti vltoz


Vltoz $HTTP_REFERER
$HTTP_USER_AGENT $REMOTE_ADDR $REMOTE_HOST $QUERY_STRING

Lers A programot meghv webhely cme.


Informci a ltogat bngszjrl s rendszerrl. A ltogat IP cme. A ltogat szmtgpnek neve. Az a (kdolt) karakterlnc, amely a webcmet kiegszti (formtuma kulcs=ertek&masikkulcs=masikertek). E kulcsok s rtkek elrhetv kell, hogy vljanak programunk rszre a megfelel globlis vltozkban is. Az esetleg a webcmhez illesztett tovbbi informci.

$PATH_INFO

A 13.1. pldaprogram ezen vltozk rtkt jelenti meg a bngszben.

13.1. program Nhny krnyezeti vltoz felsorolsa


1: <html> 2: <head> 3: <title>13.1. program Nhny krnyezeti vltoz felsorolsa</title> 4: </head> 5: <body> 6: <?php 7: $korny_valtozok = array( "HTTP_REFERER", "HTTP_USER_AGENT", "REMOTE_ADDR", "REMOTE_HOST", "QUERY_STRING", "PATH_INFO" );

Kapcsolat a klvilggal

239

13.1. program (folytats)


8: 9: 10: 11: 12: 13: 14: 15: foreach ( $korny_valtozok as $valtozo ) { if ( isset( $$valtozo ) ) print "$valtozo: ${$valtozo}<br>"; } ?> </body> </html>

Figyeljk meg, hogyan alaktottuk a szvegknt trolt vltozneveket valdi vltozkk. Ezt a mdszert a negyedik rn tanultuk. A 13.1. brn a 13.1. kd kimenett lthatjuk. Az brn lthat adatokat gy kaptuk, hogy a programot egy msik oldal hivatkozsn keresztl hvtuk meg. A programot meghv hivatkozs gy nzett ki: <A HREF='13.1.program.php/tovabbi/utvonal?nev=ertek'>gyernk</A> Amint lthatjuk, a hivatkozs relatv tvonalat hasznl a 13.1.program.php meghvsra.

13.1. bra
Nhny krnyezeti vltoz kiratsa a bngszben

13

Az elrsi t azon rsze, mely programunk nevt kveti, (jelen esetben a /tovabbi/utvonal) a $PATH_INFO vltozban ll majd rendelkezsnkre.

240

13. ra

A lekrdezs szvegt nem dinamikusan illesztettk a hivatkozsba (nev=ertek), de ettl fggetlenl az a $QUERY_STRING vltozban lesz elrhet. A lekrdez karakterlncokkal legtbbszr akkor tallkozunk, ha egy GET metdust hasznl rlap hvja meg a programot, de magunk is elllthatunk ilyet, hogy segtsgvel adatokat tovbbthassunk laprl lapra. A lekrdez karakterlnc nvrtk prokbl ll, melyeket S jel (&) vlaszt el egymstl. Az adatprok URL kdols formban kerlnek a webcmbe, hogy a bennk szerepl, a webcmekben nem megengedett vagy mst jelent karakterek ne okozzanak hibt. Ezt gy oldottk meg, hogy a problms karaktereket hexadecimlis megfeleljkre cserlik. Br a teljes karakterlnc elrhet a $QUERY_STRING krnyezeti vltozban, nagyon ritkn lehet szksgnk r, pontosan a kdolt mivolta miatt. De azrt is mellzk a hasznlatt, mert az sszes nvrtk pr rendelkezsnkre ll globlis vltozk formjban is (jelen esetben pldul ltrejn a $nev vltoz s az rtke ertek lesz). A $HTTP_REFERER vltoz rtke akkor lehet hasznos szmunkra, ha nyomon szeretnnk kvetni, hogy programunkat mely hivatkozson keresztl rtk el. Nagy krltekintssel kell eljrnunk azonban, mert ez s tulajdonkppen brmely msik krnyezeti vltoz is nagyon knnyen meghamisthat. (Az ra folyamn azt is megtudhatjuk, hogyan.) A nevet sajnlatos mdon a kezdetekkor egy fejleszt elrta (helyesen HTTP_REFERRER-nek kellene neveznnk), mdostsa a korbbi vltozatokkal val sszeegyeztethetsg megrzse rdekben nem trtnt meg. Ezenkvl nem minden bngsz adja meg ezt az informcit, gy hasznlatt clszer elkerlnnk. A $HTTP_USER_AGENT vltoz sztbontsval rjhetnk, milyen opercis rendszert, illetve bngszt hasznl a ltogat, de tudnunk kell, hogy ezek az adatok is hamisthatk. A vltozban elrhet rtket akkor hasznlhatjuk, ha a bngsz tpustl vagy a vltozattl fggen ms s ms HTML kdot vagy JavaScriptet szeretnnk elkldeni a ltogatnak. A tizenhetedik s tizennyolcadik rban mindent megtanulunk arrl, hogyan nyerhetjk ki a szmunkra fontos adatokat ebbl a karakterlncbl. A $REMOTE_ADDR vltoz a ltogat IP cmt tartalmazza, gy a webhely ltogatinak azonostsra hasznlhat. Ne feledjk azonban, hogy a felhasznlk IP cme tbbnyire nem lland, hiszen az internetszolgltatk ltalban dinamikusan osztjk ki felhasznliknak a cmeket, gy az minden csatlakozs sorn ms lehet, teht ugyanaz az IP cm klnbz ltogatkat jelenthet s a klnbz IP cmek is takarhatnak egyetlen felhasznlt. A $REMOTE_HOST vltoz nem biztos, hogy hozzfrhet; ez a kiszolgl belltsaitl fgg. Ha ltezik, a felhasznl szmtgpnek nevt tallhatjuk benne. A vltoz meglthez a kiszolglnak az IP cm alapjn minden krskor le kell krdeznie a gp nevt, ami idignyes feladat, gy a kiszolgl ezen kpessgt

Kapcsolat a klvilggal a hatkonysg kedvrt gyakran letiltjk. Ha nem ltezne ilyen vltoz, az informcihoz a $REMOTE_ADDR segtsgvel juthatunk hozz; ksbb azt is ltjuk majd, hogyan.

241

A HTTP gyfl-kiszolgl kapcsolat rvid ismertetse


A kiszolgl s az gyfl kzti adatforgalom rszletes ismertetse tlmutat knyvnk keretein, tbbek kztt azrt, mert a PHP ezen rszletek szakszer kezelsrl is gondoskodik helyettnk. A folyamatot azonban nem hibaval alapjaiban megismerni, mert szksgnk lehet r, ha olyan programot szeretnnk rni, amely weboldalakat tlt le vagy webcmek llapott ellenrzi. JDONSG A HTTP jelentse hiperszveg-tviteli protokoll. Nem ms, mint szablyok halmaza, melyek elrjk, hogy az gyfl milyen krsekkel fordulhat a kiszolglhoz s az milyen vlaszokat kell, hogy adjon. Mind az gyfl, mind a kiszolgl informcit szolgltat magrl s a kldtt adatokrl. Ezen informcik legtbbjt a PHP-bl krnyezeti vltozkon keresztl rhetjk el.

A krs
Az gyfl szigor szablyok szerint krhet adatokat a kiszolgltl. A krs legfeljebb hrom rszbl llhat: A krs sora Fejlc Trzs A legfontosabb a krs sora. Itt hatrozzuk meg a krs fajtjt (GET, HEAD vagy POST), a krt dokumentum cmt s az tviteli protokoll vltozatszmt (HTTP/1.0 vagy HTTP/1.1). Egy jellemz krs a kvetkezkppen nz ki: GET /egy_dokumentum.html HTTP/1.0 Ekkor az gyfl egy GET krst kezdemnyez. Ms szval lekr egy dokumentumot, de adatokat nem kld. (Valjban kisebb mennyisg adat kldsre a GET krs alkalmazsakor is van lehetsg, ha azt lekrdez karakterlnc formjban hozzrjuk az URL vghez.) A HEAD mdszer akkor alkalmazand, ha nem magra a dokumentumra, csak annak tulajdonsgaira vagyunk kvncsiak, vgl a POST krs arra szolgl, hogy adatokat kldjnk az gyfltl a kiszolglnak. Ez legtbbszr HTML rlapok esetben hasznlatos.

13

242

13. ra A kifogstalan GET krshez egyetlen krsor elkldse is elegend. A krs vgt gy tudathatjuk a kiszolglval, hogy egy res sort kldnk neki. A legtbb gyfl (ltalban bngszprogram) a krsoron kvl kld egy fejlc rszt is, amely nvrtk prokbl ll. Az oldal lekrsvel rkezett fejlcek legtbbjhez krnyezeti vltozk formjban hozz is frhetnk programunkbl. Az gyfl fejlcnek minden sora egy kettsponttal elvlasztott nvbl s rtkbl ll. A 13.2 tblzat nhny lehetsges fejlc-nevet sorol fel.

13.2 tblzat Nhny fejlc-kulcs


Nv Accept
Accept-Encoding Accept-Charset Accept-Language Host

Lers Az gyfl ltal kezelhet dokumentumtpusok listja.


Az gyfl szmra elfogadhat kdolsi s tmrtsi formtumok listja. Az gyfl ltal elnyben rszestett nemzetkzi karakterkszlet. Az gyfl ltal elnyben rszestett nyelv (a magyar nyelv esetben hu). Az gyfl krse ltal megcmzett gp neve. Egyes kiszolglk csak ltszlagos (virtulis) kiszolglk, a berkez krseket nem nll szmtgp kezeli. Ilyen esetekben komoly jelentsge van ennek az adatnak. Azon dokumentum cme, melynek egyik hivatkozsa alapjn a krs ltrejtt. Az gyflprogram tpusa s vltozatszma.

Referer User-Agent

A GET s a HEAD eljrsoknl a krst a fejlc s az utna kvetkez res sor zrja, a POST tpusnl azonban az res sort az zenet trzse kveti. A trzs tartalmazza a kiszolglnak szl sszes adatot, jobbra URL kdols nvrtk prok, a lekrdez karakterlncokhoz hasonlan. A 13.2 pldban egy jellemz, mindennapos krst mutatunk be, melyet egy Netscape 4.7 kezdemnyezett.

Kapcsolat a klvilggal

243

13.2. plda Jellemz Netscape-krs


GET / HTTP/1.0 Referer: http://www.linuxvilag.hu/index.html Connection: Keep-Alive User-Agent: Mozilla/4.7 [en] (X11; I; Linux 2.2.13 i686) Host: www.kiskapu.hu Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */* Accept-Encoding: gzip Accept-Language: en Accept-Charset: iso-8859-1,*,utf-8

A vlasz
Miutn a kiszolgl fogadta az gyfl krst, vlaszt kld. A vlasz ltalban a kvetkez hrom rszbl tevdik ssze: llapot Fejlc Trzs Amint ltjuk, a krs s a vlasz szerkezete igen hasonl. A fejlc bizonyos sorai tulajdonkppen gyfl s kiszolgl ltal kldve egyarnt meglljk helyket, nevezetesen azok, amelyek a trzsre vonatkoznak. Az llapot sor a kiszolgl ltal hasznlt protokollt (HTTP/1.0 vagy HTTP/1.1) adja meg, illetve egy vlaszkdot s egy azt magyarz szveget. Szmos vlaszkd ltezik, mindegyik a krs sikeressgrl vagy sikertelensgrl ad informcit. A 13.3-as tblzat a leggyakoribb kdok jelentst tartalmazza.

13

244

13. ra

13.3 tblzat Nhny vlaszkd


Kd 200
301 302 404 500

Szveg OK

Lers A krs sikeres volt s a trzsben megtallhat a vlasz.

Moved Permanently A krt adat nem tallhat a kiszolgln, de a fejlcben megtallhat annak j helye. Moved Temporarily A krt adatot ideiglenesen thelyeztk, de a fejlc elrulja, hogy hov. Not Found Internal Server Error A krt adat nem tallhat a megadott cmen. A kiszolgl vagy egy CGI program komoly problmba tkztt a krs teljestse sorn.

Ennek megfelelen a jellegzetes vlaszsor a kvetkezkppen fest: HTTP/1.1 200 OK A fejlc rsz a vlaszfejlc soraibl ll, melyek formtuma a krsfejlc soraihoz hasonl. A 13.4 tblzat a legsrbben alkalmazott fejlcelemekbl szemezget.

13.4 tblzat A kiszolgl vlaszfejlcnek leghtkznapibb elemei


Nv Date
Server Content-Type Content-Length Location

Lers Az aktulis dtum


A kiszolgl neve s vltozatszma A trzsben szerepl adat MIME tpusa A trzs mrete bjtban Egy alternatv dokumentum teljes elrsi tja (kiszolgloldali tirnyts esetn)

Miutn a kiszolgl elkldte a fejlcet s a szoksos res sort, elkldi a trzset (a krsben tulajdonkppen ignyelt dokumentumot). A 13.3 plda egy jellemz vlaszt mutat be.

Kapcsolat a klvilggal

245

13.3. plda A kiszolgl vlasza


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: HTTP/1.1 200 OK Date: Sun, 30 Jan 2000 18:02:20 GMT Server: Apache/1.3.9 (Unix) Connection: close Content-Type: text/html <html> <head> <title>13.3. lista A kiszolgl vlasza</title> </head> <body> dvzlet! </body> </html>

Dokumentum letltse tvoli cmrl


Br a PHP kiszolgloldali nyelv, esetenknt gyflknt viselkedve adatokat krhet egy tvoli cmrl s a kapott adatokat programunk rendelkezsre bocsthatja. Ha mr jrtasak vagyunk a kiszolgln lv fjlok kezelsben, nem okozhat komoly gondot a tvoli helyen lv adatok lekrse sem. Az a helyzet ugyanis, hogy a kett kztt formailag semmi klnbsg nincs. Az fopen()-nel ugyangy megnyithatunk egy webcmet, ahogy azt egy fjl esetben tennnk. A 13.4. pldaprogram egy tvoli kiszolglhoz kapcsoldva adatokat kr le, majd megjelenti azokat a bngszben.

13

13.4. program Weboldal letltse s megjelentse az fopen()-nel


1: <html> 2: <head> 3: <title>13.4. program Weboldal letltse s megjelentse az fopen()-nel</title> 4: </head> 5: <body> 6: <?php 7: $weboldal = "http://www.php.net/index.php"; 8: $fajlmutato = fopen( $weboldal, "r" ) or die("A $weboldal nem nyithat meg");

246

13. ra

13.4. program (folytats)


9: while ( ! feof( $fajlmutato )) 10: 11: ?> 12: </body> 13: </html> Ha megnzzk ezt az oldalt, akkor a PHP honlapjt kell ltnunk, azzal a kis klnbsggel, hogy a kpek nem jelennek meg. Ennek oka, hogy az oldalon tallhat IMG hivatkozsok ltalban relatvak, gy az oldal megjelentsekor a bngsz a mi kiszolglnkon keresi azokat. Ezen gy segthetnk, hogy a HEAD HTML elemet az albbi sorral bvtjk: <base href="http://www.php.net/index.php"> Az esetek tbbsgben azonban nem a letlttt adatok megjelentse, hanem a feldolgozs a feladat. Az fopen() egy fjlmutatval tr vissza, ha sikerlt felptenie a kapcsolatot s false (hamis) rtkkel, ha nem jtt ltre a kapcsolat vagy nem tallta a fjlt. A kapott fjlmutat a tovbbiakban ugyangy hasznlhat az olvasshoz, mint a helyi fjlok kezelse esetben. A PHP a tvoli kiszolglnak gy mutatkozik be, mint egy PHP gyfl. A szerz rendszern a PHP a kvetkez krst kldi el: GET /index.php HTTP/1.0 Host: www.php.net User-Agent: PHP/4.0.3 Ez a megkzelts elg egyszer, gy az esetek tbbsgben elegend, ha ezt alkalmazzuk weblapok letltshez. Szksgnk lehet viszont ms hlzati szolgltatsokhoz val kapcsoldsra, vagy pp csak tbbet szeretnnk megtudni a dokumentumrl, elemezve annak fejlct. Ekkor mr ms eszkzkhz kell folyamodnunk. Hogy ezt hogyan tehetjk meg? Nos, az ra folyamn lesz mg errl sz. print fgets( $fajlmutato, 1024 );

talakts IP cmek s gpnevek kztt


Ha kiszolglnk nem is bocstja rendelkezsnkre a ltogat gpnek nevt a $REMOTE_HOST vltozban, a ltogat cmhez minden bizonnyal hozzjuthatunk a $REMOTE_ADDR vltozbl. A vltozra alkalmazva a gethostbyaddr() fggvnyt megtudhatjuk a ltogat gpnek nevt. A fggvny egy IP cmet brzo-

Kapcsolat a klvilggal l karakterlncot vr paramterknt s az annak megfelel gpnvvel tr vissza. Ha hiba lp fel a nv ellltsa sorn, kimenetknt a beadott IP cmet kapjuk meg vltozatlanul. A 13.5-s program a $REMOTE_HOST hinya esetn a gethostbyaddr() fggvny segtsgvel ellltja a felhasznl gpnek nevt.

247

13.5. program Gpnv lekrdezse a gethostbyaddr() segdletvel


1: <html> 2: <head> 3: <title>13.5. program Gpnv lekrdezse a gethostbyaddr() segdletvel</title> 4: </head> 5: <body> 6: <?php 7: if ( isset( $REMOTE_HOST ) ) 8: print "dvzljk $REMOTE_HOST<br>"; 9: elseif ( isset ( $REMOTE_ADDR ) ) 10: print " dvzljk ".gethostbyaddr( $REMOTE_ADDR )."<br>"; 11: else 12: print " dvzljk, akrki is n.<br>"; 13: ?> 14: </body> 15: </html>

13

Ha a $REMOTE_HOST vltoz ltezik, egyszeren megjelentjk annak rtkt. Ha nem ltezik, megprbljuk a $REMOTE_ADDR alapjn a gethostbyaddr() fggvnnyel ellltani a gpnevet. Ha minden ksrletnk csdt mondott, ltalnos dvzl szveget jelentnk meg. Egy gp cmnek a nv alapjn trtn meghatrozshoz a gethostbyname() fggvnyt hasznlhatjuk. Ennek paramtere egy gpnv, visszatrsi rtke pedig hiba esetn ugyanez a gpnv, sikeres talakts esetn viszont a megnevezett gp IP cme.

Hlzati kapcsolat ltestse


Eddig minden feladatunkat knnyen meg tudtuk oldani, mert a PHP a tvoli weblapok lekrst kznsges fjlkezelss egyszerstette szmunkra. Nha azonban nagyobb felgyeletet kell gyakorolnunk egy-egy hlzati kapcsolat felett, de legalbbis a szoksosnl tbb jellemzjt kell ismernnk.

248

13. ra A hlzati kiszolglk fel az fsockopen() fggvnnyel nyithatunk meg egy kapcsolatot. Paramtere egy IP cm vagy gpnv, egy kapuszm s kt vltozhivatkozs. Vltozhivatkozsokat gy ksztnk, hogy S (&) jelet runk a vltoz neve el. Megadhatunk tovbb egy nem ktelez idkorlt-paramtert is, amely annak az idtartamnak a hossza (msodpercben), ameddig a fggvny vr a kapcsolat ltrejttre. Ha sikerlt megteremtenie a kapcsolatot, egy fjlmutatval tr vissza, egybknt pedig false rtket ad. A kvetkez kdrszlet kapcsolatot nyit egy webkiszolgl fel. $fajlmutato = fsockopen( "www.kiskapu.hu", 80, &$hibakod, &$hibaszoveg, 30 ); A webkiszolglk ltalban a 80-as kapun vrjk a krseket. Az els hivatkozott vltoz, a $hibaszam sikertelen mvelet esetn egy hibakdot tartalmaz, a $hibaszoveg pedig bvebb magyarzattal szolgl a hibrl. Miutn visszakaptuk a kapcsolat fjlmutatjt, a kapcsolaton keresztl az fputs() s fgets() fggvnyek segtsgvel rhatunk s olvashatunk is, ahogy ezt egy kznsges fjl esetben is tehetjk. Munknk vgeztvel a kapcsolatot az fclose() fggvnnyel bonthatjuk. Most mr elegend tuds birtokban vagyunk ahhoz, hogy kapcsolatot ltesthessnk egy webkiszolglval. A 13.6-os programban megnyitunk egy HTTP kapcsolatot, lekrnk egy fjlt, majd egy vltozban troljuk azt.

13.6. program Weboldal lekrse az fsockopen() hasznlatval


1: <html> 2: <head> 3: <title>13.6. program Weboldal lekrse az fsockopen() hasznlatval</title> 4: </head> 5: <body> 6: <?php 7: $kiszolgalo = "www.kiskapu.hu"; 8: $lap = "/index.html"; 9: $fajlmutato = fsockopen( "$kiszolgalo", 80, &$hibaszam, &$hibaszoveg); 10: if ( ! $fajlmutato )

Kapcsolat a klvilggal

249

13.6. program (folytats)


11: die ( "Nem sikerlt kapcsoldni a $kiszolgalo gphez:\nA hiba kdja: $hibaszam\nA hiba szvege: $hibaszoveg\n" ); 12: 13: $lekeres = "GET $lap HTTP/1.0\r\n"; 14: $lekeres .= "Host: $kiszolgalo\r\n"; 15: $lekeres .= "Referer: http://www.linuxvilag.hu/index.html\r\n"; 16: $lekeres .= "User-Agent: PHP browser\r\n\r\n"; 17: $lap = array(); 18: fputs ( $fajlmutato, $lekeres ); 19: while ( ! feof( $fajlmutato ) ) 20: $lap[] = fgets( $fajlmutato, 1024 ); 21: fclose( $fajlmutato ); 22: print "A kiszolgl ".(count($lap))." sort kldtt el!"; 23: ?> 24: </body> 25: </html>

Figyeljk meg, milyen krsfejlcet kldtnk a kiszolglnak. A tvoli gp webmestere a fejlc User-Agent sorban feltntetett adatokat ltni fogja a webkiszolgl napljban. A webmester szmra radsul gy fog tnni, mintha a http://www.linuxvilag.hu/index.html cmrl mutatott volna egy hivatkozs a krt oldalra s mi ennek segtsgvel krtk volna le az oldalt. Emiatt programjainkban nmi fenntartssal kell kezelnnk az ezen fejlcekbl elll krnyezeti vltozk tartalmt s sokkal inkbb segdadatoknak kell azokat tekintennk, mintsem tnyeknek. Vannak esetek, amikor meg kell hamistani a fejlceket. Szksgnk lehet pldul olyan adatokra, amelyeket a kiszolgl csak Netscape bngsznek kld el. Ezek elrsnek egyetlen mdja, ha a User-Agent fejlcsorban egy Netscape bngszre jellemz karakterlncot kldnk. Ennek a webmesterek nem igazn rlnek, hiszen dntseiket a kiszolgl gyjttte statisztikk alapjn kell meghozniuk. Hogy segthessnk ebben nekik, lehetleg ne hamistsuk meg adatainkat, hacsak felttlenl nem szksges. A 13.6-os program nem sokkal bvtette a PHP beptett lapkr mdszereit. A 13.7-es plda azonban mr az fsockopen()-es mdszert alkalmazza egy tmbben megadott weboldalak letltshez s kzben a kiszolgl ltal visszaadott hibakdokat is ellenrzi.

13

250

13. ra

13.7. program Az llapotsor megjelentse webkiszolglk vlaszaibl


1: <html> 2: <head> 3: <title>13.7. program Az llapotsor megjelentse webkiszolglk vlaszaibl</title> 4: </head> 5: <body> 6: <?php 7: $ellenorzendo = array ( "www.kiskapu.hu" => "/index.html", 8: "www.virgin.com" => "/nincsilyenlap.html", 9: "www.4332blah.com" => "/nemletezogep.html" 10: ); 11: foreach ( $ellenorzendo as $kiszolgalo => $lap ) 12: { 13: print "Csatlakozsi ksrlet a $kiszolgalo gphez ...<BR>\n"; 14: $fajlmutato = fsockopen( "$kiszolgalo", 80, &$hibaszam, &$hibaszoveg, 10); 15: if ( ! $fajlmutato ) 16: { 17: print "A $kiszolgalo gphez nem sikerlt csatlakozni:\n<br>A hiba kdja: $hibaszam\n<br>Szvege: $hibaszoveg\n"; 18: print "<br><hr><br>\n"; 19: continue; 20: } 21: print "A $lap oldal fejlcnek letltse ...<br>\n"; 22: fputs( $fajlmutato, HEAD $lap HTTP/1.0\r\n\r\n" ); 23: print fgets( $fajlmutato, 1024 ); 24: print "<br><br><br>\n"; 25: fclose( $fajlmutato ); 26: } 27: ?> 28: </body> 29: </html>

Elszr ltrehozunk egy asszociatv tmbt az ellenrzend kiszolglnevekbl s az oldalak cmeibl. Ezeket sorra vesszk a foreach utasts segtsgvel. Minden elemnl az fsockopen()-nel kezdemnyeznk egy kapcsolatot az adott cmmel,

Kapcsolat a klvilggal de a vlaszra csak 10 msodpercig vrunk. Ha ezen bell nem rkezne vlasz, zenetet jelentnk meg a bngszben, majd a continue utastssal a kvetkez cmre lpnk. Ha a kapcsolatteremts sikeres volt, krelmet is kldnk a kiszolglnak. A krshez a HEAD eljrst hasznljuk, mert a lap tartalmra nem vagyunk kvncsiak. Az fgets() segtsgvel beolvassuk az els sort, az llapotsort. A jelen pldban nem elemezzk a fejlc tbbi rszt, ezrt lezrjuk a kapcsolatot az fclose() fggvnnyel, majd tovbblpnk a kvetkez cmre. A 13.2-es brn a 13.7. program kimenete lthat.

251

13.2. bra
Kiszolglk vlaszt megjelent program

13
NNTP kapcsolat ltrehozsa az fsockopen()-nel
Az fsockopen() fggvny tetszleges internetkiszolglval kpes kapcsolatot teremteni. A 13.8. pldban egy NNTP (Usenet) kiszolglhoz kapcsoldunk: kivlasztunk egy hrcsoportot, majd megjelentjk els zenetnek fejlct.

13.8. program Egyszer NNTP kapcsolat az fsockopen() hasznlatval


1: <html> 2: <head> 3: <title>13.8. program Egyszer NNTP kapcsolat az fsockopen() hasznlatval</title> 4: </head> 5: <body> 6: <?php 7: $kiszolgalo = "news"; // ezt sajt hrkiszolglnk cmre kell belltanunk

252

13. ra

13.8. program (folytats)


8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: $csoport = "alt.test"; $sor = ""; print "<pre>\n"; print " Csatlakozs a $kiszolgalo kiszolglhoz\n\n"; $fajlmutato = fsockopen( "$kiszolgalo", 119, &$hibaszam, &$hibaszoveg, 10 ); if ( ! $fajlmutato ) die("Csatlakozs a $kiszolgalo gphez sikertelen\n$hibaszam\n$hibaszoveg\n\n"); print " Kapcsolat a $kiszolgalo gppel felvve\n\n"; $sor = fgets( $fajlmutato, 1024 ); $allapot = explode( " ", $sor ); if ( $allapot[0] != 200 ) { fputs( $fajlmutato, "close" ); die("Hiba: $sor\n\n"); } print "$sor\n"; print " A $csoport kivlasztsa\n\n"; fputs( $fajlmutato, "group ".$csoport."\n" ); $sor = fgets( $fajlmutato, 1024 ); $allapot = explode( " ", $sor ); if ( $allapot[0] != 211 ) { fputs( $fajlmutato, "close" ); die("Hiba: $sor\n\n"); } print "$sor\n"; print " Az els zenet fejlcnek lekrse\n\n"; fputs( $fajlmutato, "head\n" ); $sor = fgets( $fajlmutato, 1024 ); $allapot = explode( " ", $sor ); print "$sor\n"; if ( $allapot[0] != 221 ) { fputs( $fajlmutato, "close" ); die("Hiba: $sor\n\n"); }

Kapcsolat a klvilggal

253

13.8. program (folytats)


44: 45: 46: 47: 48: 49: 50: 51: 52: 53: while ( ! ( strpos($sor, ".") === 0 ) ) { $sor = fgets( $fajlmutato, 1024 ); print $sor; } fputs( $fajlmutato, "close\n" ); print "</pre>"; ?> </body> </html>

A 13.8. program egy kicsit tbbet mutat annl, hogyan nyissunk az fsockopen()nel NNTP kapcsolatot. Vals alkalmazs esetn a visszakapott sorok elemzst clszer egy fggvnnyel vgezni, egyrszt azrt, hogy megszabaduljunk az ismtlsektl, msrszt azrt, hogy tbb adatot is kinyerhessnk a vlaszbl. Mieltt azonban jra feltallnnk a kereket, clszer, ha megismerkednk a PHP IMAP fggvnyeivel, amelyekkel mindez a munka automatizlhat. A fenti programban a $kiszolgalo vltoz trolja a hrkiszolgl nevt, a $csoport pedig annak a csoportnak a nevt, melyhez kapcsoldni szeretnnk. Ha ki szeretnnk prblni ezt a programot, javtsuk t a $kiszolgalo vltoz rtkt az internetszolgltatnk ltal megadott hrkiszolgl nevre, a $csoport-ot kedvenc csoportunkra. Az fsockopen()-nel a kiszolgl 119-es kapujra csatlakozunk, mert ez a hrcsoport szolgltats szabvnyos kapuja. Ha nem kapunk vissza hasznlhat fjlmutatt, a die() fggvny segtsgvel megjelentnk egy hibazenetet a bngszben s kilpnk a programbl. Kapcsolds esetn a kiszolgltl kapnunk kell egy nyugtz zenetet, amit az fgets() fggvnnyel prblunk fogadni. Ha minden zkkenmentesen zajlott, a visszakapott szveg a 200-as llapotkddal kezddik. Ennek ellenrzshez az explode() fggvnnyel a szkzk mentn sztdaraboljuk a $sor vltozt s a darabokat egy tmbbe helyezzk. Az explode() fggvnnyel rszletesebben a tizenhetedik rban foglalkozunk. Ha a kapott tmb els eleme (a nulls index) 200, akkor tovbblpnk, egybknt pedig befejezzk a programot. Ha minden az elvrsoknak megfelelen haladt, akkor a "group" paranccsal kivlasztjuk a kvnt hrcsoportot. Ha ez is sikerlt, a kiszolglnak egy 211-es llapotkddal kezdd szveget kell vlaszul kldenie. Ezt is ellenrizzk s sikertelensg esetn kilpnk a programbl.

13

254

13. ra A hrcsoport kivlasztsa utn kldnk egy "head" parancsot. Ennek hatsra visszakapjuk a csoport els zenetnek fejlct. Termszetesen krsnkre ez esetben is elszr egy nyugta rkezik, mely a 211-es llapotkdot kell, hogy tartalmazza. A fejlc csak ezt kveten rkezik, szmos hasznos informcit tartalmaz sorral. A fejlcet zr sor egyetlen pontot tartalmaz. Ezt a sort egy while ciklussal keressk meg. Mindaddig, mg a kiszolgl vlaszsora nem ponttal kezddik, tovbbi sorokat olvasunk be s mindegyiket megjelentjk a bngszben. Vgs lpsknt bontjuk a kapcsolatot. A 13.3-as bra a 13.8-as program egy lehetsges eredmnyt mutatja be.

13.3. bra
NNTP kapcsolat megteremtse

Levl kldse a mail() fggvnnyel


A PHP leveszi a vllunkrl az elektronikus levelezs gondjt is. A mail() fggvny hrom karakterlncot vr paramterknt. Az els a cmzett, a msodik a levl trgya, a harmadik pedig maga az zenet. A mail() false rtkkel tr vissza, ha problmba tkzik a levl kldse sorn. A kvetkez kdrszlet egy rvid levl kldst pldzza: $cimzett = "valaki@tartomany.hu"; $targy = "dvzlet"; $uzenet = "ez csak egy prba zenet! "; mail( $cimzett, $targy, $uzenet ) or print "A levl elkldse sikertelen";

Kapcsolat a klvilggal Ha a PHP-t UNIX rendszeren futtatjuk, a Sendmailt fogja hasznlni, ms rendszereken a helyi vagy egy tvoli SMTP kiszolglt fog feladata elvgzshez ignybe venni. A kiszolglt a php.ini fjl SMTP utastsval kell belltani. Nem kell a mail() ktelez paramterei ltal ellltott fejlcekre szortkoznunk. A fggvnynek van ugyanis egy elhagyhat negyedik paramtere is, mellyel szabadon alakthatjuk az elkldend levl fejlceit. Az ebben felsorolt fejlcsorokat a CRLF (\r\n) karakterprral kell elvlasztanunk. Az albbi pldban egy From (Felad) s egy X-Priority (Fontossg) mezvel bvtjk a fejlcet. Ez utbbit csak bizonyos levelezrendszerek veszik figyelembe. A plda a kvetkez: $cimzett = "valaki@tartomany.hu"; $felado = "masvalaki@masiktartomany.hu"; $targy = "dvzlet "; $uzenet = "ez csak egy proba zenet! "; mail( $cimzett, $targy, $uzenet, "From: $felado\r\nX-Priority: 1 (Highest)" ) or print "A levl elkldse sikertelen";

255

sszefoglals
Ezen az rn megtudhattuk, hogyan vethetjk be a krnyezeti vltozkat, ha tbb adatot szeretnnk megtudni ltogatinkrl. Ha nem tudjuk a ltogat gpnek nevt, a gethostbyaddr() fggvnnyel kiderthetjk. Lthattuk miknt zajlik egy HTTP kapcsolat megteremtse a kiszolgl s az gyfl kztt, megtanultuk, hogyan tltsnk le egy dokumentumot a webrl az fopen() segtsgvel s hogyan ptsk ki sajt HTTP kapcsolatunkat az fsockopen() fggvny felhasznlsval. Az fsockopen()-nel ms hlzati szolgltatsokhoz is kapcsoldtunk, vgl pedig elektronikus levelet kldtnk a programbl a mail() fggvny egyszer meghvsval.

13

Krdsek s vlaszok
A HTTP meglehetsen misztikusnak tnik. Tnyleg szksg van az ismeretre, ha j PHP kdot szeretnnk rni? Nem. Kitn programok kszthetk a kiszolgl-gyfl prbeszd rszletes ismerete nlkl is. Msfell azonban szksg van ilyen alapvet ismeretekre, ha kicsit bonyolultabb feladatokat szeretnnk programozottan vgrehajtani, pldul weboldalakat letlteni.

256

13. ra Ha n is knnyedn kldhetek hamis fejlceket, akkor mennyire bzhatok a msok fejlcei alapjn ltrehozott krnyezeti vltozkban? Az olyan krnyezeti vltozkban, mint a $HTTP_REFERER vagy a $HTTP_USER_AGENT, nem szabad megbznunk, amennyiben ezen informcik pontos ismerete programunkban alapvet kvetelmny. Az gyflprogramok tekintlyes hnyada azonban nem hazudik: ha a bngsztpust s az egyb felhasznli jellemzket olyan cllal gyjtjk, hogy az abbl ksztett statisztikk elemzse alapjn a felhasznlkat jobban szolglhassuk, nincs rtelme foglalkoznunk azzal, hogy nem minden adat felttlenl helytll.

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Mely krnyezeti vltoz rulja el neknk annak a lapnak a cmt, amely a programunkra hivatkozott? 2. Mirt nem felel meg a $REMOTE_ADDR vltoz a ltogat nyomon kvetsre? 3. Minek a rvidtse s mit jelent a HTTP? 4. A fejlc mely sorbl tudhatja meg a kiszolgl, hogy milyen gyflprogramtl rkezett a krs? 5. Mit takar a kiszolgl 404-es vlaszkdja? 6. Anlkl, hogy kln kapcsolatot ptennk fel egy kiszolglval, mely fggvnnyel tlthetnk le egy weboldalt rla? 7. Adott IP cm alapjn hogyan derthet ki a hozz tartoz gp neve? 8. Melyik fggvny hasznlhat hlzati kapcsolat ltrehozsra? 9. A PHP mely fggvnyvel kldennk elektronikus levelet?

Kapcsolat a klvilggal

257

Feladatok
1. Ksztsnk egy programot, amely egy webcmet kr be (pldul http://www.kiskapu.hu/) a felhasznltl, majd egy HEAD krst kldve felveszi a kapcsolatot azzal. Jelentsk meg a kapott vlaszt a bngszben. Ne feledkezznk meg arrl, hogy a kapcsolat nem mindig jn ltre. 2. Ksztsnk olyan programot, amely a felhasznlnak lehetv teszi, hogy begpeljen nmi szveget, majd elektronikus levl formjban tovbbtsa azt a mi e-mail cmnkre. ruljuk el a felhasznlnak, hogy a krnyezeti vltozk mit is lltanak rla.

13

14. RA
Dinamikus kpek kezelse
Az ezen az rn vett fggvnyek a GD nev nylt forrskd programknyvtron alapulnak. A GD knyvtr olyan eszkzcsoport, melynek segtsgvel futsidben kpeket hozhatunk ltre s kezelhetjk azokat. A GD-rl a http://boutell.com/gd/ weboldal szolgl bvebb informcival. Ha a knyvtrat teleptettk s a PHP-t is lefordtottuk, elkezdhetnk dinamikus kpeket ltrehozni a PHP grafikus fggvnyeivel. Sok rendszer mg mindig a knyvtr egy rgebbi vltozatt futtatja, amely a kpeket GIF formtumban hozza ltre. A knyvtr ksbbi vltozatai licenszokok miatt nem tmogatjk a GIF formtumot. Ha rendszernkre a knyvtr egy jabb vltozatt teleptettk, gy is lefuttathatjuk a PHP-t, hogy a kpalkot fggvnyek kimeneti formtuma PNG legyen, amelyet a legtbb bngsz tmogat. A GD knyvtr segtsgvel menet kzben hozhatunk ltre bonyolult alakzatokat a PHP grafikus fggvnyeivel. Az ra sorn a kvetkezket tanuljuk meg: Hogyan hozzunk ltre s jelentsnk meg egy kpet? Hogyan dolgozzunk a sznekkel? Hogyan rajzoljunk alakzatokat, pldul krveket, tglalapokat s sokszgeket?

260

14. ra Hogyan tltsnk ki sznnel alakzatokat? Hogyan kezeljk a TrueType bettpusokat?

Kpek ltrehozsa s megjelentse


Mieltt elkezdhetnnk a kpekkel foglalkozni, elszr szert kell tennnk egy kpazonostra. Ezt az imagecreate() fggvny segtsgvel tehetjk meg. Ennek kt paramtere van, az egyik a kp magassgra vonatkozik, a msik a szlessgre. Ekkor egy kpazonostt kapunk vissza, amelyet az rn trgyalt majdnem mindegyik fggvny esetben hasznlni fogunk. Miutn megkaptuk az azonostt, mr majdnem kszen llunk arra, hogy megjelentsk els kpnket a bngszben. Ehhez az imagegif() fggvnyre van szksgnk, amelynek paramtere a kpazonost. A 14.1. programban a kp ltrehozshoz s megjelentshez hasznlt fggvnyeket lthatjuk.

14.1. program Dinamikusan ltrehozott kp


1: 2: 3: 4: 5: <?php header("Content-type: image/gif"); $kep = imagecreate( 200, 200 ); imagegif($kep); ?>

Fontos, hogy a Content-type fejlcsort minden egyb eltt kldtk a bngsznek. Kzlnnk kell a bngszvel, hogy egy kpet kldnk, klnben a program kimenett HTML-knt kezeli. A programot a bngsz mr kzvetlenl vagy egy IMG elem rszeknt hvhatja meg. <img src="14.1.program.php" alt="egy PHP ksztette kp"> A 14.1. brn lthatjuk a 14.1. program kimenett. Egy tglalapot hoztunk ltre, de egyelre nem tudjuk annak sznt belltani.

Dinamikus kpek kezelse

261

14.1. bra
Dinamikusan ltrehozott alakzat

A szn belltsa
A szn belltshoz egy sznazonostra van szksgnk. Ezt az imagecolorallocate() fggvnnyel kaphatjuk meg, amelynek paramtere a kpazonost, illetve hrom 0 s 255 kztti egsz szm, amelyek a vrs, zld s kk sznsszetevket jelentik. Egy sznazonostt kapunk vissza, amellyel ksbb alakzatok, kitltsek vagy szvegek sznt hatrozhatjuk meg. $piros = imagecolorallocate($kep, 255,0,0); Az imagecolorallocate() fggvny els meghvsakor egyttal tlltja a paramterl kapott alakzat sznt is. gy ha az elz kdrszletet hozzadjuk a 14.1. programhoz, egy vrs tglalapot kapunk.

14

Vonalak rajzolsa
Mieltt egy kpre vonalat rajzolhatnnk, meg kell adnunk annak kt vgpontjt. A kpet gy kpzeljk el, mint kpernypontokbl ll tmbt, melynek mindkt tengelye 0-tl szmozdik. A szmozs kezdpontja a kp bal fels sarka. Ms szval az (5, 8) koordintj kppont a hatodik kppont fentrl lefel s a kilencedik kppont balrl jobbra szmolva.

262

14. ra Az imageline() fggvny kt kppont kz rajzol egy egyenest. A fggvny paramterknt egy kpazonostt vr, ngy egsz szmot, amelyek az egyenes kt vgpontjnak koordintit jelentik, valamint egy sznazonostt. Ha a 14.2. programban megrajzoljuk a tglalap egy tljt.

14.2. program Egyenes rajzolsa az imageline() fggvnnyel


1: 2: 3: 4: 5: 6: 7: 8: <?php header("Content-type: image/gif"); $kep = imagecreate( 200, 200 ); $piros = imagecolorallocate($kep, 255,0,0); $kek = imagecolorallocate($kep, 0,0,255 ); imageline( $kep, 0, 0, 199, 199, $kek ); imagegif($kep); ?>

Kt sznazonostt kapunk, egyet a piros s egyet a kk sznnek. Ezutn a $kek vltozban trolt azonostt hasznljuk a vonal sznnek megadsra. Fontos megjegyeznnk, hogy a vonal a (199, 199) s nem a (200, 200) koordintkban vgzdik, tekintve, hogy a kppontokat 0-tl kezdve szmozzuk. A 14.2. brn a 14.2. program eredmnyt lthatjuk.

14.2. bra
Egyenes rajzolsa az imageline() fggvnnyel

Dinamikus kpek kezelse

263

Alakzatok kitltse
A PHP segtsgvel ugyangy kisznezhetnk alakzatokat, mint kedvenc grafikai programunkkal. Az imagefill() fggvny bemenete egy kpazonost, a kitlts kezdkoordinti, valamint egy sznazonost. A fggvny a kezd kpponttal megegyez szn szomszdos kppontokat a kijellt sznre lltja. A 14.3. program a kpet az imagefill() fggvny meghvsval teszi egy kicsit rdekesebb.

14.3. program Az imagefill() fggvny hasznlata


1: 2: 3: 4: 5: 6: 7: 8: 9: <?php header("Content-type: image/gif"); $kep = imagecreate( 200, 200 ); $piros = imagecolorallocate($kep, 255,0,0); $kek = imagecolorallocate($kep, 0,0,255 ); imageline( $kep, 0, 0, 199, 199, $kek ); imagefill( $kep, 0, 199, $kek ); imagegif($kep); ?>

A 14.3. brn a 14.3. program kimenett lthatjuk.

14.3. bra
Az imagefill() fggvny hasznlata

14

264

14. ra

Krv rajzolsa
Az imagearc() fggvny segtsgvel krveket rajzolhatunk. Bemenete egy kpazonost, a kzppont koordintja, a szlessget meghatroz egsz szm, a magassgot meghatroz egsz szm, egy kezd- s egy vgpont (fokban mrve), valamint egy sznazonost. A krveket az ramutat jrsnak megfelelen, 3 rtl kezdve rajzoljuk. A kvetkez kdrszlet egy negyed krvet rajzol ki: imagearc( $kep, 99, 99, 200, 200, 0, 90, $kek ); Ez egy olyan krvrszletet jelent meg, melynek kzppontja a (99, 99) koordintj pontban van. A teljes magassg s szlessg 200-200 kppontnyi. A krv 3 rnl kezddik s 90 fokot rajzolunk (azaz 6 rig). A 14.4. program teljes krt rajzol s kk sznnel tlti ki.

14.4. program Kr rajzolsa az imagearc() fggvnnyel


1: 2: 3: 4: 5: 6: 7: 8: 9: <?php header("Content-type: image/gif"); $kep = imagecreate( 200, 200 ); $piros = imagecolorallocate($kep, 255,0,0); $kek = imagecolorallocate($kep, 0,0,255 ); imagearc( $kep, 99, 99, 180, 180, 0, 360, $kek ); imagefill( $kep, 99, 99, $kek ); imagegif($kep); ?>

A 14.4. program kimenett a 14.4. brn lthatjuk.

Dinamikus kpek kezelse

265

14.4. bra
Kr rajzolsa az imagearc() fggvnnyel

Tglalap rajzolsa
A PHP imagerectangle() fggvnyvel tglalapot rajzolhatunk. Az imagerectangle() bemenete egy kpazonost, a tglalap bal fels s jobb als sarknak koordintja, valamint egy sznazonost. A kvetkez kdrszlet olyan tglalapot rajzol, melynek bal fels s jobb als koordinti rendre (19, 19) s (179, 179): imagerectangle( $kep, 19, 19, 179, 179, $kek );

Az alakzatot ezutn az imagefill() fggvnnyel tlthetjk ki. Mivel ez meglehetsen gyakori mvelet, a PHP-ban ltezik az imagefilledrectangle() fggvny, amely ugyanazokat a bemeneti rtkeket vrja, mint az imagerectangle(), de az ltalunk meghatrozott sznnel ki is tlti a tglalapot. A 14.5. program egy kisznezett tglalapot hoz ltre s megjelenti a bngszben.

14

266

14. ra

14.5. program Tglalap rajzolsa az imagefilledrectangle() fggvnnyel


1: 2: 3: 4: 5: 6: 7: 8: <?php header("Content-type: image/gif"); $kep = imagecreate( 200, 200 ); $piros = imagecolorallocate($kep, 255,0,0); $kek = imagecolorallocate($kep, 0,0,255 ); imagefilledrectangle( $kep, 19, 19, 179, 179, imagegif( $kep ); ?>

$kek );

A 14.5. brn a 14.5. program ltal ellltott kpet lthatjuk.

14.5. bra
Tglalap rajzolsa az imagefilledrectangle() fggvnnyel

Sokszg rajzolsa
Az imagepolygon() fggvny segtsgvel kifinomultabb alakzatokat is rajzolhatunk. E fggvny bemenete egy kpazonost, a pontok koordintibl ll tmb, az alakzat pontjainak szmt jelz egsz szm s egy sznazonost. Az imagepolygon() bemenett kpez tmbnek szmmal indexeltnek kell lennie. Az els kt elem az els pont koordintit adja meg, a msodik kett a msodik pontt s gy tovbb. Az imagepolygon() fggvny megrajzolja a pontok kztti vonalakat s az utols pontot automatikusan sszekti az elsvel. Az imagefilledpolygon() fggvny segtsgvel sznnel kitlttt sokszgek hozhatk ltre.

Dinamikus kpek kezelse A 14.6. program egy kitlttt sokszget rajzol s jelent meg a bngszben.

267

14.6. program Sokszg rajzolsa az imagefilledpolygon() fggvnnyel


<?php header("Content-type: image/gif"); $kep = imagecreate( 200, 200 ); $piros = imagecolorallocate($kep, 255,0,0); $kek = imagecolorallocate($kep, 0,0,255 ); $pontok = array (10, 10, 190, 190, 190, 10, 10, 190 ); imagefilledpolygon( $kep, $pontok, count ( $pontok )/2, $kek ); 12: imagegif($kep); 13: ?> 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:

Vegyk szre, hogy az sszektend pontok szma az imagefilledpolygon() fggvny hvsakor megegyezik a $pontok tmb elemei szmnak felvel. A 14.6. brn a 14.6. program eredmnyt lthatjuk.

14.6. bra
Sokszg rajzolsa az imagefilledpolygon() fggvnnyel

14

268

14. ra

A sznek tltszv ttele


A PHP az imagecolortransparent() fggvnnyel lehetv teszi, hogy a kivlasztott szneket az brn bell ttetszv tegyk. A fggvny bemenete egy kp- s egy sznazonost. Ha a kpet megjelentjk egy bngszben, az imagecolortransparent() fggvnynek tadott szn ttetsz lesz. A 14.7. program kimenete a sokszget rajzol programot gy vltoztatja meg, hogy az alakzat szni fog a bngszben, ahelyett, hogy egy httrszn eltt jelenne meg.

14.7. program A sznek tltszv ttele az imagecolortransparent() fggvnnyel


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: <?php header("Content-type: image/gif"); $kep = imagecreate( 200, 200 ); $piros = imagecolorallocate($kep, 255,0,0); $kek = imagecolorallocate($kep, 0,0,255 ); $pontok = array (10, 10, 190, 190, 190, 10, 10, 190 );

imagefilledpolygon( $kep, $pontok, count ( $pontok )/2, $kek ); 15: imagecolortransparent( $kep, $piros ); 16: imagegif($kep); 17: ?>

A 14.7. brn a 14.7. program kimenett lthatjuk.

Dinamikus kpek kezelse

269

14.7. bra
A sznek tltszv ttele az imagecolortransparent() fggvnnyel

Szvegek kezelse
Ha rendszernkn vannak TrueType betk, a kpekre rhatunk is. A GD programknyvtr mellett szksgnk lesz a FreeType programknyvtr teleptsre is. Ha ezek rendelkezsnkre llnak, egy kpben megjelen diagramokat s navigcis elemeket is ltrehozhatunk. A PHP biztost szmunkra egy olyan eszkzt is, amellyel ellenrizhetjk, hogy a berand szveg elfr-e a rendelkezsre ll helyen.

Szvegrs az imageTTFtext() fggvnnyel


Az imageTTFtext() fggvnnyel az brkra szveget rhatunk. A fggvny nyolc bemen paramtere a kvetkez: kpazonost, mret, amely a kirand szveg magassgra utal, szg, a kezd x s y koordintk, sznazonost, a TrueType bettpus elrsi tvonala s a kirand szveg. A kirand szveg kezdkoordintja hatrozza meg, hol lesz a szveg els karakternek alapvonala. A 14.8. program egy karakterlncot r az brra, majd az eredmnyt megjelenti a bngszben.

14

270

14. ra

14.8. program Szvegrs az imageTTFtext() fggvnnyel


1: 2: 3: 4: 5: 6: 7: <?php header("Content-type: image/gif"); $kep = imagecreate( 400, 200 ); $piros = imagecolorallocate($kep, 255,0,0); $kek = imagecolorallocate($kep, 0,0,255 ); $betukeszlet = "/usr/local/office52/share/fonts/ /TrueType/arial.ttf";

8: 9: imageTTFtext( $kep, 50, 0, 20, 100, $kek, $betukeszlet, "dvzljk!" ); 10: 11: imagegif($kep); 12: ?>

Ltrehozunk egy 400 kppontnyi szles s 200 kppontnyi magas vsznat, megadunk kt sznt s a $betukeszlet vltozban troljuk a TrueType bettpus elrsi tjt. Ezutn rrjuk az brra a dvzljk! szveget. Figyelem, a bettpusok a kiszolgln feltehetleg ms knyvtrban tallhatk! Ha nem vagyunk biztosak a helyben, keressk a .ttf kiterjeszts fjlokat. Az imageTTFtext() meghvshoz az 50-es magassgot, 0 fokos szget s (20, 100) kezdkoordintt adtuk t. Emellett a fggvny megkapja mg a $kek vltozban trolt sznazonostt s a $betukeszlet vltozban trolt bettpust, vgl a kirand szveget. Az eredmnyt a 14.8. brn lthatjuk.

14.8. bra
Szveg rsa az imageTTFtext() fggvnnyel

Dinamikus kpek kezelse Persze most mg csak tallgatunk, hov tegyk a szveget. A betmret nem rul el sokat a szveg magassgrl, a szlessgrl mg kevesebbet. Az imageTTFtext() fggvny persze visszaad informcit a szveg kiterjedsrl, de akkorra mr minden eldlt. Szerencsre a PHP lehetsget nyjt arra, hogy prblkozzunk, mieltt mg lesben elvgeznnk a mveletet.

271

Szveg kiterjedsnek ellenrzse az imageTTFbox() fggvnnyel


A szveg kiterjedsrl az imageTTFbox() fggvnnyel szerezhetnk informcit, amely onnan kapta nevt, hogy a szveget hatrol dobozt rja le. A fggvny bemenete a betmret, a szg, a bettpus elrsi tja s a krdses szveg. Azon kevs fggvnyek egyike, melyekhez nem kell a kpazonost. Egy nyolcelem tmbt ad vissza, amely a szveg kirshoz szksges terlet paramtereit (koordintit) tartalmazza. A 14.1. tblzatban a fggvny ltal visszaadott tmbt rtelmezzk.

14.1. tblzat Az imageTTFbox() fggvny ltal visszaadott tmb


Sorszm 0
1 2 3 4 5 6 7

Lers bal als (vzszintes tengely)


bal als (fggleges tengely) jobb als (vzszintes tengely) jobb als (fggleges tengely) jobb fels (vzszintes tengely) jobb fels (fggleges tengely) bal fels (vzszintes tengely) bal fels (fggleges tengely)

14

A fggleges tengelyhez visszaadott szmok (1-es, 3-as, 5-s, s 7-es tmbelemek) a szveg alapvonalhoz viszonyulnak, amelynek koordintja 0. A szveg tetejnek a fggleges tengelyen mrt rtkei ehhez kpest ltalban negatv szmok, mg a szveg aljnak itt mrt rtkei ltalban pozitvak. gy kapjuk meg, hny kpponttal nylik a szveg az alapvonal al. Az imageTTFbox() ltal figyelembe vett koordintarendszert gy kell elkpzelnnk, mintha a szveg alapvonala lenne az y irnyban vett 0 rtk s a negatv koordintk attl felfel, a pozitvak pedig attl lefel helyezkednnek el. gy pldul ha az imageTTFbox() fggvnnyel ellenrizend szvegben van egy "y", a visszakapott tmbben az 1-es index elem lehet, hogy 3 lesz, mivel az "y" als szra hrom kpponttal nylik

272

14. ra az alapvonal al. Lehetsges, hogy a 7-es elem 10 lesz, mivel a szveg 10 kpponttal van az alapvonal fl emelve. A pontos rtkek bettpustl s betmrettl fggnek. Csak hogy bonyoltsuk a helyzetet, gy tnik, hogy az imageTTFbox() fggvny ltal visszaadott alapvonal s a rajzols kzben lthat kztt 2 kppontos eltols van. Ezt gy ellenslyozhatjuk, hogy az alapvonalat kt kppontnyival magasabbnak kpzeljk, mint amilyennek az imageTTFbox() fggvny mutatja. A vzszintes tengelyen a bal oldali szmok (a 0-s s a 6-os elem) esetben az imageTTFbox() fggvny az adott kezdpont eltt kezdd szveget negatv szmmal kifejezett eltolssal jelli. Ez ltalban alacsony szm, mivel a betk jellemzen jelentsebb eltrst mutatnak az alapvonaltl, mint az x irny kezdkoordinttl (gondoljunk a p, g vagy j betkre). A vzszintes tengelyen gy mr csak az elvrt pontossg krdse, hogy szksgnk van-e a koordintk kiigaztsra. Az imageTTFbox() fggvny ltal visszaadott rtkeket arra is hasznlhatjuk, hogy az brn bell a szveget igaztsuk. A 14.9. program dinamikusan kldi a bngsznek a szveget, gy, hogy mind a vzszintes, mind a fggleges tengelyen kzpre helyezi azt.

14.9. program Szveg elhelyezse az imageTTFbox() fggvny hasznlatval


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: <?php header("Content-type: image/gif"); $magassag = 100; $szelesseg = 200; $betumeret = 50; if ( ! isset ( $szoveg ) ) $szoveg = "Vltoztasson meg!"; $kep = imagecreate( $szelesseg, $magassag ); $piros = imagecolorallocate($kep, 255,0,0); $kek = imagecolorallocate($kep, 0,0,255 ); $betukeszlet = "/usr/local/office52/share/fonts/ /TrueType/arial.ttf"; $szovegszelesseg = $szelesseg; $szovegmagassag; while ( 1 ) { $doboz = imageTTFbox( $betumeret, 0, $betukeszlet, $szoveg ); $szovegszelesseg = abs( $doboz[2] ); $szovegmagassag = ( abs($doboz[7]) )-2;

Dinamikus kpek kezelse

273

14.9. program (folytats)


19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: if ( $szovegszelesseg < $szelesseg - 20 ) break; $betumeret--; } $gifXkozep = (int) ( $szelesseg/2 ); $gifYkozep = (int) ( $magassag/2 ); imageTTFtext( $kep, $betumeret, 0, (int) ($gifXkozep-($szovegszelesseg/2)), (int) ($gifYkozep+($szovegmagassag/2)), $kek, $betukeszlet, $szoveg ); imagegif($kep); ?>

A kp magassgt s szlessgt a $magassag s $szelesseg vltozkban troljuk, a bettpus alapbellts mrett pedig 50-re lltjuk. Megvizsgljuk, hogy ltezik-e mr a $szoveg nev vltoz; ha nem, belltjuk egy alaprtkre. Ezzel az eljrssal egy brnak is lehetnek paramterei, fogadhat adatot egy weboldalrl akr egy URL kereskifejezsbl, akr egy kitlttt rlaprl. A kpazonost ellltshoz az imagecreate() fggvnyt hasznljuk. A sznazonostkat a szoksos mdon lltjuk el, a $betukeszlet nev vltozban pedig a TrueType bettpus elrsi tjt rgztjk. Azt szeretnnk, hogy a $szoveg vltozban trolt karaktersorozat elfrjen a rendelkezsre ll helyen, de egyelre nem tudhatjuk, hogy ez sikerlni fog-e. A while utastson bell tadjuk a bettpus elrsi tjt s a szveget az imageTTFbox() fggvnynek, az eredmnyl kapott tmbt pedig a $doboz vltozba helyezzk. A $doboz[2] tartalmazza a jobb als sarok helyt a vzszintes tengelyen. Ezt vesszk a karaktersorozat szlessgnek s a $szovegszelesseg vltozban troljuk. A szveget fgglegesen is kzpre szeretnnk helyezni, de a szveg alapvonala alatt lv rszt figyelmen kvl hagyva. Az alapvonal feletti magassg meghatrozshoz hasznlhatjuk a $doboz[7] vltozban tallhat szm abszolt rtkt, br ezt mg ki kell igaztanunk a fent emltett kt kpponttal. Ezt az rtket a $szovegmagassag vltozban troljuk. Most, hogy kiszmtottuk a szveg szlessgnek rtkt, sszevethetjk az bra szlessgvel (tz kppontnyival kell kevesebbnek lennie, a keret miatt). Ha a szveg keskenyebb, mint a kp szlessge, befejezzk a ciklust. Ellenkez esetben cskkentjk a betmretet s jra prblkozunk.

14

274

14. ra A $magassag s a $szelesseg vltozk rtkt elfelezve megkapjuk az bra hozzvetleges kzppontjt. A szveget az bra kzppontjbl s a szveg magassgbl, illetve szlessgbl kiszmtott eltolssal az brra rjuk, vgl megjelentjk a kpet a bngszben. A 14.9. brn lthatjuk a 14.9. program kimenett. Ezt a kdot egy msik oldal is meghvhatja, egy IMG elem rszeknt. A kvetkez rszlet egy olyan programot hoz ltre, amely lehetv teszi az egyes felhasznlknak, hogy sajt szveget jelentsenek meg az brn: 1: 2: 3: 4: 5: 6: 7: 8: 9: <?php if ( ! isset( $szoveg ) ) $szoveg = "Dinamikus szveg!"; ?> <form action="<? print $PHP_SELF ?>" method="POST"> <input type="text" name="szoveg"> </form> <p> <img src="14.9.program.php?<? print "szoveg=".urlencode($szoveg) ?>">

Amikor a 14.9. programot meghvjuk, egy olyan kereskifejezssel egsztjk ki a hvst, amely tartalmazza a megjelentend szveget. A tizenkilencedik rban tbbet is tanulhatunk az informcik programrl programra val tadsrl.

14.9. bra
Szveg elhelyezse az imageTTFbox() fggvny hasznlatval

Dinamikus kpek kezelse

275

A fenti elemek sszegyrsa


Ksztsnk egy pldt az ezen az rn tanult fggvnyek hasznlatval! Tegyk fel, hogy arra krtek bennnket, hogy ksztsnk egy dinamikus oszlopgrafikont, amely tbb cmkzett szmot hasonlt ssze. Az egyes oszlopok alatt a megfelel cmknek kell lennie. gyfelnknek tudnia kell mdostani a grafikon oszlopainak szmt, a kp szlessgt s magassgt s a grafikont krlvev keret mrett. A grafikont fogyaszti szavazshoz fogjk hasznlni, gy az adatokat csak ltszlagos pontossggal kell megjelenteni. Egy sokkal rszletesebb lebontst az brt tartalmaz oldal HTML rszben tallhatunk. Az oszlopokat s rtkeiket a legegyszerbb mdon egy asszociatv tmbben trolhatjuk. Miutn megvan ez a tmb, ki kell szmolnunk az oszlopok szmt s a tmb legnagyobb rtkt: $cellak = array ( "tetszik"=>200, "nem tetszik"=>400, "kzmbs"=>900 ); $max = max( $cellak ); $cellaszam = count( $cellak ); Ltre kell hoznunk nhny vltozt, gy gyfelnk egyni ignyeihez igazthatja az brt: $teljesszelesseg = 400; $teljesmagassag = 200; $xmargo = 20; // jobb s bal marg $ymargo = 20; // fels s als marg $oszlopkoz = 5; // az oszlopok kztti hely $alsokeret = 40; // az bra aljn kimarad hely (a margt nem szmolva) $betukeszlet = "/usr/local/office52/share/fonts/ /TrueType/arial.ttf"; gyfelnk a vltozk mdostsval meghatrozhatja az bra magassgt s szlessgt. Az $xmargo s $ymargo a grafikon krli margvastagsgot adja meg. Az $oszlopkoz az oszlopok kztti tvolsgot hatrozza meg, az $alsokeret vltoz pedig az oszlopok alatti cmkknek sznt hely nagysgt. Most hogy megvannak ezek az rtkek, a nmi szmolgats rn bellk kapott hasznos szmokat vltozkba tesszk:

14

276

14. ra $vaszonszelesseg = ( $teljesszelesseg - $xmargo*2 ); $vaszonmagassag = ( $teljesmagassag - $ymargo*2 - $alsokeret ); $xPoz = $xmargo; // a rajzols kiindulpontja az x tengelyen $yPoz = $teljesmagassag - $ymargo - $alsokeret; // a rajzols kiindulpontja az y tengelyen $cellaszelesseg = (int) (( $vaszonszelesseg - ( $oszlopkoz * ( $cellaszam-1 ) )) / $cellaszam) ; $szovegmeret = (int)($alsokeret); Kiszmtjuk a rajzfelletet (azt a terletet, ahov majd az oszlopok kerlnek). A vzszintes sszetevt gy kapjuk meg, hogy a teljes szlessgbl kivonjuk a marg ktszerest. A fggleges mrethez az $alsokeret vltozt is szmtsba kell vennnk, hogy a cmkknek helyet hagyjunk. Az $xPoz trolja azt az x koordintt, amelytl az oszlopok rajzolst kezdjk, gy ennek rtkt az $xmargo vltoz rtkre lltjuk, amely a marg rtknek vzszintes sszetevjt trolja. Az oszlopok talppontjt trol $yPoz vltoz rtkt gy kapjuk meg, ha az bra teljes magassgbl kivonjuk a margt s a cmkknek kihagyott hely nagysgt, amelyet az $alsokeret vltozban troltunk. A $cellaszelesseg az egyes oszlopok szlessgt trolja. Ahhoz, hogy az rtkt megkapjuk, szmoljuk ki az oszlopok kztti helyek sszegt, ezt vonjuk ki a diagram szlessgbl, majd az eredmnyt osszuk el az oszlopok szmval. Kezdetben gy lltjuk be a szveg mrett, hogy egyezzen a szveg szmra szabadon maradt terlet magassgval (amit az $alsokeret vltozban trolunk). Mieltt megkezdennk a munkt az brval, meg kell hatroznunk a szveg mrett. Viszont nem tudjuk, milyen szlesek lesznek a cmkk s mindenkppen azt szeretnnk, hogy az egyes cmkk elfrjenek a felettk lev oszlop szlessgn bell. A $cellak tmbn egy ciklus segtsgvel meghatrozzuk a legnagyobb cmke mrett: forach( $cellak as $kulcs => $ertek ) { while ( 1 ) { $doboz = ImageTTFbBox( $szovegmeret, 0, $betukeszlet, $kulcs ); $szovegszelesseg = $doboz[2]; if ( $szovegszelesseg < $cellaszelesseg ) break; $szovegmeret; } }

Dinamikus kpek kezelse Minden elem esetben egy ciklust kezdve, az imageTTFbox() segtsgvel informcit szerznk a cmke mrett illeten. A kapott rtket a $doboz[2] vltozban tallhatjuk meg, amit sszevetnk a $cellaszelesseg vltozval, amely egy oszlop szlessgt tartalmazza. A ciklust abban az esetben lltjuk le, ha a szveg szlessge kisebb, mint az oszlopszlessg. Egybknt pedig cskkentjk a $szovegmeret rtkt s jra ellenrizzk a mreteket. A $szovegmeret addig cskken, mg a tmb sszes cmkje kisebb nem lesz az oszlopszlessgnl. Most mr vgre ltrehozhatunk egy kpazonostt s elkezdhetnk dolgozni vele. $kep = imagecreate( $teljesszelesseg, $teljesmagassag ); $piros = ImageColorAllocate($kep, 255, 0, 0); $kek = ImageColorAllocate($kep, 0, 0, 255 ); $fekete = ImageColorAllocate($kep, 0, 0, 0 ); forach( $cellak as $kulcs => $ertek ) { $cellamagassag = (int) (($ertek/$max) * $vaszonmagassag); $kozeppont = (int)($xPoz+($cellaszelesseg/2)); imagefilledrectangle( $kep, $xPoz, ($yPoz-$cellamagassag), ($xPoz+$cellaszelesseg), $yPoz, $kek ); $doboz = ImageTTFBox( $szovegmeret, 0, $betukeszlet, $kulcs ); $szovszel = $doboz[2]; ImageTTFText( $kep, $szovegmeret, 0, ($kozeppont($szovszel/2)), ($teljesmagassag-$ymargo), $fekete, $betukeszlet, $kulcs ); $xPoz += ( $cellaszelesseg + $oszlopkoz); } imagegif( $kep ); Ezt az imagecreate() fggvnnyel tesszk meg, majd kiosztunk nhny sznt is. jra vgiglpkednk a $cellak tmbn. Kiszmtjuk az oszlop magassgt s az eredmnyt a $cellamagassag-ba helyezzk. Kiszmoljuk a kzppont x koordintjt, amely megegyezik az $xPoz s a fl oszlop szlessgnek sszegvel. Az imagefilledrectangle() fggvnynek az $xPoz, $yPoz, $cellamagassag s $cellaszelesseg vltozkat tadva megrajzoljuk az oszlopot.

277

14

278

14. ra A szveg kzpre igaztshoz megint szksgnk van az imageTTFbox() fggvnyre, amelynek eredmnytmbjt a $doboz vltozban troljuk. A $doboz[2] rtket fogjuk munkaszlessgnek vlasztani, ezt bemsoljuk a $szovszel tmeneti vltozba. Most mr elegend informci ll rendelkezsnkre ahhoz, hogy kirassuk a cmkt. Az x koordinta a $kozeppont vltoz s a szvegszlessg felnek klnbsge lesz, az y koordinta pedig az alakzat magassgnak s a margnak a klnbsge. Megnveljk az $xPoz vltozt, felkszlve ezzel a kvetkez oszlop feldolgozsra. A ciklus vgeztvel megjelentjk az elkszlt kpet. A teljes programot a 14.10. pldban lthatjuk, a vgeredmnyt pedig a 14.10. brn.

14.10. program Egy dinamikus oszlopdiagram


1: <?php 2: header("Content-type: image/gif"); 3: $cellak = array ( "tetszik"=>200, "nem tetszik"=>400, "kzmbs"=>900 ); 4: $max = max( $cellak ); 5: $cellaszam = count( $cellak ); 6: $teljesszelesseg = 300; 7: $teljesmagassag = 200; 8: $xmargo = 20; // jobb s bal marg 9: $ymargo = 20; // fenti s lenti marg 10: $oszlopkoz = 10; // az oszlopok kztti hely 11: $alsokeret = 30; // az bra aljn kimarad hely (a margt nem szmolva) 12: $betukeszlet = "/usr/local/office52/share/fonts/ /TrueType/arial.ttf"; 13: $vaszonszelesseg = ( $teljesszelesseg - $xmargo*2 ); 14: $vaszonmagassag = ( $teljesmagassag - $ymargo*2 - $alsokeret ); 15: $xPoz = $xmargo; // a rajzols kiindulpontja az x tengelyen 16: $yPoz = $teljesmagassag - $ymargo - $alsokeret; // a rajzols kiindulpontja az y tengelyen 17: $cellaszelesseg = (int) (( $vaszonszelesseg ( $oszlopkoz * ( $cellaszam-1 ) )) / $cellaszam) ;

Dinamikus kpek kezelse

279

14.10. program (folytats)


18: $szovegmeret = (int)($alsokeret); 19: // betmret kiigaztsa 20: forach( $cellak as $kulcs => $ertek ) 21: { 22: while ( 1 ) 23: { 24: $doboz = ImageTTFbBox( $szovegmeret, 0, $betukeszlet, $kulcs ); 25: $szovegszelesseg = abs( $doboz[2] ); 26: if ( $szovegszelesseg < $cellaszelesseg ) 27: break; 28: $szovegmeret; 29: } 30: } 31: $kep = imagecreate( $teljesszelesseg, $teljesmagassag ); 32: $piros = ImageColorAllocate($kep, 255, 0, 0); 33: $kek = ImageColorAllocate($kep, 0, 0, 255 ); 34: $fekete = ImageColorAllocate($kep, 0, 0, 0 ); 35: $szurke = ImageColorAllocate($kep, 100, 100, 100 ); 36: 37: forach( $cellak as $kulcs => $ertek ) 38: { 39: $cellamagassag = (int) (($ertek/$max) * $vaszonmagassag); 40: $kozeppont = (int)($xPoz+($cellaszelesseg/2)); 41: imagefilledrectangle( $kep, $xPoz, ($yPoz-$cellamagassag), ($xPoz+$cellaszelesseg), $yPoz, $kek ); 42: $doboz = ImageTTFbBox( $szovegmeret, 0, $betukeszlet, $kulcs ); 43: $szovszel = $doboz[2]; 44: ImageTTFText( $kep, $szovegmeret, 0, ($kozeppont-($szovszel/2)), 45: ($teljesmagassag-$ymargo), $fekete, $betukeszlet, $kulcs ); 46: $xPoz += ( $cellaszelesseg + $oszlopkoz); 47: } 48: imagegif( $kep ); 49: ?>

14

280

14. ra

14.10. bra
Egy dinamikus oszlopdiagram

sszefoglals
A GD programknyvtr PHP-s tmogatsa lehetv teszi, hogy dinamikus oszlopdiagramokat s navigcis elemeket hozhassunk ltre, viszonylag knnyen. Ezen az rn megtanultuk, hogyan hasznljuk az imagecreate() s az imagegif() fggvnyeket kpek ltrehozsra s megjelentsre. Azt is megtanultuk, hogyan szerezznk sznazonostt s hogyan tltsnk ki sznnel terleteket az imagecolorallocate() s az imagefill() fggvnyekkel. Megnztk, hogyan hasznljunk vonal- s alakzat fggvnyeket alakzatok krvonalainak megrajzolsra s kitltsre. Megtanultuk, hogyan hasznljuk a PHP ltal tmogatott FreeType programknyvtrat a TrueType bettpusokkal val munkra, valamint elemeztnk egy programot, amelyben egy alakzatra szveget rtunk s megnztnk egy pldt, amelyben a tanult eljrsokat a gyakorlatban is lthattuk.

Krdsek s vlaszok
Fellpnek-e teljestmnybeli problmk dinamikus kpek hasznlata esetn? Egy dinamikusan ltrehozott kp lassabban tltdik be a bngszbe, mint egy mr ltez fjl. A program hatkonysgtl fggen ezt a felhasznl nem felttlenl veszi szre, de azrt a dinamikus kpeket mdjval hasznljuk.

Dinamikus kpek kezelse

281

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Milyen fejlcsort kell a bngsznek kldennk a GIF kp ltrehozsa s megjelentse eltt? 2. Milyen fggvnyt hasznlnnk egy kpazonost ellltshoz, amelyet a tbbi fggvnynl hasznlhatunk? 3. Milyen fggvnyt hasznlnnk a ltrehozott GIF kp megjelentsre? 4. Milyen fggvny segtsgvel szerezhetjk meg a sznazonostt? 5. Melyik fggvnnyel rajzolnnk vonalat egy dinamikus kpre? 6. Melyik fggvnnyel tltennk ki sznnel egy dinamikus alakzatot? 7. Melyik fggvnyt hasznlhatjuk krv rajzolsra? 8. Hogyan rajzoljunk tglalapot? 9. Hogyan rajzoljunk sokszget? 10. Melyik fggvnnyel rnnk egy dinamikus alakzatra (a FreeType programknyvtr segtsgvel)?

Feladatok
1. rjunk egy programot, amely egy folyamatjelzt hoz ltre, amely mutatja, mennyi pnz folyt be egy gyjts alkalmval az adott clra szksges pnzbl. 2. rjunk egy programot, amely egy fcmet brzol kpet r ki egy bejv rlap vagy lekrdezs adataibl. Tegyk lehetv, hogy a felhasznl hatrozza meg a rajzterletet, az eltr s a httr sznt, valamint az rnyk megltt s annak mrett.

14

15. RA
Dtumok kezelse
A dtumok annyira mindennapjaink rszt kpezik, hogy nem is gondolkodunk, amikor velk dolgozunk, naptrunk fortlyainak helyes kezelse azonban a programokat meglehetsen bonyolultt teheti. Szerencsre a PHP hatkony eszkzket biztost a dtumszmtshoz, amely megknnyti a feladatot. Ebben a fejezetben a kvetkezkrl tanulunk: Hogyan krdezhetjk le a pontos idt s dtumot? Hogyan szerezhetnk informcit egy dtumrl? Hogyan formzzunk meg egy dtumot? Hogyan ellenrizzk a dtumok rvnyessgt? Hogyan lltsuk be a dtumot? Hogyan rjunk egyszer naptrprogramot?

284

15. ra

A dtum kidertse a time() fggvnnyel


A PHP time() fggvnye mindent elrul, amire szksgnk lehet a pontos idvel s dtummal kapcsolatban. A fggvnynek nincs bemenete (paramtere) s egy egsz szmot ad vissza, amely egy kicsit nehezen rtelmezhet, viszont nagyon informatv. A time() ltal visszaadott egsz szm a greenwichi kzpid szerinti 1970. janur 1. jfl ta eltelt msodpercek szmt adja meg. Ez a dtum a UNIX kor kezdete nven ismeretes, az azta eltelt msodpercek szmt pedig idblyegnek (nha idblyegz, time stamp) nevezik. Az idblyeget a PHP eszkzeivel emberi fogyasztsra alkalmasabb formra hozhatjuk, de felmerl a krds: mg ha ilyen nagyszer eszkzk is llnak rendelkezsnkre, az idblyeg nem feleslegesen tlbonyoltott mdja a dtum trolsnak? Nem, ppen ellenkezleg: egyetlen szmbl rengeteg informcit szerezhetnk. s ami mg ennl is jobb, az idblyeggel sokkalta knnyebben lehet szmtsokat vgezni, mint azt gondolnnk. Kpzeljnk csak el egy hzi dtumrendszert, amelyben az veket, hnapokat s a hnapok napjait jegyezzk fel. Most kpzeljnk el egy olyan programot, amellyel egy napot kell hozzadnunk egy adott dtumhoz. Ha ez a dtum ppensggel 1999. december 31., akkor ahelyett, hogy 1-et adnnk a dtumhoz, olyan programot kellene rni, amely a napot 1-re rn t, a hnapot janurra, az vet pedig 2000-re. Az idblyegben viszont csak egy napnyi msodpercet kell hozzadni az aktulis dtumhoz s mr kszen is vagyunk. Ezt az j szmot pedig kedvnk szerint alakthatjuk t valamilyen bartsgosabb formra.

Az idblyeg talaktsa a getdate() fggvnnyel


Most, hogy rendelkezsnkre ll az idblyeg, t kell alaktanunk, mieltt megmutatnnk a felhasznlnak. A getdate() elhagyhat bemenete egy idblyeg, visszatrsi rtke pedig egy asszociatv tmb. Ha nem adjuk meg az idblyeget, a fggvny az ppen aktulis idblyeggel dolgozik, mintha azt a time() fggvnytl kapta volna. A 15.1. tblzat a getdate() ltal visszaadott tmb elemeit rszletezi.

15.1. tblzat A getdate() fggvny ltal visszaadott asszociatv tmb


Kulcs seconds
minutes hours mday

Lers A percbl eltelt msodpercek szma (0-59)


Az rbl eltelt percek szma (0-59) A nap rja (0-23) A hnap napja (1-31)

Plda 28
7 12 20

Dtumok kezelse

285

15.1. tblzat (folytats)


wday mon year yday weekday month 0 A ht napja (0-6) Az v hnapja (1-12) v (ngy szmjeggyel) Az v napja (0-365) A ht napja (nvvel) Az v hnapja (nvvel) Az idblyeg 4 1 2000 19 Thursday January 948370048

A 15.1. programban a getdate() fggvnnyel sztbontjuk az idblyeget, majd a foreach utastssal kirjuk az egyes elemeket. A 15.1. brn a getdate() fggvny egy lehetsges kimenett lthatjuk. A getdate() a helyi idzna szerinti dtumot adja vissza.

15.1. program Dtum lekrdezse a getdate() fggvnnyel


1: <html> 2: <head> 3: <title>15.1. program Dtum lekrdezse a getdate() fggvnnyel</title> 4: </head> 5: <body> 6: <?php 7: $datum_tomb = getdate(); // nem adtunk meg bemenetet, gy a mai dtumot fogja visszaadni 8: foreach ( $datum_tomb as $kulcs => $ertek ) 9: { 10: print "$kulcs = $ertek<br>"; 11: } 12: ?> 13: <hr> 14: <? 15: print "A mai dtum: " $datum_tomb["year"] " " $datum_tomb["mon"] " " $datum_tomb["mday"] <p>"; 16: ?> 17: </body> 18: </html>

15

286

15. ra

15.1. bra
A getdate() fggvny hasznlata

Az idblyeg talaktsa a date() fggvnnyel


A getdate() fggvnyt akkor hasznljuk, amikor a kimenett kpez elemeket szeretnnk hasznlni, a dtumot azonban ltalban szvegknt szeretnnk megjelenteni. A date() fggvny a dtumot formzott karakterlnc formjban adja vissza. A date() fggvny ltal visszaadott rtk formtuma a paramterknt tadhat formz karakterlnccal nagymrtkben befolysolhat. A formz karakterlncon kvl a date() fggvnynek tadhatjuk az idblyeget is, br ez nem ktelez. A 15.2. tblzatban lthatjuk azokat a kdokat, amelyeket a formz karakterlnc tartalmazhat. A date() fggvnynek tadott formzban tallhat minden egyb szveg a visszaadott rtkben vltozatlanul meg fog jelenni.

15.2. tblzat A date() ltal hasznlt formzsi kdok.


Formtum a
A d D F h H g G

Lers am (dleltt) vagy pm (dlutn), kisbetvel


AM (dleltt) vagy PM (dlutn), nagybetvel A hnap napja (bevezet nullkkal rt szm) A ht napja (hrom betvel) A hnap neve ra (12 rs formtum, bevezet nullkkal) ra (24 rs formtum, bevezet nullkkal) 05 ra (12 rs formtum, bevezet nullk nlkl) ra (24 rs formtum, bevezet nullk nlkl)

Plda pm
PM 05 Thu January 03 3 5

Dtumok kezelse

287

15.2. tblzat (folytats)


Formtum i
j l L m M n s U y Y z Z

Lers Perc
A hnap napja (bevezet nullk nlkl) A ht napja (nvvel) Szkv (1 ha igen, 0 ha nem) Az v hnapja (szmmal, bevezet nullkkal) Az v hnapja (hrom betvel) Az v hnapja (szmmal, bevezet nullk nlkl) 1 Az ra percei Idblyeg v (kt szmjegy) v (ngy szmjegy) Az v napja (0-365) A greenwichi kzpidtl val eltrs msodpercben

Plda 47
5 Thursday 1 01 Jan 24 948372444 00 2000 19 0

A 15.2. program nhny formtumkdot mutat be.

15.2. program Dtum formzsa a date() fggvnnyel


1: <html> 2: <head> 3: <title>15.2. program Dtum formzsa a date() fggvnnyel</title> 4: </head> 5: <body> 6: <?php 7: print date("Y.m.d. H:i:s<br>", time()); 8: // 2000.12.10. 14:42:55 9: 10: $de_du = Array ("am" => "dleltt", "pm" => "dlutn"); 11: $honapok = Array("janur", "februr", "mrcius", "prilis", 12: "mjus", "jnius", "jlius", "augusztus", "szeptember", 13: "oktber", "november", "december");

15

288

15. ra

15.2. program (folytats)


14: 15: $napszak = $de_du[date("a")]; 16: $honap = $honapok[date("n")-1]; 17: 18: print " Ma " . date("Y ") . $honap . date(" j. \\n\ap\j\a v\a\\n, " ); 19: print $napszak . date(" g r\a i perc"); 20: // Ma 2000 december tizedike van, dlutn 2 ra 42 perc. 21: ?> 22: </body> 23: </html>

A magyar dtumok formzsa ktsgtelenl bonyolultabb, mint a belsleg tmogatott angol dtumformtumok, ezrt ltre kell hoznunk egy tmbt, amely a dleltt s dlutn szavakat tartalmazza, valamint egy msik tmbt a hnapok nevei szmra. A $napszak egyszeren a date() fggvny "a" formtumra adott kimenetbl szrmaztathat, a $honap-hoz pedig a tmb date("n")-1-edik elemt kell vennnk, mivel a tmbk nulltl szmozdnak. Br a formzs bonyolultnak tnik, nagyon knny elvgezni. Ha olyan szveget szeretnnk a formzshoz adni, amely formtumkd-betket tartalmaz, a fordtott perjel (\) karakterrel jelezhetjk, hogy az utna jv karakter nem formtumkd. Azon karakterek esetben, amelyek a \ utn vlnak vezrlkarakterr, ezt a \ el tett jabb \ segtsgvel kell jeleznnk. A "\n"-t pldul ennek megfelelen "\\n"-nek kell rnunk, ha egy n-t szeretnnk a formzsi karaktersorozatba rni. A fenti pldban a formtumkarakterek tkzst elkerlend vettk kln a $honap s $napszak kirst, hogy a date() fggvny ne tekintse ezek karaktereit rtelmezend formtum-meghatrozsoknak. A date() fggvny a helyi idzna szerint adja vissza a dtumot. Ha azt szeretnnk, hogy greenwichi kzpid (Greenwich Mean Time, GMT) szerint kapjuk meg, hasznljuk a gmdate() fggvnyt, amely egybknt minden ms tekintetben ugyangy mkdik.

Idblyeg ksztse az mktime() fggvnnyel


Mr kpesek vagyunk az aktulis dtumot hasznlni, de tetszleges dtumokat mg nem tudunk kezelni. Az mktime() fggvny ltal visszaadott idblyeget a date() vagy a getdate() fggvnyekkel hasznlhatjuk. Az mktime() fggvny bemenete hat egsz szm, a kvetkez sorrendben:

Dtumok kezelse ra perc msodperc hnap hnap napja v A 15.3. program az mktime() fggvnnyel llt el idblyeget, amit aztn a date() fggvnnyel hasznl.

289

15.3. program Idblyeg ksztse az mktime() fggvnnyel


1: <html> 2: <head> 3: <title>15.3. program Idblyeg ksztse az mktime() fggvnnyel </title> 4: </head> 5: <body> 6: <?php 7: // idblyeget kszt 1999. 05. 01. 12 ra 30 perchez 8: $ido = mktime( 12, 30, 0, 5, 1, 1999 ); 9: print date("Y.m.d. H:i:s<br>", $ido); 10: // 1999.05.01. 12:30:00 11: ?> 12: </body> 13: </html>

Az mktime() fggvny nhny vagy akr az sszes eleme elhagyhat, ilyenkor az aktulis idnek megfelel rtkeket hasznlja. Az mktime() emellett azokat az rtkeket is kiigaztja, amelyek tl vannak a megfelel rtktartomnyon, gy ha 25-t adunk meg ra paramterknt, akkor a meghatrozott nap, hnap, v paramterek utni nap reggeli 1.00-knt fogja kezelni azt. Az mktime() fggvny kimenete ltalban adatbzisban vagy fjlban val trolshoz, illetve dtumszmtsokhoz lehet hasznos.

15

A dtum ellenrzse a checkdate() fggvnnyel


Elfordulhat, hogy a felhasznl ltal bevitt dtummal kell dolgoznunk. Mieltt nekikezdennk a munknak vagy trolnnk a dtumot, meg kell bizonyosodnunk rla, hogy az rvnyes-e. A checkdate() fggvny hrom egsz szmot, a hnapot, a napot, s az vet kri paramterknt (ebben a sorrendben) s true (igaz) rtket ad vissza, ha a hnap 1 s 12 kzt van, a nap elfogadhat az adott

290

15. ra hnapban s vben (szmtsba vve a szkveket) s az v 0 s 32 767 kz esik. Vigyzzunk azonban, mert elfordulhat, hogy egy dtum ugyan rvnyes, de ms dtumfggvnyek szmra mgsem elfogadhat. Pldul a kvetkez sor true (igaz) rtket ad vissza: checkdate( 4, 4, 1066 ) Viszont ha ezekkel az rtkekkel egy dtumot szeretnnk ltrehozni, az mktime() ltal visszaadott idblyeg 1 lenne. ltalnos szablyknt fogadjuk el, hogy az 1902 eltti vekre nem hasznljuk az mktime() fggvnyt s az 1970 elttiekre is csak elvigyzatosan.

Egy plda
Prbljunk meg ezen fggvnyek kzl egyetlen pldn bell minl tbbet hasznlni. Ksztsnk naptrat, amely egy 1980 s 2010 kztti tetszleges hnap napjait mutatja. A felhasznl lenyl menvel vlaszthatja ki a hnapot s az vet. A program kimenetben az adott hnap dtumai a ht napjainak megfelelen kerlnek elrendezsre. Kt globlis vltozt hasznlunk, a $honap s az $ev vltozkat, melyek adatait a felhasznl adja meg. A kt vltoz segtsgvel elksztjk a meghatrozott hnap els napjnak idblyegt. Ha nem adtuk meg az vet vagy a hnapot, vagy megadtuk, de a bevitt adat nem rvnyes, a program bemenetnek alapbelltsknt a foly v aktulis hnapjnak els napjt tekintjk.

A felhasznl ltal bevitt adatok ellenrzse


Amikor egy felhasznl elszr ltogat el weboldalunkra, valsznleg nem fogja megadni a bekrt adatokat. Erre az isset() fggvny segtsgvel kszthetjk fel programunkat. Ez a fggvny a false (hamis) rtket adja vissza, ha a neki tadott vltoz nem meghatrozott. (Hasznlhatjuk helyette a checkdate() fggvnyt is.) A 15.4. plda azt a kdrszletet tartalmazza, amely ellenrzi a $honap s az $ev vltozkat s egy idblyeget hoz ltre bellk.

15.4. program A felhasznl ltal bevitt adatok ellenrzse a naptrprogram szmra


1: <?php 2: if ( ! checkdate( $honap, 1, $ev ) ) 3: { 4: $mostTomb = getdate(); 5: $honap = $mostTomb["mon"]; 6: $ev = $mostTomb["year"]; 7: }

Dtumok kezelse

291

15.4. program (folytats)


8: $kezdet = mktime ( 0, 0, 0, $honap, 1, $ev ); 9: $elsoNapTombje = getdate($kezdet); 10: if ($elsoNapTombje["wday"] == 0) { $elsoNapTombje["wday"] = 6; } 11: else { $elsoNapTombje["wday"]--; } 12: ?>

A 15.4. program egy nagyobb program rszlete, gy nmagban nincs kimenete. Az if utastsban a checkdate() fggvnyt hasznljuk a $honap s az $ev vltozk ellenrzsre. Ha ezek nem meghatrozottak, a checkdate() false (hamis) rtket ad vissza, mivel nem hozhatunk ltre rvnyes dtumot meghatrozatlan hnap s v paramterekbl. E megkzelts tovbbi haszna, hogy egyttal a felhasznl ltal bevitt adat rvnyessgt is ellenrizzk. Ha a dtum nem rvnyes, a getdate() fggvnnyel ltrehozunk egy, az aktulis dtumon alapul asszociatv tmbt. Ezutn a tmb mon s year elemeivel magunk lltjuk be a $honap s az $ev vltozk rtkeit. Most hogy megbizonyosodtunk, hogy a program bemenett kpez kt vltoz rvnyes adatot tartalmaz, az mktime() fggvnyt hasznljuk a hnap els napja idblyegnek ltrehozsra. A ksbbiek sorn mg szksgnk lesz ennek az idblyegnek a napjra s hnapjra, ezrt ltrehozunk egy $elsoNapTombje nev vltozt, amely a getdate() fggvny ltal visszaadott s ezen az idblyegen alapul asszociatv tmb lesz. Vgl a magyar hthasznlatnak megfelelen t kell alaktanunk a ht napjra vonatkoz rtket. A getdate() s ms dtumfggvnyek a ht els napjnak a vasrnapot tekintik. Ezrt ha a ht els napjn vagyunk (ez kapja a nulls szmot), akkor hetedikre rjuk t, egybknt pedig a nap szmt eggyel cskkentjk. gy a vasrnap a ht vgre kerl, a tbbi nap pedig eggyel elrbb, azaz a htf az els helyen szerepel.

A HTML rlap ltrehozsa


Olyan kezelfelletet kell ltrehoznunk, amellyel a felhasznlk lekrdezhetik egy hnap s v adatait. Ennek rdekben SELECT elemeket fogunk hasznlni. Br ezeket mdosthatatlan elemekknt, a HTML kdban is megadhatnnk, azt is biztostanunk kell, hogy a lenyl menk alapbelltsa az adott hnap legyen, ezrt a menket dinamikusan hozzuk ltre s csak ott adjuk hozz a SELECTED tulajdonsgot az OPTION elemhez, ahol szksges. A 15.5. programban a ltrehozott rlapot lthatjuk.

15

292

15. ra

15.5. program A naptrprogram HTML rlapja


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: <?php if ( ! checkdate( $honap, 1, $ev ) ) { $mostTomb = getdate(); $honap = $mostTomb["mon"]; $ev = $mostTomb["year"]; } $kezdet = mktime ( 0, 0, 0, $honap, 1, $ev ); $elsoNapTombje = getdate($kezdet); if ($elsoNapTombje["wday"] == 0) { $elsoNapTombje["wday"] = 6; } else { $elsoNapTombje["wday"]--; } ?> <html> <head> <title><?php print "Naptr:" $elsoNapTombje["year"] $elsoNapTombje["month"] ?></title> <head> <body> <form method="post"> <select name="honap"> <?php $honapok = Array ("janur", "februr", "mrcius", "prilis", "mjus", "jnius", "jlius", "augusztus", "szeptember", "oktber", "november", "december"); for ( $x=1; $x <= count( $honapok ); $x++ ) { print "\t<option value=\"$x\""; print ($x == $honap)?" SELECTED":""; print ">".$honapok[$x-1]."\n"; } ?> </select> <select name="ev"> <?php for ( $x=1980; $x<2010; $x++ ) { print "\t<option"; print ($x == $ev)?" SELECTED":"";

Dtumok kezelse

293

15.5. program (folytats)


39: 40: 41: 42: 43: 44: 45: 46: ?> </select> <input type="submit" value="Megjelents!"> </form> </body> </html> print ">$x\n"; }

Miutn ltrehoztuk a $kezdet idblyeget s az $elsoNapTombje vltozt, megrjuk az oldal HTML kdjt. Vegyk szre, hogy az $elsoNapTombje vltozt arra hasznljuk, hogy az vet s a hnapot a TITLE (cm) elemhez adhassuk. Az elz pldkban a FORM elemen belli $PHP_SELF globlis vltozt hasznltuk arra, hogy biztostsuk, az rlap az elklds utn jra megjelenti magt, e programban viszont azt a tnyt hasznltuk ki, hogy ha egy FORM kdbl kihagyjuk az ACTION paramtert, alapbellts szerint ugyanez trtnik. A lenyl menk SELECT elemnek ltrehozshoz visszalpnk PHP mdba, hogy ltrehozzuk az egyes OPTION cmkket. Elszr ltrehozunk egy $honapok nev tmbt, amely a 12 hnap nevt tartalmazza. Ezen aztn vgiglpkednk egy ciklussal, mindegyikbl ksztve egy OPTION cmkt. Ez az egyszer SELECT elem ltrehozsnak tlbonyoltott mdja lenne, ha nem kellene kzben figyelnnk az $x vltozt (a for ciklusvltozjt). Ha az $x s a $honap megegyezik, a SELECTED kifejezst hozzadjuk az OPTION cmkhez, biztostvn ezzel, hogy a megfelel hnap automatikusan kijelldik a lap betltsekor. Hasonl mdszerrel rjuk meg az v menjt is, vgl HTML mdba visszatrve ltrehozzuk a Megjelents gombot. gy egy olyan rlapot kapunk, amely sajt magnak elkldi a hnap s v paramtereket, s amelynek vagy az aktulis v s hnap, vagy pedig az elzleg megadott v s hnap az alapbelltsa. A ksz rlapot a 15.2. brn lthatjuk.

15

294

15. ra

15.2. bra
A naptr rlapja

A naptr tblzatnak ltrehozsa


Most egy tblzatot kell ltrehoznunk, amit a kivlasztott hnap napjaival kell feltltennk. Ezt a 15.6. pldban kvethetjk nyomon, amely a teljes naptrprogramot tartalmazza.

15.6. program A teljes naptrprogram


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: <?php define("EGYNAP", (60*60*24) ); if ( ! checkdate( $honap, 1, $ev ) ) { $mostTomb = getdate(); $honap = $mostTomb["mon"]; $ev = $mostTomb["year"]; } $kezdet = mktime ( 0, 0, 0, $honap, 1, $ev ); $elsoNapTombje = getdate($kezdet); if ($elsoNapTombje["wday"] == 0) { $elsoNapTombje["wday"] = 6; } else { $elsoNapTombje["wday"]--; } ?> <html> <head> <title><?php print "Naptr:" $elsoNapTombje["year"] $elsoNapTombje["month"] ?></title> <head> <body>

Dtumok kezelse

295

15.6. program (folytats)


20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: <form method="post"> <select name="honap"> <?php $honapok = Array ("janur", "februr", "mrcius", "prilis", "mjus", "jnius", "jlius", "augusztus", "szeptember", "oktber", "november", "december"); for ( $x=1; $x <= count( $honapok ); $x++ ) { print "\t<option value=\"$x\""; print ($x == $honap)?" SELECTED":""; print ">".$honapok[$x-1]."\n"; } ?> </select> <select name="ev"> <?php for ( $x=1980; $x<2010; $x++ ) { print "\t<option"; print ($x == $ev)?" SELECTED":""; print ">$x\n"; } ?> </select> <input type="submit" value="Megjelents!"> </form> <p> <?php $napok = Array ("htf", "kedd", "szerda", "cstrtk, "pntek", "szombat", "vasrnap"); print "<TABLE BORDER=1 CELLPADDING=5>\n"; foreach ( $napok as $nap ) print "\t<td><b>$nap</b></td>\n"; $kiirando = $kezdet; for ( $szamlalo=0; $szamlalo < (6*7); $szamlalo++ ) { $napTomb = getdate( $kiirando );

15

296

15. ra

15.6. program (folytats)


57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: if ( (($szamlalo) % 7) == 0 ) { if ( $napTomb["mon"] != $honap ) break; print "</tr><tr>\n"; } if ( $szamlalo < $elsoNapTombje["wday"] || $napTomb["mon"] != $honap ) { print "\t<td><br></td>\n"; } else { print "\t<td>" . $honapok[$napTomb["mon"]-1] " $napTomb["mday"] "</td>\n"; $kiirando += EGYNAP; } } print "</tr></table>"; ?> </body> </html>

Mivel a tblzat fejlcbe a ht napjai kell, hogy kerljenek, a programot vgiglptetjk a napok neveinek tmbjn s mindegyiket sajt celljba rjuk. A lnyeg a program utols for ciklusban trtnik. Megadjuk a $szamlalo vltoz kezdeti rtkt, majd biztostjuk, hogy a ciklus 42 ismtls utn lell. Erre azrt van szksg, hogy a dtumoknak elegend cellt hozzunk ltre. A ciklusban a $kiirando vltozt a getdate() fggvnnyel egy dtumtmbb alaktjuk s az eredmnyt a $napTomb vltozba tesszk. Br a ciklus indtsakor a $kiirando vltoz rtke a hnap els napja lesz, az idblyeget a ciklus minden lefutsakor 24 rval nveljk. A maradkos oszts segtsgvel megnzzk, hogy a $szamlalo vltoz rtke oszthat-e 7-tel. Az ehhez az if utastshoz tartoz kdrsz csak akkor fut le, ha a $szamlalo 0 vagy a 7 tbbszrse. gy eldnthetjk, hogy befejezzk-e a ciklust vagy j sort kezdjnk.

Dtumok kezelse Ha ltjuk, hogy mg a ciklus els lefutsban vagy egy cellasor vgnl vagyunk, elvgznk mg egy ellenrzst: megvizsgljuk, hogy a $napTomb mon (hnapszm) eleme nem egyenl-e a $honap vltozval. Ha nem egyenl, a ciklust befejezhetjk. Emlkezznk vissza, hogy a $napTomb-ben ugyanaz az idpont van, mint ami a $kezdet-ben, ami viszont a hnapnak pontosan az a rsze, amelyet megjelentnk. Ha a $kezdet tljut az aktulis hnapon, a $napTomb[mon] ms szmot fog tartalmazni, mint a felhasznl ltal megadott $honap szm. A maradkoszts igazolta, hogy ppen egy sor vgn llunk: ha j hnapban jrunk, elhagyhatjuk a ciklust, ha viszont a sor vgre rtnk s mg mindig ugyanabban a hnapban vagyunk, befejezzk a sort s jat kezdnk. A kvetkez if utastsban azt hatrozzuk meg, hogy rjunk-e szveget a cellba. Nem minden hnap kezddik htfvel, gy knnyen meglehet, hogy egy-kt res cellval indtunk. Emellett kevs hnap vgzdik sor vgn, gy az is valszn, hogy mieltt lezrnnk a tblzatot, egy pr res cellt is kell rnunk. A hnap els napjnak adatait az $elsoNapTombje vltozban talljuk. Ebbl az $elsoNapTombje["wday"] kifejezs segtsgvel kiderthet, hogy az adott dtum hnyadik nap a hten. Ha a $szamlalo kisebb, mint ez a szm, akkor tudjuk, hogy mg nem rtk el azt a cellt, amelybe mr rhatnnk. Ugyanezt felhasznlva ha a $honap vltoz mr nem egyenl a $napTomb["mon"] vltozval, tudhatjuk, hogy elrtk a hnap vgt (de a sor vgt mg nem). Mindkt esetben egy res cellt runk ki a bngszbe. A vgs else utastsnl jn a feladat rdekes rsze. Azzal mr tisztban vagyunk, hogy a kirand hnapban vagyunk s az aktulis nap oszlopa megegyezik az $elsoNapTombje vltozban trolt szmmal. Most kerl felhasznlsra a ciklus korbbi rszben ltrehozott $napTomb asszociatv tmb, valamint a hnapok magyar neveit tartalmaz $honapok tmb, hogy kirjuk a hnap nevt s napjt egy cellba. Vgl nveljk a $kiirando vltozt, amely az idblyeget tartalmazza. Egyszeren hozzadjuk egy nap msodperceinek szmt (ezt az rtket a program elejn hatroztuk meg) s mr jra is kezdhetjk a ciklust a $kiirando vltoz egy j rtkvel. A 15.3. brn a program egy lehetsges eredmnyt lthatjuk.

297

15

298

15. ra

15.3. bra
A naptrprogram

sszefoglals
Ezen az rn megtanultuk, hogyan hasznljuk a time() fggvnyt az aktulis idblyeg megszerzsre. Megtanultuk, hogyan hasznljuk az idblyegbl a dtum rszeinek kinyersre a getdate() fggvnyt s az idblyeget formzott szvegg alakt date() fggvnyt. Arrl is tanultunk, hogyan hozzunk ltre idblyeget az mktime() fggvnnyel. Megtanultuk ellenrizni a dtum rvnyessgt a checkdate() fggvnnyel, magyar elvrsok szerint formztunk dtumokat, vgl tanulmnyoztunk egy pldaprogramot, amely az emltett fggvnyeket alkalmazta.

Krdsek s vlaszok
Vannak olyan fggvnyek, amelyekkel a klnbz naptrak kztt vltogatni lehet? Igen, a PHP naptrak teljes sorozatt biztostja. Ezekrl a hivatalos PHP kziknyvben olvashatunk, a http://www.php.net/manual/ref.calendar.php cmen.

Dtumok kezelse

299

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Hogyan kapunk meg egy UNIX idblyeget, amely a pontos dtumot s idt jelli? 2. Melyik az a fggvny, amelynek bemenete egy idblyeg s egy, az adott dtumot jelkpez asszociatv tmbt ad vissza? 3. Mely fggvnyt hasznlnnk a dtum formzsra? 4. Hogyan kapjuk meg egy tetszleges dtum idblyegt? 5. Melyik fggvnyt hasznljuk egy dtum rvnyessgnek ellenrzsre?

Feladatok
1. Ksztsnk egy szletsnapig visszaszmll programot. rlappal lehessen megadni az v, h s nap rtkeit, kimenete pedig egy zenet legyen, amely kzli a felhasznlval, hogy hny nap, ra, perc, msodperc van mg htra a nagy napig.

15

16. RA
Az adatok kezelse
Ezen az rn az adatellenrzsben s az adatmveletekben fogunk egy kicsit elmlyedni. jra ttekintjk az adattpusokat. A PHP ugyan automatikusan kezeli ezeket, de elengedhetetlen, hogy rtsk az adatkezelst, ha nagy, megbzhat hlzati alkalmazsokat kell rnunk. Visszatrnk a tmbkhz is s vgl megismerkednk a PHP fejlettebb adatkezelsi, adatosztlyozsi eljrsaival. Az ra folyamn a kvetkezkrl tanulunk: Hogyan alaktsuk t az egyes adattpusokat ms adattpusokk? Hogyan alaktja t automatikusan a PHP az adattpusokat a kifejezsekben? Milyen tovbbi mdjai vannak az adattpusok ellenrzsnek? Mirt fontos megrtennk az adattpusokat? Hogyan ellenrizzk, hogy egy vltoznak van-e rtke? Hogyan lehet msknt bejrni egy tmbt? Hogyan derthetjk ki, hogy egy tmb tartalmaz-e egy bizonyos elemet? Hogyan alaktsuk t egy tmb minden elemt? Hogyan lehet sajt szempontok alapjn tmbrendezst vgezni?

302

16. ra

jra az adattpusokrl
A negyedik rban mr tanultunk nhny dolgot a PHP adattpusairl. Van azonban mg valami, ami eddig kimaradt. Ebben a rszben a vltozk adattpusnak ellenrzsre hasznlt fggvnyek kzl ismerkednk meg nhnnyal, majd sorra vesszk azokat a feltteleket, amelyek mellett a PHP automatikusan elvgzi helyettnk az adattpus-talaktsokat.

Egy kis ismtls


Azt mr tudjuk, hogy a PHP vltozinak rtke egsz szm (integer), lebegpontos szm (double), karakterlnc (string), logikai rtk (boolean), objektum vagy tmb lehet. A gettype() fggvnnyel brmelyik vltoztpust lekrdezhetjk. A fggvny bemenete egy tetszleges tpus vltoz, kimenete pedig a vltoz adattpust ler szveg: $adat = 454; print gettype( $adat ); // azt rja ki, hogy "integer", azaz egsz szm A vltozk adattpust kzvetlen tpustalaktssal vagy a settype() fggvnnyel mdosthatjuk. Az adattpusok talaktshoz a zrjelbe tett adattpust a megvltoztatand vltoz vagy rtk el rjuk. A folyamat kzben a vltoz tartalmt a legcseklyebb mrtkben sem mdostjuk, ehelyett egy talaktott msolatot kapunk vissza. A kvetkez kdrszlet egy tizedestrtet alakt t egsz szmm. $adat = 4.333; print ( integer ) $adat; // "4"-et r ki Az $adat vltoz lebegpontos szm tpus maradt, mi csupn a tpustalakts eredmnyt rattuk ki. A vltozk adattpusnak mdostshoz a settype() fggvnyt hasznlhatjuk, amelynek bemenete az talaktand vltoz s a cladattpus neve. $adat = 4.333; settype( $adat, "integer" ); print $adat; // "4"-et r ki Az $adat vltoz most mr egy egsz szmot tartalmaz.

Az adatok kezelse

303

sszetett adattpusok talaktsa


Nhny egyszer (skalris s szveges) adattpus kztti tvltst mr lttuk rszleteiben is. Mi trtnik viszont akkor, ha egyszer (egsz s nem egsz szmok) s sszetett adattpusok (objektumok s tmbk) kztt kell tpust vltani? Amikor egy egyszer adattpust tmbb alaktunk, olyan tmb jn ltre, melynek els eleme az eredeti rtk lesz: $szoveg = "ez az n szvegem" $tomb_szoveg = (array) $szoveg; print $tomb_szoveg[0]; // kirja az "ez az n szvegem" karakterlncot Amikor a skalris vagy szveges vltozkat objektumokk alaktjuk, egy egyetlen scalar nev tulajdonsgot tartalmaz objektum jn ltre, ez tartalmazza az eredeti rtket: $szoveg = "ez az n szvegem" $obj_szoveg = (object) $szoveg; print $obj_szoveg->scalar; // kirja az "ez az n szvegem" karakterlncot A dolog a tmbk s objektumok kztti vltskor vlik igazn izgalmass. Amikor egy tmbt objektumm alaktunk, egy olyan j objektum jn ltre, amelyben a tmb egyes kulcsainak egy-egy tulajdonsg felel meg. $cimek = array ( "utca" => "Futca", "varos" => "Nagyfalva" ); $obj_cimek = ( object ) $cimek; print $obj_cimek->utca; // azt rja ki, hogy "Futca" Fordtott esetben, egy objektum tmbb alaktsakor, olyan tmb jn ltre, amelyben minden objektum tulajdonsgnak megfelel egy tmbelem. A metdusokat az talakts figyelmen kvl hagyja. class Pont { var $x; var $y; function Pont( $x, $y ) { $this->x = $x; $this->y = $y;

16

304

16. ra } } $pont = new Pont( 5, 7 ); $tomb_pont = (array) $pont; print $tomb_pont["x"]; // azt rja ki, hogy "5"

Az adattpusok automatikus talaktsa


Ha olyan kifejezst hozunk ltre, amelyben kt klnbz adattpus szerepel operandusknt, a PHP automatikusan talaktja az egyiket a szmthatsg kedvrt. Valsznleg ezt mr ignybe vettk, anlkl, hogy tudtunk volna rla. Az rlapokbl szrmaz vltozk mindig karakterlncok, de ezeket hasznlhattuk igazhamis rtk kifejezsekben is vagy szmolsoknl, ha ppen arra volt szksgnk. Tegyk fel, hogy egy felhasznlt megkrdeznk, hny rt tlt a hlzaton hetente, s a vlaszt az $orak nev vltozban troljuk. Ez kezdetben szvegknt kerl trolsra. $orak = "15" if ($orak > 15) print "Ilyen gyakori felhasznlnak akr rengedmny is jrhatna"; Az $orak ellenrzsekor a "15" karakterlnc egsz szmm alakul, gy a kifejezs eredmnye true (igaz) lesz. Az automatikus talakts szablyai viszonylag egyszerek. Egsz szmokbl vagy lebegpontosakbl ll krnyezetben a karakterlncok tartalmuknak megfelelen kerlnek talaktsra. Ha egy karakterlnc egsz szmmal kezddik, a szm az annak megfelel rtk. gy a kvetkez kifejezs eredmnye 80: 4 * "20mb" Ha a karakterlnc nem szmmal kezddik, 0-v alakul. gy a kvetkez sor 0-t ad eredmnyl: 4 * "krlbell 20mb" Ha a karakterlncban a szmot egy pont kveti, akkor az lebegpontos rtkk alakul. Ennek megfelelen a kvetkez sor eredmnye 4,8 lesz: 4 * "1.2"

Az adatok kezelse Az ++ s -- mveletek karakterlncokra val alkalmazsa klnleges eset. A karakterlnc nvelse, mint ahogy azt elvrtuk, 1-et ad a karakterlnc talaktott rtkhez, de csak abban az esetben, ha a karakterlnc kizrlag szmokbl ll. Maga az j rtk azonban karakterlnc marad: $szoveg = "4"; $szoveg++; print $szoveg; // kirja az 5-t print gettype( $szoveg ); // azt rja ki, hogy "string" Ha egy betket tartalmaz karakterlncot prblunk nvelni, egyedl az utols karakter kdja fog megnni: $szoveg = "alszol"; $szoveg++; print $szoveg; // azt rja ki, hogy "alszom" Vessk ssze ezt a karakterlnc nvelsnek egy msik megkzeltsvel: $szoveg = "alszol"; $szoveg += 1; print $szoveg; // 1-et r ki print gettype( $szoveg ); // azt rja ki, hogy "integer", azaz egsz szm Az elz pldban a $szoveg vltoz elszr 0-v (egsz szmm) alakul, aztn adjuk hozz az 1-et. Ennek a mveletnek az eredmnye 1, amelyet jra a $szoveg vltozba helyeznk. A vltoz most mr egy egsz szmot fog tartalmazni. Az egsz szmok s a lebegpontosak kztti automatikus tvlts mg ennl is egyszerbb. Ha egy kifejezs brmelyik operandusa lebegpontos, a PHP a msik operandust is lebegpontoss alaktja s az eredmny is lebegpontos lesz: $eredmeny = ( 1 + 20.0); print gettype( $eredmeny ); // azt rja ki, hogy "double", azaz lebegpontos Fontos megjegyeznnk, hogy ha az automatikus talakts egy kifejezs kirtkelshez szksges, a kifejezs egyik operandusa sem vltozik meg. Ha egy operandust t kell alaktani, akkor annak talaktott msolata fog szerepelni a kifejezs rszeknt.

305

16

306

16. ra

Az adattpusok ellenrzse
Mr le tudunk krdezni adattpusokat a gettype() fggvnnyel, ami a hibakeressnl jl jhet, hiszen minden vltozrl meg tudjuk mondani, hogy milyen tpus. Gyakran viszont csak azt szeretnnk megnzni, hogy a vltoz egy bizonyos adattpus rtket tartalmaz-e. A PHP ehhez az egyes adattpusoknak megfelel fggvnyeket biztost, amelyek bemenete egy vltoz vagy egy rtk, visszatrsi rtke pedig logikai. A fggvnyek listjt a 16.1. tblzat tartalmazza.

16.1. tblzat Az adattpusok ellenrzsnek fggvnyei


Fggvny is_array()
is_bool() is_double() is_int() is_object() is_string()

Lers Igaz (true) rtket ad vissza, ha a paramter tmb


Igaz (true) rtket ad vissza, ha a paramter logikai rtk Igaz (true) rtket ad vissza, ha a paramter lebegpontos szm Igaz (true) rtket ad vissza, ha a paramter egsz szm Igaz (true) rtket ad vissza, ha a paramter objektum Igaz (true) rtket ad vissza, ha a paramter karakterlnc

Ezek a fggvnyek egy kicsit megknnytik az adattpusok ellenrzst. Az if ( gettype( $valtozo ) == "array" ) print "ez egy tmb"; megegyezik a if ( is_array( $valtozo ) ) print "ez egy tmb"; kddal. (A $valtozo ellenrzsnek msodik mdja egy kicsit tmrebb.)

Az adattpus-vlts tovbbi mdjai


Eddig az adattpus-vlts kt mdjval ismerkedtnk meg: vagy egy rtket alaktunk t meghatrozott adattpuss, vagy a settype() fggvnyt hasznljuk. Ezek mellett a PHP bizonyos fggvnyekkel lehetv teszi, hogy rtkeket egsz szmm, lebegpontos szmm vagy szvegg alaktsunk t. E fggvnyek bemenete tmbn s objektumon kvl brmilyen adattpus lehet, kimenetk pedig az talaktott rtk. Lersukat a 16.2. tblzatban tallhatjuk meg.

Az adatok kezelse

307

16.2. tblzat Az adattpus-vlts fggvnyei


Fggvny Lers doubleval() Bemenete egy rtk, kimenete egy azonos rtk lebegpontos szm
intval() strval() Bemenete egy rtk, kimenete egy azonos rtk egsz szm Bemenete egy rtk, kimenete egy azonos rtk karakterlnc

Mirt olyan fontosak az adattpusok?


A PHP nem kveteli meg tlnk, hogy egy vltoz ltrehozsakor megadjuk annak adattpust, de elvgzi az adattpus talaktsokat helyettnk, ha a kifejezsekben klnbz adattpus vltozkat hasznlunk. Ha a PHP ennyire leegyszersti az letnket, akkor mirt van szksgnk mgis az adattpusok nyomon kvetsre? Azrt, hogy megelzhessk a hibkat. Kpzeljnk el egy olyan fggvnyt, amely egy tmb kulcsait s rtkeit rja ki egy bngszbe. A PHP-ben a fggvnyparamterek tpust sem adhatjuk meg, gy nem rhatjuk el, hogy a meghv kd egy tmbt adjon t neknk, amikor a fggvnyt meghatrozzuk. function tombKiir( $tomb ) { foreach ( $tomb as $kulcs => $ertek ) print "$kulcs: $ertek<P>"; } A kvetkez fggvny jl mkdik, ha tmb paramterrel hvjk meg. tombKiir ( array(4, 4, 55) ); Ha figyelmetlensgnkben skalris paramtert adunk t neki, az hibhoz vezet, amint azt a kvetkez plda is mutatja: tombKiir ( 4 ); // Warning: Non array argument supplied for foreach() in // /home/httpd/htdocs/proba2.php on line 5 // azaz "Figyelmeztets: a foreach() fggvnynek nem tmb paramtert adtunk t // a /home/httpd/htdocs/proba2.php program 5. sorban"

16

308

16. ra Azzal, hogy ellenrizzk a kapott paramter adattpust, sokkal alkalmazkodbb tesszk a fggvnyt. Azt is megtehetjk, hogy a fggvny szp csndben visszatr, ha skalris rtket kap: function tombKiir( $tomb ) { if ( ! is_array( $tomb )) return false; foreach ( $tomb as $kulcs => $ertek ) print "$kulcs: $ertek<P>"; return true; } Most mr a hv kd ellenrizheti a fggvny visszaadott rtkeit, hogy megllapthassa, vgre tudta-e hajtani feladatt. Adattalaktst is hasznlhatunk, hogy a skalris adatot tmbknt hasznlhassuk fel: function tombKiir( $tomb ) { if ( ! is_array( $tomb )) $tomb = (array) $tomb; foreach ( $tomb as $kulcs => $ertek ) print "$kulcs: $ertek<P>"; return true; } A tombKiir() fggvny nagyon rugalmass vlt, most mr tetszleges adattpust kpes feldolgozni, akr objektumot is. Az adattpus ellenrzse akkor is jl jhet, ha a fggvnyek visszaadott rtkeit szeretnnk ellenrizni. Nhny nyelv, pldul a Java, minden metdusa mindig egy elre meghatrozott adattpust ad vissza. A PHP-nak nincsenek ilyen megktsei, viszont az ilyen rugalmassg alkalmanknt ktrtelmsgekhez vezethet. Erre lttunk egy pldt a tizedik rban. A readdir() fggvny hamis (false) rtket ad vissza, amikor elri a beolvasott knyvtr vgt, minden ms esetben viszont a knyvtr egyik elemnek nevt tartalmaz karakterlncot. Hagyomnyosan a kvetkezhz hasonl szerkezetet hasznlnnk, ha egy knyvtr elemeit szeretnnk beolvastatni: $kvt = opendir( "konyvtar" ); while ( $nev = readdir( $kvt ) ) print "$nev<br>"; closedir( $kvt );

Az adatok kezelse Ha azonban a readdir() ltal visszaadott egyik alknyvtr neve "0", a while utasts kifejezse erre a karakterlncra false (hamis) rtket ad vissza s befejezi a felsorolst. Ha ellenrizzk a readdir() visszaadott rtknek adattpust, elkerlhetjk ezt a problmt: $kvt = opendir( "konyvtar" ); while ( is_string( $nev = readdir( $kvt ) ) ) print "$nev<br>"; closedir( $kvt );

309

A vltozk megltnek s ressgnek ellenrzse


Az adattpusok ellenrzse hasznos lehet, m elzleg meg kell bizonyosodnunk rla, hogy a vltoz egyltaln ltezik-e, s meg kell nznnk, milyen rtket tartalmaz. Ezt az isset() fggvnnyel tehetjk meg, amelynek bemenete egy vltoz, kimenete pedig true (igaz), ha a vltoz tartalmaz valamifle rtket: $nincsertek; if ( isset( $nincsertek ) ) print "a \$nincsertek vltoznak van rtke"; else print "a \$nincsertek vltoznak nincs rtke"; // kirja, hogy "a $nincsertek vltoznak nincs rtke" Azt a vltozt, amelyet mr bevezettnk, de amelynek mg nem adtunk rtket, a fggvny nem belltottknt, rtk nlkliknt fogja kezelni. Egy veszlyre azonban hadd hvjuk fel a figyelmet: ha 0-t vagy res karakterlncot rendelnk egy vltozhoz, a fggvny azt mr belltottknt, rtkkel rendelkeznek fogja tekinteni: $nincsertek = ""; if ( isset( $nincsertek ) ) print "a \$nincsertek vltoznak van rtke"; else print " a \$nincsertek vltoznak nincs rtke "; // kirja, hogy "a $nincsertek vltoznak van rtke" Azok a vltozk, amelyeket a bejv rlapok tltenek fel rtkkel, mindig belltottknt fognak szerepelni, mg akkor is, ha a felhasznl egyetlen mezt sem tlttt ki adattal. Hogy az ilyen helyzetekkel megbirkzhassunk, elszr ellenriznnk kell, hogy res-e a vltoz. Az empty() fggvny bemenete egy vltoz,

16

310

16. ra kimenete pedig true (igaz), ha a vltoz nincs belltva vagy olyan adatot tartalmaz, mint a 0 vagy egy res karakterlnc. Akkor is igaz rtket ad vissza, ha a vltoz res tmbt tartalmaz: $nincsertek = ""; if ( empty( $nincsertek ) ) print "a \$nincsertek vltoz res"; else print " a \$nincsertek vltoz adatot tartalmaz"; // kirja, hogy "a $nincsertek vltoz res"

Tovbbi tudnivalk a tmbkrl


A hetedik rban mr bemutattuk a tmbket s a tmbk kezelshez szksges fggvnyeket. Ebben a rszben tovbbi fggvnyekkel s tletekkel ismerkedhetnk meg.

Tmbk bejrsa ms megkzeltsben


A PHP 4 j eszkze a foreach utasts, amellyel tmbk elemeit olvashatjuk be. A knyvben lv pldk legnagyobb rszben ezt hasznljuk. A PHP 3 esetben mg egsz mskppen kellett bejrni a tmbket. Ha a PHP 3-nak is megfelel programokat szeretnnk rni vagy szeretnnk rteni a PHP 4 eltti forrskdokat is, ezzel tisztban kell lennnk. Tmb ltrehozsakor a PHP egy bels mutatt alkalmaz, amely a tmb els elemre mutat. Ennek az elemnek a kulcshoz s rtkhez az each() fggvnnyel frhetnk hozz. Az each() fggvny bemenete egy tmbvltoz, kimenete pedig egy ngyelem tmb. Ezek kzl az elemek kzl kett szmmal indexelt, kett pedig a "key" (kulcs) s az "value" (rtk) cmkt viseli. A fggvny meghvsa utn a bels mutat a vizsglt tmb kvetkez elemre fog mutatni, kivve, ha elrte a tmb vgt, ilyenkor false (hamis) rtket ad vissza. Hozzunk ltre egy tmbt s prbljuk ki az each() fggvnyt: $reszletek = array( "iskola" => "Kpzmvszeti", "tantargy" => "Trbeli brzols" ); $elem = each( $reszletek ); print "$elem[0]<br>"; // azt rja ki, hogy "iskola" print "$elem[1]<p>"; // azt rja ki, hogy "Kpzmvszeti" print "$elem["key"]<br>"; // azt rja ki, hogy "iskola" print "$elem["value"]<br>"; // azt rja ki, hogy "Kpzmvszeti"

Az adatok kezelse A $reszletek nev tmbt kt elemmel hozzuk ltre, ezutn tadjuk az each() fggvnynek s a visszaadott rtket az $elem nev tmbbe helyezzk. Az $elem tartalmazza a $reszletek tmbvltoz els elemnek kulcst s rtkt. Az each() ltal visszaadott tmbt kicsit nehzkes skalris vltozkhoz rendelni, de szerencsre a PHP list() fggvnye megoldja ezt a problmt. A list() fggvny tetszleges szm vltozt elfogad bemenetknt s ezek mindegyikt a jobb oldaln megadott tmbvltoz megfelel rtkeivel tlti fel: $tomb list( print print print = array( 44, 55, 66, 77 ); $elso, $masodik ) = $tomb; "$elso"; // azt rja ki, hogy "44" "<BR>"; "$masodik"; // azt rja ki, hogy "55"

311

Vegyk szre, hogy a list() fggvnnyel knnyedn msolhatjuk t az elz plda tmbjnek elemeit a kln vltozkba. Hasznljuk arra a list() fggvnyt, hogy az each() minden egyes meghvsakor kt vltoznak adjon rtket. $reszletek = array( "iskola" => "Kpzmvszeti", "tantargy" => "Trbeli brzols" ); while ( list( $kulcs, $ertek ) = each( $reszletek ) ) print "$kulcs: $ertek<BR>"; Br a kd mkdni fog, valjban mg egy sor hinyzik. Ha tmbnkre mr hasznltuk a bels mutatt mdost fggvnyek egyikt, az mr nem a tmb elejre mutat. A reset() fggvnnyel visszallthatjuk a mutatt a tmb kezdetre. Ez a fggvny paramterknt egy tmbvltozt vr. gy az albbi ismersebb szerkezet foreach( $reszletek as $kulcs => $ertek ); print "$kulcs: $ertek<BR>"; egyenrtk a kvetkezvel: reset( $reszletek ); while ( list( $kulcs, $ertek ) = each( $reszletek ) ) print "$kulcs: $ertek<BR>";

16

312

16. ra

Elem keresse tmbben


A PHP 4-et megelzleg ha azt szerettk volna megtudni, hogy egy elem elfordule egy tmbben, addig kellett bejrnunk a tmbt, mg megtalltuk az elemet vagy elrtk a tmb vgt. A PHP 4-ben azonban mr rendelkezsnkre ll az in_array() fggvny. Kt paramtere van, az egyik a keresett rtk, a msik az a tmb, amelyben keresni kvnunk. A fggvny true (igaz) rtket ad vissza, ha megtallja a keresett rtket, egybknt false (hamis) rtket kapunk. $reszletek = array( "iskola" => "Kpzmvszeti", "tantargy" => "Trbeli brzols" ); if ( in_array( "Trbeli brzols", $reszletek ) ) print "A kurzus tovbbi intzkedsig felfggesztve<P>\n";

Elemek eltvoltsa a tmbbl


Az unset() fggvnnyel elemeket is eltvolthatunk egy tmbbl. A fggvny bemenetl egy vltozt vagy egy tmbelemet vr, majd azt minden teketria nlkl megsemmisti. Ha a paramter egy tmb egy eleme, a tmbt automatikusan lervidti. unset( $proba["cim"] ); unset( $szamok[1] ); Az unset() fggvny egyetlen csapdja az lehet, hogy a tmb indexei nem kvetik a tmb megvltozott mrett. Az elz plda tmbje a $szamok[1] elem eltvoltsa utn a kvetkezkppen fest: $szamok[0] $szamok[2] $szamok[3] Szerencsre a foreach() fggvnnyel ezen is gond nlkl vgiglpkedhetnk.

Fggvnyek alkalmazsa a tmb sszes elemre


A kifejezsekben szerepl skalris vltozkat knnyen mdosthatjuk, egy tmb sszes elemt megvltoztatni mr egy kicsit nehezebb. Ha pldul a tmb sszes elemnek rtkhez egy szmot akarunk adni, azt gy tehetnnk meg, hogy a tmb sszes elemn vgiglpkedve frisstjk az rtkeket. A PHP azonban ennl elegnsabb megoldst knl.

Az adatok kezelse Az array_walk() fggvny egy tmb minden elemnek kulcst s rtkt tadja egy, a felhasznl ltal meghatrozott fggvnynek. A fggvny bemenete egy tmbvltoz, egy, a fggvny nevt megad karakterlnc rtk, s egy elhagyhat harmadik paramter, amelyet a vlasztott fggvnynek szeretnnk mg tadni. Vegynk egy pldt. Van egy adatbzisbl kinyert rtmbnk, de mieltt munkhoz kezdennk vele, az sszes rhoz hozz kell adnunk a forgalmi adt. Elszr azt a fggvnyt hozzuk ltre, amely hozzadja az adt: function ado_hozzaado( &$ertek, $kulcs, $adoszazalek ) { $ertek +=( ($adoszazalek/100) * $ertek ); } Az array_walk() szmra ksztett sszes fggvnynek egyrtket, egy kulcsot s egy elhagyhat harmadik paramtert kell vrnia. Ha paramterknt nem rtket szeretnnk tadni, hanem egy vltozt, melyben tkrzdhetnek a fggvny okozta vltoztatsok a fggvny hatkrn kvl is, a fggvny-meghatrozsban egy S jelet (&) kell az adott paramter el rni. Ez fogja biztostani, hogy ha a fggvnyen bell mdostjuk az rtket, az megjelenik a fggvnyen kvl a tmbben is. Ez az oka annak is, hogy pldnkban az ado_hozzaado() fggvnynek nincs szoksos rtelemben vett visszatrsi rtke. Most hogy megvan a fggvnynk, mris meghvhatjuk az array_walk() fggvnyt a megfelel paramterekkel: function ado_hozzaado( &$ertek, $kulcs, $adoszazalek ) { $ertek +=( ($adoszazalek/100) * $ertek ); } $arak = array( 10, 17.25, 14.30 ); array_walk( $arak, "ado_hozzaado", 10 ); foreach( $arak as $ertek ) print "$ertek<BR>"; // kimenete: // 11 // 18.975 // 15.73 A $arak tmbvltozt az ado_hozzaado() fggvny nevvel egytt tadjuk az array_walk() fggvnynek. Az ado_hozzaado() fggvnynek tudnia kell az rvnyes adkulcsot. Az array_walk() harmadik, elhagyhat paramtere taddik a megnevezett fggvnynek s ezzel elrjk, hogy az rtesljn az adkulcsrl.

313

16

314

16. ra

Tmbk egyni rendezse

A kulcs vagy rtk alapjn trtn rendezssel mr megismerkedtnk, nem mindig szoktunk azonban ilyen egyszeren rendezni tmbket. Elfordulhat, hogy tbbdimenzis tmbbe begyazott rtkek alapjn vagy a szokvnyos alfanumerikus sszehasonltstl eltr szempont szerint szeretnnk rendezni. A PHP lehetv teszi, hogy magunk hatrozzuk meg az sszehasonlt tmbrendez fggvnyeket. Szmmal indexelt tmbk esetben ilyenkor az usort() fggvnyt kell meghvnunk, melynek bemenete a rendeznival tmb s annak a fggvnynek a neve, amely egy elempr sszehasonltst kpes elvgzi. Az ltalunk meghatrozott fggvnynek kt paramtert kell elfogadnia, amelyek az sszehasonltand tmbrtkeket tartalmazzk. Ha a felttelek alapjn ezek azonosak, a fggvny a 0 rtket kell, hogy visszaadja, ha a trgytmbben az els paramternek a msodik eltt kell jnnie, akkor 1-et, ha pedig ez els paramternek kell a msodik utn szerepelnie, akkor 1-et. A 16.1. programban azt lthatjuk, hogyan hasznljuk az usort() fggvnyt egy tbbdimenzis tmb rendezsre.

16.1. program Tbbdimenzis tmb rendezse mez alapjn az usort() fggvnnyel


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: <?php $termekek = array( array( "nev"=>"HAL 2000", "ar"=>4500.5 ), array( "nev"=>"Modem", "ar"=>55.5 ), array( "nev"=>"Nyomtat", "ar"=>2200.5 ), array( "nev"=>"Csavarhz", "ar"=>22.5 ) ); function arHasonlito( $a, $b ) { if ( $a["ar"] == $b["ar"] ) return 0; if ( $a["ar"] < $b["ar"] ) return -1; return 1; } usort( $termekek, "arHasonlito" ); foreach ( $termekek as $ertek ) print $ertek["nev"] ":" $ertek["ar"] "<br>\n"; ?>

Az adatok kezelse Elszr ltrehozzuk a $termekek tmbt, amelyet az egyes rtkek r mezje alapjn szeretnnk rendezni. Ezutn ltrehozzuk az arHasonlito() fggvnyt, amelynek kt paramtere van, $a s $b. Ezek tartalmazzk azt a kt tmbt, amely a $termekek tmb msodik szintjt alkotja. sszehasonltjuk az "ar" elemeiket s ha a kt r azonos, 0-t, ha az els kevesebb, mint a msik, 1-et, egybknt pedig 1-et adunk vissza. Miutn meghatroztuk a rendez fggvnyt s a tmbt is, meghvhatjuk az usort() fggvnyt, amelynek tadjuk a $termekek tmbt s az sszehasonlt fggvny nevt. Az usort() ismtelten meghvja fggvnynket, mindig tadja annak a $termekek egy elemt s felcserli az elemeket, a visszaadott rtkeknek megfelelen. Vgl vgiglptetnk a tmbn, hogy megmutassuk az j elrendezst. Az usort() fggvnyt szmmal indexelt tmbk esetben hasznljuk. Ha ms egyni rendezst szeretnnk egy asszociatv tmbn vgrehajtani, hasznljuk az uasort() fggvnyt. Az uasort() gy rendez, hogy megtartja a kulcsok s az rtkek kztti trstst is. A 16.2. program az uasort() hasznlatt egy asszociatv tmb rendezsn keresztl mutatja be.

315

16.2. program Tbbdimenzis tmb rendezse mez alapjn az uasort() fggvnnyel


1: <?php 2: $termekek = array( 3: "HAL 2000" => array( "szin" =>"piros", "ar"=>4500.5 ), 4: "Modem" => array( "szin" =>"kk", "ar"=>55.5 ), 5: "Nyomtat" => array( "szin" =>"zld", "ar"=>2200.5 ), 6: "Csavarhz" => array( "szin" =>"piros", "ar"=>22.5 ) 7: ); 8: function arHasonlito( $a, $b ) 9: { 10: if ( $a["ar"] == $b["ar"] ) 11: return 0; 12: if ( $a["ar"] < $b["ar"] ) 13: return -1; 14: return 1; 15: } 16: uasort( $termekek, "arHasonlito" );

16

316

16. ra

16.2. program (folytats)


17: foreach ( $termekek as $kulcs => $ertek ) 18: print "$kulcs: " $ertek["ar"] "<br>\n"; 19: ?>

Az uksort() fggvnnyel az asszociatv tmbkn a kulcsok alapjn vgezhetnk egyni rendezst. Az uksort() pontosan ugyangy mkdik, mint az usort() s az uasort(), azzal a klnbsggel, hogy az uksort() a tmb kulcsait hasonltja ssze. A 16.3. programban az uksort() fggvnnyel az egyes kulcsok karakterszma alapjn rendeznk egy tmbt. Megelzve a kvetkez ra anyagt, az strlen() fggvnnyel llaptjuk meg a kulcsok hosszsgt. Az strlen() fggvny bemenete egy karakterlnc, visszaadott rtke pedig annak hosszsga karakterben mrve.

16.3. program Asszociatv tmb rendezse kulcshosszsg alapjn az uksort() fggvnnyel


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: "xxxx" => 4, "xxx" => 5, "xx" => 7, "xxxxx" => 2, "x" => 8 ); function hosszHasonlito( $a, $b ) { if ( strlen( $a ) == strlen( $b ) ) return 0; if ( strlen( $a ) < strlen( $b ) ) return -1; return 1; } uksort( $ikszek, "hosszHasonlito" ); foreach ( $ikszek as $kulcs => $ertek ) print "$kulcs: $ertek <br>\n"; // a kimenet: <?php $ikszek = array(

Az adatok kezelse

317

16.3. program (folytats)


22: 23: 24: 25: 26: 27: 28: // // // // // ?> x: 8 xx: 7 xxx: 5 xxxx: 4 xxxxx: 2

sszefoglals
Az ra sorn a tmbkkel s adattpusokkal kapcsolatos ismeretekben mlyedtnk el. Megtanultuk, mi trtnik, ha sszetett adattpust skalriss alaktunk s fordtva. Megtudtuk, hogyan kezeli a PHP a klnbz adattpusokat egy kifejezsben, hogyan hatrozza meg automatikusan az eredmny adattpust helyettnk. Megismerkedtnk szmos fggvnnyel; pldul az is_array()-jel, amely klnfle adattpusokat ellenriz, vagy az intval()-lal, amely az adatot egsz rtkv alaktja t. Megtanultuk, hogyan lehet a PHP-ben hagyomnyos mdon tmbt bejrni, az each() s a list() fggvnnyel. Az in_array() fggvnnyel kpesek vagyunk ellenrizni, hogy ltezik-e egy adott rtk egy tmbben, s el tudunk tvoltani egy elemet egy tmbbl az unset() fggvnnyel. Az array_walk() fggvnnyel mr egy tmb sszes elemn is vgezhetnk mveleteket, vgl azt is tudjuk, hogyan hasznljuk az usort(), az uasort() s az uksort() fggvnyeket arra, hogy a tmbk egyni rendezst vgezzk.

Krdsek s vlaszok
A PHP minden tmbkezel fggvnyvel megismerkedtnk? Nem, az egsz knyv sem lenne elg az sszes tmbkezel fggvny bemutatshoz. Teljes listjukat s lersukat a http://www.php.net/manual/ref.array.php weboldalon tallhatjuk.

16

318

16. ra

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Melyik az a fggvny, amellyel adattpusokat tetszleges ms adattpuss alakthatunk? 2. Sikerlhet ez fggvny nlkl is? 3. Mit r ki a kvetkez kd? print "four" * 200; 4. Hogyan hatroznnk meg, hogy egy adott vltoz tmb-e? 5. Melyik fggvny adja vissza paramternek rtkt egsz szmknt? 6. Hogyan ellenrizzk, hogy egy vltoznak adtunk-e mr rtket? 7. Hogyan ellenrizzk, hogy egy vltoz res rtket (pldul 0-t vagy res karakterlncot) tartalmaz? 8. Melyik fggvnnyel trlnnk egy tmb egy elemt? 9. Melyik fggvnnyel rendeznnk egy szmmal indexelt tmbt?

Feladatok
1. Nzzk vgig mg egyszer a knyv sorn megoldott feladatokat. Alaktsunk t minden foreach utastst gy, hogy az megfeleljen a PHP 3 kvetelmnyeinek is. 2. Hozzunk ltre egy vegyes adattpus tmbt. Rendeztessk a tmbt adattpusok szerint.

17. RA
Karakterlncok kezelse
A Vilghl valjban szveges fjlokra pl krnyezet, s igazbl nem szmt, mivel gazdagodik a jvben a tartalma, a mlyn mindig szveges llomnyokat fogunk tallni. gy nem meglep, hogy a PHP 4 sok olyan fggvnyt biztost, amellyel szvegmveletek vgezhetk. Az ra sorn a kvetkezket tanuljuk meg: Hogyan formzzunk karakterlncokat? Hogyan hatrozzuk meg a karakterlncok hosszt? Hogyan talljunk meg egy karakterlncon belli karakterlncot? Hogyan bontsuk szt a karakterlncot alkotelemeire? Hogyan tvoltsuk el a szkzket a karakterlncok vgrl vagy elejrl? Hogyan cserljnk le karakterlnc-rszleteket? Hogyan vltoztassuk egy karakterlncban a kisbetket nagybetre s fordtva?

320

17. ra

Karakterlncok formzsa
A megjelenteni kvnt karakterlncot eddig egyszeren kirattuk a bngszbe. A PHP kt olyan fggvnyt tartalmaz, amely lehetv teszi az elzetes formzst, fggetlenl attl, hogy tizedestrteket kell valahny tizedes pontossgra kerekteni, egy mezn bell kell jobbra vagy balra igaztani valamit, vagy egy szmot kell klnbz szmrendszerekben megjelenteni. Ebben a rszben a printf() s az sprintf() fggvnyek ltal biztostott formzsi lehetsgekkel ismerkednk meg.

A printf() fggvny hasznlata


Ha mr dolgoztunk C-vel, biztosan ismers lesz a printf() fggvny, amelynek PHP-s vltozata hasonl, de nem azonos azzal. A fggvny bemenete egy karakterlnc, ms nven a formtumvezrl karakterlnc (rviden formz karakterlnc vagy egyszeren formz), emellett tovbbi, klnbz tpus paramterek. A formz karakterlnc ezen tovbbi paramterek megjelentst hatrozza meg. A kvetkez kdrszlet pldul a printf() fggvnyt hasznlja, hogy egy egsz szmot decimlis rtkknt rjon ki: printf("az n szmom az %d", 55 ); // azt rja ki, hogy "az n szmom az 55" A formz karakterlncban (ami az els paramter) egy klnleges kdot helyeztnk el, amely talaktsi meghatrozsknt ismert. JDONSG Az talaktsi meghatrozs szzalkjellel (%) kezddik, s azt hatrozza meg, hogyan kell a printf() fggvny neki megfelel paramtert kezelni. Egyetlen formtumvezrl karakterlncba annyi talaktsi meghatrozst rhatunk, amennyit csak akarunk, feltve, hogy a printf() fggvnynek ugyanennyi paramtert adunk t a formzt kveten. A kvetkez kdrszlet kt szmot r ki a printf() hasznlatval: printf("Az els szm: %d<br>\nA msodik szm: %d<br>\n", 55, 66 ); // A kirt szveg: // Az els szm: 55 // A msodik szm: 66 Az els talaktsi meghatrozs a printf() msodik paramternek felel meg, ami ebben az esetben az 55. A kvetkez talaktsi meghatrozs a 66-nak felel meg. A szzalkjelet kvet d bet miatt a fggvny az adatot decimlis egszknt rtelmezi. A meghatrozsnak ez a rsze tpusparamterknt ismeretes.

Karakterlncok kezelse

321

A printf() s a tpusparamterek
Egy tpusparamterrel mr tallkoztunk, ez volt a d, amely az adatot decimlis formtumban jelenti meg. A tbbi tpusparamtert a 17.1. tblzatban lthatjuk.

17

17.1. tblzat Tpusparamterek


Paramter d
b c f o s x X

Lers A paramtert decimlis szmknt jelenti meg.


Egsz szmokat binris szmknt jelent meg. Egy egsz szmot annak ASCII megfeleljeknt jelent meg. A paramtert lebegpontos szmknt brzolja. Egy egsz szmot oktlis (8-as szmrendszer) szmknt jelent meg. A paramtert karakterlnc-llandnak tekinti. Egy egsz szmot kisbets hexadecimlis (16-os szmrendszer) szmknt jelent meg. Egy egsz szmot nagybets hexadecimlis (16-os szmrendszer) szmknt jelent meg

A 17.1. program a printf() fggvnnyel egy szmot a 17.1. tblzat tpusparamterei segtsgvel jelent meg. Vegyk szre, hogy a formz karakterlnc nem egyszeren csak talaktsi meghatrozsokat tartalmaz, minden tovbbi benne szerepl szveg kirsra kerl.

17.1. program Nhny tpusparamter hasznlatnak bemutatsa


1: <html> 2: <head> 3: <title>17.1. program Nhny tpusparamter hasznlatnak bemutatsa</title> 4: </head> 5: <body> 6: <?php 7: $szam = 543; 8: printf("Decimlis: %d<br>", $szam ); 9: printf("Binris: %b<br>", $szam );

322

17. ra

17.1. program (folytats)


10: 11: 12: 13: 14: 15: 16: 17: printf("Ktszeres pontossg: %f<br>", $szam ); printf("Oktlis: %o<br>", $szam ); printf("Karakterlnc: %s<br>", $szam ); printf("Hexa (kisbets): %x<br>", $szam ); printf("Hexa (nagybets): %X<br>", $szam ); ?> </body> </html>

A 17.1. program kimenett a 17.1. brn lthatjuk. A printf() fggvnnyel gyorsan tudunk adatokat egyik szmrendszerbl a msikba talaktani s az eredmnyt megjelenteni.

17.1. bra
Nhny tpusparamter hasznlatnak bemutatsa

Ha a HTML-ben hivatkoznunk kell egy sznre, hrom 00 s FF kz es, a vrs, zld s kk sznt kpvisel hexadecimlis szmot kell megadnunk. A printf() fggvnyt hasznlhatjuk arra, hogy a hrom 0 s 255 kz es decimlis szmot azok hexadecimlis megfelelire alaktsuk t: $piros = 204; $zold = 204; $kek = 204; printf( "#%X%X%X", $piros, $zold, $kek ); // azt rja ki, hogy "#CCCCCC"

Karakterlncok kezelse Br a tpusparamterrel a decimlis szmokat hexadecimliss alakthatjuk, azt nem tudjuk meghatrozni, hogy az egyes paramterek kimenete hny karaktert foglaljon el. A HTML sznkdjban minden hexadecimlis szmot kt karakteresre kell kitlteni, ami problmt okoz, ha pldul az elz kdrszlet $piros, $zold, $kek vltozit gy mdostjuk, hogy 1-et tartalmazzanak. Kimenetl "#111"-et kapnnk. A bevezet nullk hasznlatt egy kitlt paramter segtsgvel biztosthatjuk.

323

17

A kitlt paramter
Bellthatjuk, hogy a kimenet bizonyos karakterekkel megfelel szlessgre tltdjn ki. A kitlt paramter kzvetlenl az talakt paramtert kezd szzalkjelet kveti. Ha a kimenetet bevezet nullkkal szeretnnk kitlteni, a kitlt paramterben a 0 karaktert az a szm kveti, ahny karakteresre szeretnnk a kimenetet bvteni. Ha a kimenet hossza ennl a szmnl kisebb lenne, a klnbsg nullkkal kerl kitltsre, ha nagyobb, a kitlt paramternek nincs hatsa: printf( "%04d", 36 ) // a kimenet "0036" lesz printf( "%04d", 12345 ) // a kimenet "12345" lesz Ha a kimenetet bevezet szkzkkel szeretnnk kitlteni, a kitlt paramternek tartalmaznia kell egy szkz karaktert, amelyet a kimenet elvrt karakterszma kvet: printf( "% 4d", 36 ) // azt rja ki, hogy " 36"

324

17. ra

Br a HTML dokumentumokban egyms utn szerepl tbb szkzt a bngszk nem jelentik meg, a megjelentend szveg el s utn helyezett <PRE> cmkvel mgis biztosthatjuk a szkzk s sortrsek megjelentst. <pre> <?php print "A ?> </pre>

szkzk

lthatv vlnak."

Ha teljes dokumentumot szeretnnk szvegknt megformzni, a header() fggvnyt hasznlhatjuk a dokumentumtpus (Content-Type) fejlcnek mdostshoz. header("Content-type: text/plain"); Ne feledjk, hogy programunk nem kldhet semmilyen kimenetet a bngsznek a header() fggvnyhvst megelzen, hogy a megfelel mdon mkdjn, mivel a kimenet megkezdsekor a vlasz fejrszt mr elkldtk a bngsznek.

Ha szkzn vagy nulln kvl ms karaktert szeretnnk a kitltshez hasznlni, a kitlt paramteren bell a kitlt karakter el rjunk egyszeres idzjelet: printf( "%'x4d", 36 ) // azt rja ki "xx36" Most mr rendelkezsnkre llnak azok az eszkzk, melyekkel a korbbi HTML kdot kiegszthetjk. Eddig ugyan mr t tudtuk alaktani a hrom szmot, de nem tudtuk bevezet nullkkal kitlteni azokat: $piros = 1; $zold = 1; $kek = 1; printf( "#%02X%02X%02X", $piros, $zold, $kek ); // azt rja ki, hogy "#010101" Most mr minden vltoz hexadecimlis szmknt fog megjelenni. Ha a kimenet kt karakternl rvidebb, a hinyt bevezet nullk ptoljk.

Karakterlncok kezelse

325

A mezszlessg meghatrozsa
Meghatrozhatjuk a kimenet ltal elfoglalt mez szlessgt is. A mezszlessg paramtere egy olyan egsz szm, amely a szzalkjel utn kvetkezik az talakt paramterben (feltve, hogy nem hasznlunk helykitlt karaktereket). A kvetkez kdrszlet kimenete egy ngyelem felsorols, amelynek mezszlessge 20 karakternyi. A szkzk lthatv ttelhez a kimenetet egy PRE elembe gyazzuk. print "<pre>"; printf("%20s\n", printf("%20s\n", printf("%20s\n", printf("%20s\n", print "</pre>"; "Knyvek"); "CDk"); "Jtkok"); "Magazinok");

17

A 17.2. brn a fenti kdrszlet eredmnyt lthatjuk.

17.2. bra
Igazts a mezszlessghez

A kimenet alaprtelmezs szerint a mezn bell jobbra igazodik. A balra igaztst a mezszlessg paramtere el tett mnuszjellel (-) rhetjk el. printf ("%-20s|<- eddig tart a balra zrs\n", "Balra zrt"); Fontos megjegyezni, hogy ha lebegpontos szmot runk ki, az igazts csak a kimenetben lev szm (ponttl jobbra lev) tizedesrszre vonatkozik. Ms szval jobbra igaztskor a lebegpontos szmnak a tizedesponttl balra es rsze a mez bal oldali, tls vgn marad.

326

17. ra

A pontossg meghatrozsa
Ha az adatot lebegpontos formban szeretnnk megjelenteni, meghatrozhatjuk a kerekts pontossgt. Ez fleg a pnznem tvltsakor szokott fontos lenni. A pontossgot meghatroz paramter egy pontbl s egy szmbl ll, s kzvetlenl a tpusparamter el kell rni. A megadott szm hatrozza meg, hny tizedesre szeretnnk kerekteni. Ez a paramter csak akkor rvnyes, ha a kimenet f tpusparamter: printf ("%.2f\n", 5.333333); // azt rja ki, hogy "5.33" A C nyelv printf() fggvnyben akkor is lehetsgnk van a pontossg megadsra, ha decimlis kimenet esetn krnk kitltst. A PHP 4-ben a pontossg paramternek nincs semmilyen hatsa a decimlis kimenetre. Egsz szmok nullkkal val bevezetshez a kitlt paramtert kell hasznlnunk.

talakt paramterek (Ismtls)


A 17.2. tblzatban az talakt paramtereket foglaljuk ssze. Megjegyzend, hogy a kt (kitlt s mezszlessg) paramter egyttes hasznlata bonyolult, gy azt tancsoljuk, egyszerre csak az egyiket hasznljuk.

17.2. tblzat Az talakts lpsei


Nv Kitlt paramter Lers A kimenet ltal elfoglaland karakterszmot s a kitltsre hasznlt karaktert adja meg.
A formzand karakterlnc mrett adja meg. Meghatrozza, hogy a ktszeres pontossg szmokat hny tizedesre kell kerekteni. Meghatrozza az eredmny adattpust.

Plda ' 4'

Mezszlessg paramter Pontossg paramter

'20' '.4'

Tpusparamter

'd'

Karakterlncok kezelse A 17.2. program a printf() hasznlatval egy termkrlistt hoz ltre.

327

17.2. program Termkrlista formzsa a printf() fggvnnyel


1: <html> 2: <head> 3: <title>17.2. program Termkrlista formzsa a printf() fggvnnyel</title> 4: </head> 5: <body> 6: <?php 7: $termekek = Array("Zld karosszk"=>"222.4", 8: "Gyertyatart" => "4", 9: "Kvzasztal" => "80.6" 10: ); 11: print "<pre>"; 12: printf("%-20s%23s\n", "Nv", "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>

17

Elszr a termkek nevt s rt tartalmaz tmbt adjuk meg. Egy PRE elemmel jelezzk a bngsznek, hogy a szkzket s a soremelseket rtelmezze. A printf() els meghvsa a kvetkez formz karakterlncot adja meg: "%-20s%23s\n" Az els talakt meghatrozs ("%-20s") a mezszlessget balra zrt 20 karakteresre lltja. Ebben a mezben egy karakterlnc tpus paramtert helyeznk el. A msodik meghatrozs ("%23s") egy jobbra zrt mezszlessget ad meg. A printf() fggvnynek ez a meghvsa hozza ltre leend tblzatunk fejlct. A printf() msodik meghvsval egy 43 karakter hossz, mnuszjelekbl (-) ll vonalat hzunk. Ezt gy rjk el, hogy egy res karakterlncot kitlt paramterrel jelentnk meg. A printf() legutols meghvsa annak a foreach utastsnak a rsze, amely vgiglpked a termkek tmbjn. Kt talakt meghatrozst hasznlunk.

328

17. ra Az els ("%-20s") a termk nevt rja ki egy 20 karakteres mezbe, balra igaztva. A msik ("%20.2f") a mezszlessg paramterrel azt biztostja, hogy az eredmny egy 20 karakteres mezben jobbra igaztva jelenjen meg, a pontossgi paramterrel pedig azt, hogy a megjelentett ktszeres pontossg rtk kt tizedesre legyen kerektve. A 17.3. brn a 17.2. program eredmnyt lthatjuk.

17.3. bra
Termkrlista formzsa a printf() fggvnnyel

Formzott karakterlnc trolsa


A printf() az adatokat a bngszben jelenti meg, ami azzal jr, hogy eredmnye programunk szmra nem elrhet. Hasznlhatjuk azonban a sprintf() fggvnyt is, amelynek hasznlata megegyezik a printf() fggvnyvel, viszont az eredmnyt egy karakterlncban adja vissza, amelyet aztn ksbbi hasznlatra egy vltozba helyezhetnk. A kvetkez kdrszlet a sprintf() fggvny segtsgvel egy lebegpontos rtket kt tizedesre kerekt s az eredmnyt a $kerek vltozban trolja: $kerek = sprintf("%.2f", 23.34454); print "Mg $kerek forintot klthetsz"; A sprintf() fggvny egy lehetsges felhasznlsa, hogy vele a megformzott adatot fjlban lehet trolni. Ennek az a mdja, hogy elszr meghvjuk a sprintf() fggvnyt, a visszaadott rtkt egy vltozban troljuk, majd az fputs() fggvnnyel fjlba rjuk.

Karakterlncok kezelse

329

Rszletesebben a karakterlncokrl

Nem minden esetben tudunk mindent azokrl az adatokrl, amelyekkel dolgozunk. A karakterlncok tbbfle forrsbl is rkezhetnek, beviheti a felhasznl, rkezhetnek adatbzisokbl, fjlokbl s weboldalakrl. A PHP 4 tbb fggvnye segtsgnkre lehet abban, hogy ezekrl a kls forrsbl rkez adatokrl tbbet tudjunk meg.

17

Szvegek indexelse
A karakterlncokkal kapcsolatban gyakran hasznljuk az indexels szt, de a tmbknl mg gyakrabban tallkozhatunk vele. Valjban a karakterlncok s a tmbk nem llnak olyan messze egymstl, mint azt gondolnnk. Egy karakterlncot elkpzelhetnk egy karakterekbl ll tmbknt is. Ennek megfelelen a karakterlncok egyes karaktereihez ugyangy frhetnk hozz, mint egy tmb elemeihez: $proba = "gazfick"; print $proba[0]; // azt rja ki, hogy "g" print $proba[2]; // azt rja ki, hogy "z" Ne felejtsk el, hogy amikor egy karakterlncon belli karakter indexrl vagy helyrl beszlnk, akkor a karaktereket ugyangy, mint a tmb elemeit 0-tl kezdve szmozzuk. A tmbkkel kapcsolatos flrertsek elkerlse rdekben a PHP 4 bevezette a $proba{0} formt is erre a clra.

Szveg hossznak megllaptsa az strlen() fggvnnyel


Az strlen() fggvny segtsgvel megllapthatjuk egy karakterlnc hosszt. A fggvny bemenete egy karakterlnc, visszatrsi rtke pedig egy egsz szm, amely a fggvnynek tadott vltoz karaktereinek szma. Ez a fggvny pldul kimondottan jl jhet a felhasznl ltal megadott bemenet hossznak ellenrzsre. A kvetkez kdrszlettel ellenrizhetjk, hogy a tagnyilvntart azonost ngykarakteres-e: if ( strlen( $tagazonosito ) == 4) print "Ksznm!"; else print "Az azonostnak ngykarakteresnek kell lennie<P>"; Ha a $tagazonosito globlis vltoz rtke ngykarakteres, megksznjk a felhasznlnak, hogy rendelkezsnkre bocstotta, ms esetben hibazenetet jelentnk meg.

330

17. ra

Szvegrsz megkeresse az strstr() fggvnnyel


Ezzel a fggvnnyel azt llapthatjuk meg, hogy egy karakterlnc megtallhat-e begyazva egy msik karakterlncban. Az strstr() fggvny kt paramtert kap bemenetl: a keresend szveget s a forrslncot, azaz azt a karakterlncot, amelyben keresnie kell. Ha a keresett karakterlnc nem tallhat a szvegben, a visszatrsi rtk false (hamis) lesz, ellenkez esetben a fggvny a forrslncbl a keresett karakterlnccal kezdd rszt adja vissza. A kvetkez pldban megklnbztetetten kezeljk azokat a tagazonostkat, amelyekben megtallhat az AB karakterlnc: $tagazonosito = "pAB7"; if ( strstr( $tagazonosito, "AB" ) ) print "Ksznm. Ne feledje, hogy tagsga hamarosan lejr!"; else print "Ksznm!"; Mivel a $tagazonosito vltoz tartalmazza az AB karakterlncot, az strstr() az AB7 karakterlncot adja vissza. Ez true (igaz) eredmnynek szmt, gy egy klnleges zenetet r ki. Mi trtnik akkor, ha a felhasznl a "pab7" karakterlncot adja meg? Az strstr() megklnbzteti a kis- s nagybetket, gy nem tallja meg az AB karakterlncot. Az if utasts felttele nem vlik igazz, gy a szokvnyos zenet kerl a bngszhz. Ha vagy AB-t, vagy ab-t szeretnnk kerestetni a szvegben, hasznljuk az stristr() fggvnyt, melynek mkdse azonos az strstr()-vel, viszont nem klnbzteti meg a kis- s nagybetket.

Rszlnc elhelyezkedsnek meghatrozsa az strpos() fggvnnyel


Az strpos() fggvny segtsgvel kiderthetjk, hogy egy szveg megtallhat-e egy msik szveg rszeknt, s ha igen, hol. Bemenett kt paramter kpezi, a forrslnc, amelyben keresnk, s a karakterlnc, amelyet keresnk. Ezek mellett ltezik mg egy harmadik, nem ktelez paramter, mgpedig azt az indexet megad egsz szm, amelytl kezdve keresni szeretnnk. Ha a keresett karakterlnc nem tallhat, a fggvny a false (hamis) rtket adja vissza, ellenkez esetben azt az egsz szmot, mely indextl a keresett szveg kezddik. A kvetkez programrszletben az strpos() fggvnnyel gyzdnk meg arrl, hogy egy karakterlnc az mz karakterekkel kezddik-e: $tagazonosito = "mz00xyz"; if ( strpos($tagazonosito, "mz") === 0 ) print "dv, mz.";

Karakterlncok kezelse Vegyk szemgyre azt a trkkt, amellyel a kvnt eredmnyt kaptuk. Az strpos() megtallja az mz karaktersort a lnc elejn. Ez azt jelenti, hogy 0 rtket ad vissza, ami viszont a kifejezs kirtkelse sorn hamis rtket eredmnyezne. Hogy ezt elkerljk, a PHP 4 j azonossg mveleti jelt (===) alkalmazzuk, amely akkor ad vissza true (igaz) rtket, ha bal s jobb oldali operandusa egyenl rtk s azonos tpus is egyben.

331

17

Szvegrszlet kinyerse a substr() fggvnnyel


A substr() fggvny egy kezdindextl kezdve meghatrozott hosszsg karakterlncot ad vissza. Bemenett kt paramter kpezi, az egyik a forrslnc, a msik a kezdindex. A fggvny az sszes karaktert visszaadja a kezdindextl a forrslnc vgig. Harmadik, nem ktelez paramtere egy egsz szm, amely a visszaadand szveg hosszt jelenti. Ha ezt is megadjuk, a fggvny csak a meghatrozott mennyisg karaktert adja vissza a kezdindextl szmtva. $proba = "gazfick"; print substr($proba,3); // azt rja ki "fick" print substr($proba,3,4); // azt rja ki "fick" Ha kezdindexknt negatv szmot adunk meg, a fggvny nem a karakterlnc elejtl szmolja a karaktereket, hanem a vgtl. A kvetkez kdrszlet meghatrozott zenetet r ki azoknak, akiknek e-mail cme .hu-val vgzdik. $cim = "felhasznalo@szolgaltato.hu" if ( substr( $cim, -3 ) == ".hu" ) print "Ne felejtse el magyar vsrlinknak jr specilis ajnlatainkat!"; else print "dvzljk zletnkben!";

Karakterlnc elemekre bontsa az strtok() fggvnnyel


Az strtok() fggvnnyel karakterlncok szintaktikai elemzst vgezhetjk. A fggvny legels meghvsakor kt paramtert vr, az elemzend karakterlncot s egy hatroljelet, amely alapjn a karakterlncot felbontja. A hatroljel tetszleges szm karakterbl llhat. A fggvny els meghvsakor tmenetileg a memriba helyezi a teljes forrslncot, gy a tovbbi meghvsok alkalmval mr csak a hatroljelet kell megadnunk. Az strtok() minden meghvsakor a kvetkez megtallt elemet adja vissza, a karakterlnc vgre rkezst a false (hamis) rtk visszaadsval jelzi. Ezt a fggvnyt legtbbszr cikluson bell hasznljuk. A 17.3. program egy URL-t bont elemeire: elszr levlasztja a gazdagpet s az elrsi tvonalat a karakterlncrl, majd a vltozrtk prokat bontja szt. A 17.3. program eredmnyt a 17.3. brn lthatjuk.

332

17. ra

17.3. program Karakterlnc elemekre bontsa az strtok() fggvnnyel


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: <html> <head> <title>17.3. program Karakterlnc elemekre bontsa az strtok() fggvnnyel</title> </head> <body> <?php $proba = "http://www.deja.com/qs.xp? OP=dnquery.xp&ST=MS&DBS=2&QRY=developer+php"; $hatarolo = "?&"; $szo = strtok( $proba, $hatarolo ); while ( is_string( $szo ) ) { if ( $szo ) print "$szo<br>"; $szo = strtok( $hatarolo ); } ?> </body> </html>

Az strtok() fggvny nmagban nem sok mindent tmogat, gy csak klnfle trkkkkel brhatjuk igazn hasznos munkra. Elszr a $hatarolo vltozban troljuk a hatroljelet. Meghvjuk az strtok() fggvnyt, tadjuk neki az elemzend URL-t s a $hatarolo karakterlncot. Az els eredmnyt a $szo vltozba helyezzk. A while ciklus felttelben azt ellenrizzk, hogy a $szo karakterlnc-e. Ha nem az, tudhatjuk, hogy elrtk az URL vgt s a feladat befejezdtt. Azrt ellenrizzk a visszaadott rtk tpust, mert ha egy karakterlnc egy sorban kt hatroljel van, az strtok() az els hatroljel elrsekor res karakterlncot ad vissza. gy, ha a $szo egy res karakterlnc, az albbi pldban lthat szokvnyosabb prblkozs sikertelen lesz, mg akkor is, ha a fggvny mg nem rte el a forrslnc vgt, mivel a while felttele hamiss vlik: while ( $szo ) { $szo = strtok( $hatarolo ); }

Karakterlncok kezelse Ha meggyzdtnk rla, hogy a $szo vltoz karakterlncot tartalmaz, elkezdhetnk dolgozni vele. Ha a $szo nem res karakterlnc, megjelentjk a bngszben. Aztn jra meg kell hvnunk a strtok() fggvnyt, hogy a $szo vltozt jabb karakterlnccal tltse fel a kvetkez kirtkelshez. Vegyk szre, hogy a msodik alkalommal nem adtuk t a fggvnynek a forrslncot. Ha ezt mgis megtennnk, jra a forrslnc els szavt talln meg, gy vgtelen ciklusba kerlnnk.

333

17

A karakterlncok kezelse
A PHP 4 a karakterlnc paramterek kisebb-nagyobb talaktshoz szmos fggvnyt biztost.

Szveg tisztogatsa a trim() tpus fggvnyekkel


Ha egy felhasznltl vagy fjlbl kapunk informcit, sohasem lehetnk biztosak benne, hogy az adat eltt vagy utn nincs egy vagy tbb flsleges elvlaszt karakter. A trim() fggvny ezeket az elvlaszt karaktereket (soremels, tabultorjel, szkz stb.) hagyja el a karakterlnc elejrl s vgrl. Bemenete a megtiszttand szveg, kimenete pedig a megtiszttott. $szoveg = "\t\t\telgg levegs ez a szveg $szoveg = trim( $szoveg ); print $szoveg // azt rja ki, hogy "elgg levegs ez a szveg" ";

Persze lehet, hogy ez a tlbuzg fggvny nem a legmegfelelbb szmunkra. Elkpzelhet, hogy a szveg elejn lev elvlaszt karaktereket meg szeretnnk tartani s csak a szveg vgrl akarjuk eltvoltani azokat. Pontosan erre a feladatra talltk ki a chop() fggvnyt. Vigyzzunk, ha Perl ismeretekkel is rendelkeznk, mivel ott a chop() fggvny egy kicsit ms jelentssel br. A problma thidalsra a PHP fejleszti ugyanezen szolgltats elrshez megadtk az rtim() fggvnynevet is. $szoveg = "\t\t\telgg levegs ez a szveg "; $szoveg = chop( $szoveg ); print $szoveg // azt rja ki, hogy " elgg levegs ez a szveg" Lehetsgnk van az ltrim() fggvny hasznlatra is, amely az elvlaszt karaktereket csak a karakterlnc elejrl tvoltja el. Ahogy az elzeknl is, bemenete az talaktand szveg, kimenete pedig az elvlaszt karakterektl csupn a bal oldaln mentes karakterlnc:

334

17. ra $szoveg = "\t\t\telgg levegs ez a szveg $szoveg = ltrim( $szoveg ); print $szoveg // azt rja ki, hogy "elgg levegs ez a szveg "; "

Karakterlnc rsznek lecserlse a substr_replace() fggvnnyel


A substr_replace() hasonlan mkdik, mint a substr(), a klnbsg abban rejlik, hogy itt lehetsg nylik a kivonatolt karakterlnc-rszlet lecserlsre is. A fggvny hrom paramtert vr: az talaktand karakterlncot, a csereszveget s a kezdindexet. Ezek mellett ltezik egy nem ktelez, negyedik hosszsg paramter is. A substr_replace() fggvny megtallja a kezdindex s a hosszsg paramter ltal meghatrozott rszlncot, lecserli azt a csereszvegre, s a teljes talaktott karakterlncot adja vissza. A kvetkez kdrszletben egy felhasznl tagazonostjnak megjtshoz le kell cserlnnk annak harmadik s negyedik karaktert: <? $tagazonosito = "mz99xyz"; $tagazonosito = substr_replace( $tagazonosito, "00", 2, 2 ); print "Az j tagnyilvntart azonost: $tagazonosito<p>"; // azt rja ki, hogy "Az j tagnyilvntart azonost: mz00xyz" ?>

Az sszes rszlnc lecserlse az str_replace() fggvnnyel


Az str_replace() fggvny a keresett karakterlnc-rsz sszes elfordulst lecserli egy msik karakterlncra. Bemenetnek hrom paramtere a lecserlend karakterlnc, a csereszveg s a forrsszveg. A fggvny kimenete az talaktott karakterlnc. A kvetkez pldban egy karakterlncban az 1999 sszes elfordulst 2000-re cserljk: $karakterlanc = "Ezt az oldal 1999-ben szerzi jog ltal vdett"; $karakterlanc .= "Felsoktatsi tjkoztat 1999"; print str_replace("1999","2000",$karakterlanc);

Karakterlncok kezelse

335

Kis- s nagybetk kzti vlts


A PHP tbb fggvnnyel is segtsgnkre van a kis- s nagybetk cserjben. Amikor felhasznlk ltal bert adattal dolgozunk, fontos lehet mindent csupa nagybetsre vagy csupa kisbetsre alaktani, hogy aztn knnyebben sszehasonlthatak legyenek. Az strtoupper() fggvny segtsgvel egy karakterlncot csupa nagybetsre alakthatunk. A fggvny egyetlen bemenete az talaktand szveg, visszatrsi rtke pedig a csupa nagybets karakterlnc: $tagazonosito = "mz00xyz"; $tagazonosito = strtoupper( $tagazonosito ); print "$tagazonosito<P>"; // azt rja ki, hogy "MZ00XYZ" Karakterlncunk csupa kisbetss val alaktshoz hasznljuk az strtolower() fggvnyt. Ennek egyetlen bemenete az talaktand szveg s a csupa kisbets karakterlncot adja vissza: $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" A PHP-nek van egy nagyszer, tneti kezelst biztost fggvnye, az ucwords(). Ez a fggvny egy karakterlnc minden szavnak els betjt teszi nagybetss. A kvetkez programrszletben a felhasznl ltal bert karakterlncban a szavak els betjt nagybetre cserljk: $teljes_nev = "vitz tindi lantos sebestyn"; $teljes_nev = ucwords( $teljes_nev ); print $teljes_nev; // azt rja ki, hogy "Vitz Tindi Lantos Sebestyn" A fggvny kizrlag a szavak els betjt cserli le, gy ha a felhasznlnak nehzsgei vannak a SHIFT billentyvel s azt rta be, hogy "ViTz tINDi laNtos sEBeSTyN", ez a fggvny nem sokban lesz segtsgre, hiszen a tneti kezels eredmnye "ViTz TINDi LaNtos SEBeSTyN" lesz. Ezen gy segthetnk, hogy az ucwords() meghvsa eltt az strtolower() fggvnnyel elszr csupa kisbetss alaktjuk a karakterlncot: $teljes_nev = "ViTz tINDi laNtos sEBeSTyN"; $teljes_nev = ucwords( strtolower($teljes_nev) ); print $teljes_nev; // azt rja ki, hogy "Vitz Tindi Lantos Sebestyn"

17

336

17. ra Fel kell, hogy hvjuk a kedves olvas figyelmt arra, hogy a magyar szvegekkel az kezetes betk miatt alapbelltsban problmink akadhatnak. A nemzeti belltsok testreszabsra hasznlhat setlocale() fggvnyt kell alkalmaznunk, hogy a kvnt eredmnyt elrjk.

Karakterlncok tmbb alaktsa az explode() fggvnnyel


A mksan robbant-nak nevezett fggvny bizonyos mrtkben hasonl az strtok() fggvnyhez. Ez a fggvny azonban egy karakterlncot tmbb bont fel, amit aztn trolhatunk, rendezhetnk, vagy azt tehetnk vele, amit csak szeretnnk. Bemenett kt paramter alkotja, ez egyik egy hatroljel, ami alapjn fel szeretnnk bontani a forrslncot, a msik maga a forrslnc. A hatroljel tbb karakterbl is llhat, ezek egytt fogjk alkotni a hatroljelet. (Ez eltr az strtok() fggvny mkdstl, ahol a megadott karakterlnc minden karaktere egy-egy nll hatroljel lesz.) A kvetkez kdrszlet egy dtumot bont fel rszeire s az eredmnyt egy tmbben trolja: $kezdet = "2000.12.01"; $datum_tomb = explode(".", $kezdet); // $datum_tomb[0] == "2000" // $datum_tomb[1] == "12" // $datum_tomb[2] == "00"

sszefoglals
A PHP klvilggal val kapcsolattartsa s adattrolsa leginkbb karakterlncokon keresztl valsul meg. Az rn a programjainkban lev karakterlncok kezelsvel ismerkedtnk meg. A printf() s az sprintf() fggvnyek segtsgvel megtanultuk formzni a karakterlncokat. Ezt a kt fggvnyt olyan karakterlncok ltrehozsra hasznljuk, amelyek egyrszt talaktjk, msrszt el is rendezik az adatokat. Tanultunk olyan fggvnyekrl, amelyek informcit rulnak el a karakterlncokrl. Meg tudjuk llaptani egy karakterlnc hosszsgt az strlen(), egy rszlnc jelenltt az strpos() fggvnnyel, vagy kiszakthatunk rszlncokat az strtok() segtsgvel. Vgl azokrl a fggvnyekrl tanultunk, amelyek karakterlncokat alaktanak t. Most mr el tudjuk tntetni az elvlaszt karaktereket a trim(), ltrim() vagy a chop() fggvnnyel, vlthatunk a kis- s nagybetk kztt az strtoupper(), az strtolower() s az ucwords() fggvnyekkel, valamint egy karakterlnc sszes elfordulst lecserltethetjk az str_replace() segtsgvel.

Karakterlncok kezelse Ezek utn nehz elhinni, de mg mindig nem vgeztnk a karakterlncokkal. A PHP ugyanis tmogatja a szablyos kifejezseket, amelyek a karakterlnckezels mg hatkonyabb formjt biztostjk. A szablyos kifejezsek alkotjk a kvetkez ra anyagt.

337

17

Krdsek s vlaszok
Vannak mg egyb hasznos karakterlnc-fggvnyek? Vannak. A PHP tbb mint 60 ilyen fggvnnyel rendelkezik! Ezekrl a PHP 4 kziknyvben olvashatunk, amelynek megfelel rsze a http://php.net/manual/ref.strings.php cmen tallhat. A printf() mkdst bemutat pldban a formzst gy jelentettk meg, hogy a kimenetet <PRE> elemek kz tettk. Ez a legjobb mdja a formzott szveg megjelentsnek a bngszben? A <PRE> cmkk akkor szksgesek, ha a sima szveg (plain text) formzst HTML-es krnyezetben is meg szeretnnk tartani. Ha viszont a teljes dokumentumot gy szeretnnk megjelenteni, a legokosabb, ha kzljk a bngszvel, hogy sima szvegknt formzza meg azt. Ez a header() fggvnnyel rhet el: Header("Content-type: text/plain");

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Milyen talakt paramtert hasznlnnk a printf() fggvnyben egy egsz szm lebegpontos szmknt val megformzsra? 2. Hogyan egsztsk ki az 1. krdsben talaktott szmot nullkkal gy, hogy a tizedespont eltti (attl balra es) rsz 4 karakter hosszsg legyen? 3. Hogyan kerektennk az elz krds lebegpontos szmt kt tizedesjegyre? 4. Milyen fggvnyeket hasznlnnk egy szveg hossznak kidertshez? 5. Milyen fggvnyeket hasznlnnk egy rszlnc ms karakterlncon belli kezdetnek meghatrozsra?

338

17. ra 6. Milyen fggvnyeket hasznlnnk arra, hogy egy szvegbl kivonjuk annak egy darabjt? 7. Hogyan tvolthatjuk el az elvlaszt karaktereket egy karakterlnc elejrl? 8. Hogyan alaktannk t egy karakterlncot csupa nagybetsre? 9. Hogyan bontannk fel egy hatroljelekkel elvlasztott karakterlncot tmbkre?

Feladatok
1. Hozzunk ltre egy olyan vlemny-visszajelz rlapot, amely a felhasznl nevt s e-mail cmt kri be. Hasznljuk a kis- s nagybetket talakt fggvnyeket a nevek els betjnek nagybetstsre, majd jelentsk meg az eredmnyt a bngszben. Ellenrizzk, hogy a cm tartalmaz-e @-jelet, ha nem, figyelmeztessk a felhasznlt. 2. Hozzunk ltre egy lebegpontos s egsz szmokbl ll tmbt. Lptessnk vgig a tmbn s kerektsk az sszes lebegpontos szmot kt tizedesjegyre. Igaztsuk jobbra a kimenetet egy 20 karakter szlessg mezben.

18. RA
A szablyos kifejezsek hasznlata
A szvegek vizsglatnak s elemzsnek nagyszer mdja a szablyos kifejezsek (regular expressions) hasznlata. Ezek lehetv teszik, hogy egy karakterlncon bell mintkat keressnk, a tallatokat pedig rugalmasan s pontosan kapjuk vissza. Mivel hatkonyabbak az elz rban tanult karakterlnc-kezel fggvnyeknl, lassabbak is azoknl. gy azt tancsoljuk, hogy ha nincs klnsebb szksgnk a szablyos kifejezsek ltal biztostott hatkonysgra, inkbb hasznljuk a hagyomnyos karakterlnc-kezel fggvnyeket. A PHP a szablyos kifejezsek kt tpust tmogatja. Egyrszt tmogatja a Perl ltal hasznltakat, az azoknak megfelel fggvnyekkel, msrszt a korltozottabb tuds POSIX szablyos kifejezs formt. Mindkettvel meg fogunk ismerkedni. Az ra sorn a kvetkezkrl tanulunk: Hogyan illessznk mintt egy karakterlncra a szablyos kifejezsek segtsgvel? Mik a szablyos kifejezsek formai kvetelmnyei?

340

18. ra Hogyan cserljnk le karakterlncokat szablyos kifejezsekkel? Hogyan keressnk s cserljnk le mintkat egy szvegben a hatkony Perl tpus szablyos kifejezsekkel?

A POSIX szablyos kifejezsek fggvnyei


A POSIX szablyos kifejezseket kezel fggvnyek lehetv teszik, hogy egy szvegben bonyolult mintkat keressnk s cserljnk le. Ezeket ltalban egyszeren szablyoskifejezs-fggvnyeknek szoktk nevezni, mi azonban POSIX szablyoskifejezs-fggvnyekknt utalunk rjuk, egyrszt azrt, hogy megklnbztethessk ket a hasonl, m hatkonyabb Perl tpus szablyos kifejezsektl, msrszt azrt, mert a POSIX bvtett szablyos kifejezs (extended regular expression) szabvnyt kvetik. A szablyos kifejezsek olyan jelegyttesek, amelyek egy szvegben egy mintra illeszkednek. Hasznlatuk elsajttsa gy jval tbbet jelent annl, hogy megtanuljuk a PHP szablyoskifejezs-fggvnyeinek be- s kimeneti paramtereit. Az ismerkedst a fggvnyekkel kezdjk s rajtuk keresztl vezetjk be az olvast a szablyos kifejezsek formai kvetelmnyeibe.

Minta keresse karakterlncokban az ereg() fggvnnyel


Az ereg() bemenete egy mintt jelkpez karakterlnc, egy karakterlnc, amiben keresnk, s egy tmbvltoz, amelyben a keress eredmnyt troljuk. A fggvny egy egsz szmot ad vissza, amely a megtallt minta illeszked karaktereinek szmt adja meg, illetve ha a fggvny nem tallja meg a mintt, a false (hamis) rtket adja vissza. Keressk a "tt"-t az "tdtt tnctanr" karakterlncban. print ereg("tt", "tdtt tnctanr", $tomb); print "<br>$tomb[0]<br>"; // a kimenet: // 2 // tt A "tt" az "tdtt" szban megtallhat, ezrt az ereg() 2-t ad vissza, ez az illeszked betk szma. A $tomb vltoz els elemben a megtallt karakterlnc lesz, amit aztn a bngszben megjelentnk. Felmerlhet a krds, milyen esetben lehet ez hasznos, hiszen elre tudjuk, hogy mi a keresett minta. Nem kell azonban mindig elre meghatrozott karaktereket keresnnk. A pontot (.) hasznlhatjuk tetszleges karakter keressekor:

A szablyos kifejezsek hasznlata print ereg("d.", "tdtt tnctanr", $tomb); print "<br>$tomb[0]<br>"; // a kimenet: // 2 // d A d. minta illeszkedik minden olyan szvegre, amely megfelel annak a meghatrozsnak, hogy egy d bet s egy azt kvet tetszleges karakter. Ebben az esetben nem tudjuk elre, mi lesz a msodik karakter, gy a $tomb[0] rtke mris rtelmet nyer.

341

18

Egynl tbbszr elfordul karakter keresse mennyisgjelzvel


Amikor egy karakterlncban egy karaktert keresnk, egy mennyisgjelzvel (kvantorral) hatrozhatjuk meg, hnyszor forduljon el a karakter a mintban. Az a+ minta pldul azt jelenti, hogy az "a"-nak legalbb egyszer el kell fordulnia, amit 0 vagy tbb "a" bet kvet. Prbljuk ki: if ( ereg("a+","aaaa", $tomb) ) print $tomb[0]; // azt rja ki, hogy "aaaa"; Vegyk szre, hogy ez a szablyos kifejezs annyi karakterre illeszkedik, amennyire csak tud. A 18.1. tblzat az ismtld karakterek keressre szolgl mennyisgjelzket ismerteti.

18.1. tblzat Az ismtld karakterek mennyisgjelzi


Jel
* + ? {n} {n,} {,n} {n1,n2}

Lers
Nulla vagy tbb elforduls Egy vagy tbb elforduls Nulla vagy egy elforduls n elforduls Legalbb n elforduls Legfeljebb n elforduls Legalbb n1 s legfeljebb n2 elforduls

Plda
a* a+ a? a{3} a{3,} a{,2} a{1,2}

Erre illeszkedik xxxx


xaax xaxx xaaa aaaa xaax xaax

Erre nem illeszkedik (Mindenre illeszkedik)


xxxx xaax aaaa aaxx aaax xaaa

342

18. ra A kapcsos zrjelben lev szmok neve korlt. Segtsgkkel hatrozhatjuk meg, hnyszor ismtldjn egy adott karakter, hogy a minta rvnyes legyen r. JDONSG A korlt hatrozza meg, hogy egy karakternek vagy karakterlncnak hnyszor kell ismtldnie egy szablyos kifejezsben. Az als s fels hatrt a kapcsos zrjelen bell hatrozzuk meg. Pldul az a{4,5} kifejezs az a ngynl nem kevesebb s tnl nem tbb elfordulsra illeszkedik. Vegynk egy pldt. Egy klub tagsgi azonostval jelli tagjait. Egy rvnyes azonostban egy s ngy kztti alkalommal fordul el a "t", ezt tetszleges szm szm vagy bet karakter kveti, majd a 99-es szm zrja. A klub arra krt fel bennnket, hogy a tennivalkat tartalmaz naplbl emeljk ki a tagazonostkat. $proba = "A ttXGDH99 tagunk befizette mr a tagsgi djat?"; if ( ereg( "t{1,4}.*99 ", $proba, $tomb ) ) print "A megtallt azonost: $tomb[0]"; // azt rja ki, hogy "A megtallt azonost: ttXGDH99" Az elz kdrszletben a tagazonost kt t karakterrel kezddik, ezt ngy nagybet kveti, majd vgl a 99 jn. A t{1,4} minta illeszkedik a kt t-re, a ngy nagybett pedig megtallja a .*, amellyel tetszleges szm, tetszleges tpus karakterlncot kereshetnk. gy tnik, ezzel megoldottuk a feladatot, pedig mg attl meglehetsen tvol llunk. A felttelek kztt a 99-cel val vgzdst azzal prbltuk biztostani, hogy megadtuk, hogy egy szkz legyen az utols karakter. Ezt aztn tallat esetn vissza is kaptuk. Mg ennl is nagyobb baj, hogy ha a forrslnc "Azonostm ttXGDH99 megkaptad mr az 1999 -es tagsgi djat?" akkor a fenti szablyos kifejezs a kvetkez karakterlncot talln meg: "tm ttXGDH99 megkaptad mr az 1999" Mit rontottunk el? A szablyos kifejezs megtallta a t bett az azonostm szban, majd utna a tetszleges szm karaktert egszen a szkzzel zrt 99-ig. Jellemz a szablyos kifejezsek mohsgra, hogy annyi karakterre illeszkednek, amennyire csak tudnak. Emiatt trtnt, hogy a minta egszen az 1999-ig illeszkedett, a 99-re vgzd azonost helyett. A hibt kijavthatjuk, ha biztosan tudjuk, hogy a t s a 99 kztti karakterek kizrlag betk vagy szmok s egyikk sem szkz. Az ilyen feladatokat egyszerstik le a karakterosztlyok.

A szablyos kifejezsek hasznlata

343

Karakterlnc keresse karakterosztlyokkal


Az eddigi esetekben megadott karakterekkel vagy a . segtsgvel kerestnk karaktereket. A karakterosztlyok lehetv teszik, hogy karakterek meghatrozott csoportjt keressk. A karakterosztly meghatrozshoz a keresend karaktereket szgletes zrjelek kz rjuk. Az [ab] minta egyetlen betre illeszkedik, ami vagy a vagy b. A karakterosztlyokat meghatrozsuk utn karakterknt kezelhetjk, gy az [ab]+ az aaa, bbb s ababab karakterlncokra egyarnt illeszkedik. Karaktertartomnyokat is hasznlhatunk karakterosztlyok megadsra: az [a-z] tetszleges kisbetre, az [A-Z] tetszleges nagybetre, a [0-9] pedig tetszleges szmjegyre illeszkedik. Ezeket a sorozatokat s az egyedi karaktereket egyetlen karakterosztlyba is gyrhatjuk, gy az [a-z5] minta tetszleges kisbetre vagy az 5-s szmra illeszkedik. A karakterosztlyokat tagadhatjuk is, a cscsos kezet (^) kezd szgletes zrjel utn val rsval: az [^A-Z] mindenre illeszkedik, csak a nagybetkre nem. Trjnk vissza legutbbi pldnkra. Mintt kell illesztennk egy 1 s 4 kztti alkalommal elfordul betre, amelyet tetszleges szm bet vagy szmjegy karakter kvet, amit a 99 zr. $proba = "Azonostm ttXGDH99 megkaptad mr az 1999 -es tagsgi djat?"; if ( ereg( "t{1,4}[a-zA-Z0-9]*99 ", $proba, $tomb ) ) print "A megtallt azonost: $tomb[0]"; // azt rja ki, hogy "A megtallt azonost: ttXGDH99 " Szp lassan alakul. Az a karakterosztly, amit hozzadtunk, mr nem fog szkzkre illeszkedni, gy vgre az azonostt kapjuk meg. Viszont ha az azonost utn a prba-karakterlnc vgre vesszt runk, a szablyos kifejezs megint nem illeszkedik: $proba = "Azonostm ttXGDH99, megkaptad mr az 1999 -es tagsgi djat?"; if ( ereg( "t{1,4}[a-zA-Z0-9]*99 ", $proba, $tomb ) ) print "A megtallt azonost: $tomb[0]"; // a szablyos kifejezs nem illeszkedik Ez azrt van, mert a minta vgn egy szkzt vrunk el, amely alapjn meggyzdhetnk, hogy elrtk az azonost vgt. gy ha egy szvegben az azonost zrjelek kzt van, ktjel vagy vessz kveti, a minta nem illeszkedik r. Kzelebb visz a megoldshoz, ha gy javtunk a szablyos kifejezsen, hogy mindenre illeszkedjk, csak szm s bet karakterekre nem:

18

344

18. ra $proba = "Azonostm ttXGDH99, megkaptad mr az 1999 -es tagsgi djat?"; if ( ereg( "t{1,4}[a-zA-Z0-9]*99[^a-zA-Z0-9]", $proba, $tomb ) ) print "A megtallt azonost: $tomb[0]"; // azt rja ki, hogy "A megtallt azonost: ttXGDH99, " Mr majdnem ksz is vagyunk, de mg mindig van kt problma. Egyrszt a vesszt is visszakapjuk, msrszt a szablyos kifejezs nem illeszkedik, ha az azonost a karakterlnc legvgn van, hiszen megkveteltk, hogy utna mg egy karakter legyen. Ms szval a szhatrt kellene megbzhat mdon megtallnunk. Erre a problmra ksbb mg visszatrnk.

Az atomok kezelse
JDONSG Az atom egy zrjelek kz rt minta (gyakran hivatkoznak r rszmintaknt is). Meghatrozsa utn az atomot ugyangy kezelhetjk, mintha maga is egy karakter vagy karakterosztly lenne. Ms szval ugyanazt a 18.1. tblzatban bemutatott rendszer alapjn felptett mintt annyiszor kereshetjk, ahnyszor csak akarjuk. A kvetkez kdrszletben meghatrozunk egy mintt, zrjelezzk, s az gy kapott atomnak ktszer kell illeszkednie a keresend szvegre: $proba = "abbaxaabaxabbax"; if ( ereg( "([ab]+x){2}", $proba, $tomb ) ) print "$tomb[0]"; // azt rja ki, hogy "abbaxaabax" Az [ab]+x illeszkedik az "abbax" s az "aabax" karakterlncokra egyarnt, gy az ([ab]+x){2} illeszkedni fog az "abbaxaabax" karakterlncra. Az ereg() fggvnynek tadott tmbvltoz els elemben kapjuk vissza a teljes, megtallt, illeszked karakterlncot. Az ezt kvet elemek az egyes megtallt atomokat tartalmazzk. Ez azt jelenti, hogy a teljes tallat mellett a megtallt minta egyes rszeihez is hozzfrhetnk. A kvetkez kdrszletben egy IP cmre illesztnk mintt, s nem csupn a teljes cmet troljuk, hanem egyes alkotelemeit is:

A szablyos kifejezsek hasznlata $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 eredmny: // 158.152.55.35 // 158 // 152 // 55 // 35 Vegyk szre, hogy a pontokat a szablyos kifejezsben fordtott perjel elzte meg. Ezzel fejeztk ki, hogy a . karaktert itt minden klnleges tulajdonsga nlkl, egyszer karakterknt szeretnnk kezelni. Minden olyan karakternl ez a kvetend eljrs, amely egyedi szereppel br a szablyos kifejezsekben.

345

18

Elgazsok
A szrkarakter (|) segtsgvel mintkat sszektve a szablyos kifejezseken bell elgazsokat hozhatunk ltre. Egy ktg szablyos kifejezs vagy az els mintra, vagy a msodik mintra illeszked karakterlncokat keresi meg. Ettl lesz a szablyos kifejezsek nyelvtana mg rugalmasabb. A kvetkez kdrszletben a .com, a .de vagy a .hu karakterlncot keressk: $domain = "www.egydomain.hu"; if ( ereg( "\.com|\.de|\.hu", $domain, $tomb ) ) print "ez egy $tomb[0] tartomny<BR>"; // azt rja ki, hogy "ez egy .hu tartomny"

A szablyos kifejezs helye


Nemcsak a keresend mintt adhatjuk meg, hanem azt is, hol illeszkedjen egy karakterlncban. Ha a mintt a karakterlnc kezdetre szeretnnk illeszteni, a szablyos kifejezs elejre rjunk egy cscsos kezetet (^). A ^a illeszkedik az "alma", de nem illeszkedik a "bann" szra. A karakterlnc vgn gy illeszthetjk a mintt, hogy dollrjelet ($) runk a szablyos kifejezs vgre. Az a$ illeszkedik a "rka", de nem illeszkedik a "hal" szra.

346

18. ra

A tagazonostt keres plda jragondolsa


Most mr rendelkezsnkre llnak azok az eszkzk, melyekkel megoldhatjuk a tagazonosts problmjt. Emlkeztetl, a feladat az volt, hogy szvegeket elmezve kigyjtsk azokat a tagazonostkat, amelyekben a "t" egy s ngy kztti alkalommal fordul el, ezt tetszleges szm szm vagy bet karakter kveti, amelyet a 99 zr. Jelenlegi problmnk az, hogyan hatrozzuk meg, hogy illeszked mintnknak szhatrra kell esnie. Nem hasznlhatjuk a szkzt, mivel a szavakat rsjelekkel is el lehet vlasztani. Az sem lehet felttel, hogy egy nem alfanumerikus karakter alkossa a hatrt, hiszen a tagazonost lehet, hogy ppen a szveg elejn vagy vgn tallhat. Most, hogy kpesek vagyunk elgazsokat megadni s helyhez ktni a szablyos kifejezseket, megadhatjuk felttelknt, hogy a tagazonostt vagy egy nem szm vagy bet karakter kvesse, vagy pedig a karakterlnc vge. Ugyanezzel a gondolatmenettel adhatjuk meg a kd elejn elfordul szhatrt is. A zrjelek hasznlatval a tagazonostt minden kzpontozs s szkz nlkl kaphatjuk vissza: $proba = "Azonostm ttXGDH99, megkaptad mr az 1999 -es tagsgi djat?"; if ( ereg( "(^|[^a-zA-Z0-9])(t{1,4}[a-zA-Z0-9]*99)([^a-zAZ0-9]|$)", $proba, $tomb ) ) print "A megtallt azonost: $tomb[2]"; // azt rja ki, hogy "A megtallt azonost: ttXGDH99" Amint lthatjuk, a szablyos kifejezsek elsre egy kicsit riasztk, de miutn kisebb egysgekre bontjuk azokat, ltalban egsz knnyen rtelmezhetk. Elrtk, hogy mintnk egy szhatrra illeszkedjen (pontosan gy, ahogy azt a feladat megkvetelte). Mivel nem vagyunk kvncsiak semmilyen, a mintt megelz vagy kvet szvegre, a minta szmunkra hasznos rszt zrjelek kz rjuk. Az eredmnyt a $tomb tmb harmadik (2-es index) elemben tallhatjuk meg. Az ereg() megklnbzteti a kis- s nagybetket. Ha nem szeretnnk megklnbztetni ket, hasznljuk az eregi() fggvnyt, amely egybknt minden ms tekintetben megegyezik az ereg() fggvnnyel.

A szablyos kifejezsek hasznlata

347

Mintk lecserlse karakterlncokban az ereg_replace() fggvnnyel


Eddig csupn mintkat kerestnk a karakterlncokban, magt a karakterlncot nem mdostottuk. Az ereg_replace() fggvny lehetv teszi, hogy megkeressk s lecserljk az adott szveg egy mintra illeszked rszlnct. Bemenete hrom karakterlnc: egy szablyos kifejezs, a csereszveg, amivel fell szeretnnk rni a megtallt mintt s a forrsszveg, amelyben keresnk. Tallat esetn a fggvny a megvltoztatott karakterlncot adja vissza, ellenkez esetben az eredeti forrsszveget kapjuk. A kvetkez kdrszletben egy klubtisztvisel nevt keressk ki, majd fellrjuk utdjnak nevvel: $proba = "Titkrunk, Vilmos Sarolta, szeretettel dvzli nt."; print ereg_replace ("Vilmos Sarolta", "Lszl Istvn", $proba); // azt rja ki, hogy " Titkrunk, Lszl Istvn, szeretettel dvzli nt." Fontos megjegyezni, hogy mg az ereg() fggvny csak a legels megtallt mintra illeszkedik, az ereg_replace() a minta sszes elfordulst megtallja s lecserli.

18

Visszautals hasznlata az ereg_replace() fggvnnyel


A visszautalsok azt teszik lehetv, hogy az illeszked kifejezs egy rszt felhasznlhassuk a fellr karakterlncban. Ehhez szablyos kifejezsnk sszes felhasznland elemt zrjelbe kell rnunk. Ezekre a rszmintk segtsgvel megtallt karakterlncokra kt fordtott perjellel s az atom szmval hivatkozhatunk (pldul \\1) a cserelncokban. Az atomok sorszmozottak, a sorszmozs kvlrl befel, balrl jobbra halad s \\1-tl indul. A \\0 az egsz illeszked karakterlncot jelenti. A kvetkez kdrszlet a hh/nn/ formtum dtumokat alaktja .hh.nn. formtumv: $datumt = "12/25/2000"; print ereg_replace("([0-9]+)/([0-9]+)/([0-9]+)", "\\3.\\1.\\2.", $datum); // azt rja ki, hogy "2000.12.25" Vegyk szre, hogy a fenti kd csereszvegben a pontok nem klnleges rtelmek, gy nem is kell \ jelet tenni eljk. A . az els paramterben kapja a tetszleges karakterre illeszkeds klnleges jelentst.

348

18. ra

Az ereg_replace() fggvny megklnbzteti a kis- s nagybetket. Ha nem szeretnnk megklnbztetni ezeket, hasznljuk az eregi_replace() fggvnyt, amely minden ms tekintetben megegyezik az ereg_replace() fggvnnyel.

Karakterlncok felbontsa a split() fggvnnyel


Az elz rban mr lttuk, hogy az explode() fggvny segtsgvel egy karakterlncot elemeire bontva tmbknt kezelhetnk. Az emltett fggvny hatkonysgt az cskkenti, hogy hatroljelknt csak egy karakterhalmazt hasznlhatunk. A PHP 4 split() fggvnye a szablyos kifejezsek hatkonysgt biztostja, vele rugalmas hatroljelet adhatunk meg. A fggvny bemenete a hatroljelknt hasznlt minta s a forrslnc, amelyben a hatrolkat keressk, kimenete pedig egy tmb. A fggvny harmadik, nem ktelez paramtere a visszaadand elemek legnagyobb szmt hatrozza meg. A kvetkez pldban egy elgaz szablyos kifejezssel egy karakterlncot bontunk fel, gy, hogy a hatroljel egy vessz s egy szkz vagy egy szkzkkel kzrefogott s sz: $szoveg = "almk, narancsok, krtk s barackok"; $gyumolcsok = split(", | s ", $szoveg); foreach ( $gyumolcsok as $gyumolcs ) print "$gyumolcs<BR>"; // a kimenet: // almk // narancsok // krtk // barackok

Perl tpus szablyos kifejezsek


Ha Perls httrrel kzeltjk meg a PHP-t, akkor a POSIX szablyos kifejezsek fggvnyeit valamelyest nehzkesnek tallhatjuk. A j hr viszont az, hogy a PHP 4 tmogatja a Perlnek megfelel szablyos kifejezseket is. Ezek formja mg az eddig tanultaknl is hatkonyabb. Ebben a rszben a kt szablyoskifejezs-forma kztti klnbsgekkel ismerkednk meg.

A szablyos kifejezsek hasznlata

349

Mintk keresse a preg_match() fggvnnyel


A preg_match() fggvny hrom paramtert vr: egy szablyos kifejezst, a forrslncot s egy tmbvltozt, amelyben az illeszked karakterlncokat adja vissza. A true (igaz) rtket kapjuk vissza, ha illeszked kifejezst tall s false (hamis) rtket, ha nem. A preg_match() s az ereg_match() fggvnyek kztti klnbsg a szablyos kifejezst tartalmaz paramterben van. A Perl tpus szablyos kifejezseket hatroljelek kz kell helyezni. ltalban perjeleket hasznlunk hatroljelknt, br ms, nem szm vagy bet karaktert is hasznlhatunk (kivtel persze a fordtott perjel). A kvetkez pldban a preg_match() fggvnnyel egy h-valami-z mintj karakterlncot keresnk: $szoveg = "veghz"; if ( preg_match( "/h.*z/", $szoveg, $tomb ) ) print $tomb[0]; // azt rja ki, hogy "hz"

18

A Perl tpus szablyos kifejezsek s a mohsg


Alaprtelmezs szerint a szablyos kifejezsek megksrelnek a lehet legtbb karakterre illeszkedni. gy a "/h.*z/" minta a h-val kezdd s z karakterre vgzd lehet legtbb karaktert kzrefog karakterlncra fog illeszkedni, a kvetkez pldban a teljes szvegre: $szoveg = "hz hz hlyz hazardroz"; if ( preg_match( "/h.*z/", $szoveg, $tomb ) ) print $tomb[0]; // azt rja ki, hogy "hz hz hlyz hazardroz" Viszont ha krdjelet (?) runk a mennyisget kifejez jel utn, rvehetjk a Perl tpus szablyos kifejezst, hogy egy kicsit mrtkletesebb legyen. gy mg a "h.*z" minta azt jelenti, hogy h s z kztt a lehet legtbb karakter, a "h.*?z" minta jelentse a h s z kztti lehet legkevesebb karakter.

350

18. ra A kvetkez kdrszlet ezzel a mdszerrel keresi meg a legrvidebb szt, amely h-val kezddik s z-vel vgzdik: $szoveg = "hz hz hlyz hazardroz"; if ( preg_match( "/h.*?z/", $szoveg, $tomb ) ) print $tomb[0]; // azt rja ki, hogy "hz"

A Perl tpus szablyos kifejezsek s a fordtott perjeles karakterek


A Perl tpus szablyos kifejezsekben is vezrlkarakterr vltoztathatunk bizonyos karaktereket, ugyangy, mint ahogy azt karakterlncokkal tettk. A \t pldul a tabultor karaktert jelenti, az \n pedig a soremelst. Az ilyen tpus szablyos kifejezsek olyan karaktereket is lerhatnak, amelyek teljes karakterhalmazokra, karaktertpusokra illeszkednek. A fordtott perjeles karakterek listjt a 18.2. tblzatban lthatjuk.

18.2. tblzat Karaktertpusokra illeszked beptett karakterosztlyok


Karakter \d
\D \s \S \w \W

Illeszkedik Brmely szmra


Mindenre, ami nem szm Brmely elvlaszt karakterre Mindenre, ami nem elvlaszt karakter Brmely szalkot karakterre (alhzst is belertve) Mindenre, ami nem szalkot karakter

Ezek a karakterosztlyok nagymrtkben leegyszersthetik a szablyos kifejezseket. Nlklk karaktersorozatok keressekor sajt karakterosztlyokat kellene hasznlnunk. Vessk ssze a szalkot karakterekre illeszked mintt az ereg() s a preg_match() fggvnyben: ereg( "h[a-zA-Z0-9_]+z", $szoveg, $tomb ); preg_match( "/h\w+z", $szoveg, $tomb ); A Perl tpus szablyos kifejezsek tbb vltkaraktert is tmogatnak, melyek hivatkozsi pontknt mkdnek. A hivatkozsi pontok a karakterlncon bell helyekre illeszkednek, nem pedig karakterekre. Ismertetsket a 18.3. tblzatban tallhatjuk.

A szablyos kifejezsek hasznlata

351

18.3. tblzat Hivatkozsi pontknt hasznlt vltkarakterek


Karakter \A
\b \B \Z \z

Illeszkedik Karakterlnc kezdetre


Szhatrra Mindenre, ami nem szhatr Karakterlnc vgre (az utols soremels vagy a karakterlnc vge eltt illeszkedik) Karakterlnc vgre (a karakterlnc legvgre illeszkedik)

18

Emlksznk mg, milyen problmink voltak a szhatrra val illesztssel a tagsgi azonostst megvalst pldban? A Perl tpus szablyos kifejezsek jelentsen leegyszerstik ezt a feladatot. Vessk ssze, hogyan illeszt mintt szalkot karakterre s szhatrra az ereg() s a preg_match(): 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 ); Az elz pldban a preg_match() fggvny meghvsakor a szhatron lev legalbb egy, de legfeljebb ngy t karakterre illeszkedik, amelyet brmennyi szvegalkot karakter kvethet s amit a szhatron lev 99 karaktersor zr. A szhatrt jell vltkarakter igazbl nem is egy karakterre illeszkedik, csupn megersti, hogy az illeszkedshez szhatr kell. Az ereg_match() meghvshoz elszr ltre kell hoznunk egy nem szalkot karakterekbl ll mintt, majd vagy arra, vagy pedig szhatrra kell illeszteni. A vltkaraktereket arra is hasznlhatjuk, hogy megszabaduljunk a karakterek jelentstl. Ahhoz pldul, hogy egy . karakterre illeszthessnk, egy fordtott perjelet kell el rnunk.

Teljeskr keress a preg_match_all() fggvnnyel


A POSIX szablyos kifejezsekkel az az egyik problma, hogy a minta karakterlncon belli sszes elfordulst bonyolult megkeresni. gy ha az ereg() fggvnnyel keressk a b-vel kezdd, t-vel vgzd szavakat, csak a legels tallatot kapjuk vissza. Prbljuk meg magunk is:

352

18. ra $szoveg = "barackot, bannt, bort, bzt s bkkat rulok"; if ( ereg( "(^|[^a-zA-Z0-9_])(b[a-zA-Z0-9_]+t) ([^a-zA-Z0-9_]|$)", $szoveg, $tomb ) ) { for ( $x=0; $x< count( $tomb ); $x++ ) print "\$tomb[$x]: $tomb[$x]<br>\n"; } // kimenete: // $tomb[0]: barackot, // $tomb[1]: // $tomb[2]: barackot // $tomb[3]: , Ahogy azt vrtuk, a $tomb harmadik elemben talljuk az els tallatot, a "barackot". A tmb els eleme tartalmazza a teljes tallatot, a msodik a szkzt, a negyedik a vesszt. Hogy megkapjuk az sszes illeszked kifejezst a szvegben, az ereg_replace() fggvnyt kellene hasznlnunk, ciklikusan, hogy eltvoltsuk a tallatokat a szvegbl, mieltt jra illesztennk a mintt. Fel kell, hogy hvjuk a kedves olvas figyelmt arra, hogy a magyar szvegekre az kezetes betk miatt alapbelltsban nem alkalmazhat a fentihez hasonl egyszer szablyos kifejezs. A nemzeti belltsok testreszabsra hasznlhat setlocale() fggvnyt kell alkalmaznunk, hogy a kvnt eredmnyt elrjk. A preg_match_all() fggvnyt hasznlhatjuk arra, hogy egyetlen hvsbl a minta sszes elfordulst megkapjuk. A preg_match_all() bemenete egy szablyos kifejezs, a forrslnc s egy tmbvltoz. Tallat esetn true (igaz) rtket ad vissza. A tmbvltoz egy tbbdimenzis tmb lesz, melynek els eleme a szablyos kifejezsben megadott mintra illeszked sszes tallatot tartalmazza. A 18.1. programban a preg_match_all() fggvnnyel illesztettk mintnkat egy szvegre. Kt for ciklust hasznlunk, hogy megjelentsk a tbbdimenzis eredmnytmbt.

18.1. program Minta teljeskr illesztse a preg_match_all() fggvnnyel


1: <html> 2: <head> 3: <title>18.1. program Minta teljeskr illesztse a preg_match_all() fggvnnyel</title> 4: </head> 5: <body>

A szablyos kifejezsek hasznlata

353

18.1. program (folytats)


6: <?php 7: $szoveg = "barackot, bannt, bort, bzt s bkkat rulok"; 8: if ( preg_match_all( "/\bb\w+t\b/", $szoveg, $tomb ) ) 9: { 10: for ( $x=0; $x< count( $tomb ); $x++ ) 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]: bannt 19: // $tomb[0][2]: bort 20: // $tomb[0][3]: bzt 21: // $tomb[0][4]: bkkat 22: ?> 23: </body> 24: </html> A $tomb vltoznak a preg_match_all() fggvnynek trtn tadskor csak az els eleme ltezik s ez karakterlncok egy tmbjbl ll. Ez a tmb tartalmazza a szveg minden olyan szavt, amely b-vel kezddik s t betre vgzdik. A preg_match_all() ebbl a tmbbl azrt kszt egy tbbdimenzisat, hogy az atomok tallatait is trolhassa. A preg_match_all() fggvnynek tadott tmb els eleme tartalmazza a teljes szablyos kifejezs minden egyes tallatt. Minden tovbbi elem a szablyos kifejezs egyes atomjainak (zrjeles rszmintinak) rtkeit tartalmazza az egyes tallatokban. gy a preg_match_all() albbi meghvsval $szoveg = "01-05-99, 01-10-99, 01-03-00"; preg_match_all( "/(\d+)-(\d+)-(\d+)/", $szoveg, $tomb ); a $tomb[0] az sszes tallat tmbje: $tomb[0][0]: 01-05-99 $tomb[0][1]: 01-10-99 $tomb[0][2]: 01-03-00 A $tomb[1] az els rszminta rtkeinek tmbje: $tomb[1][0]: 01

18

354 $tomb[1][1]: $tomb[1][2]: A $tomb[2] a $tomb[2][0]: $tomb[2][1]: $tomb[2][2]: s gy tovbb.

18. ra 01 01 msodik rszminta rtkeinek tmbjt trolja: 05 10 03

Mintk lecserlse a preg_replace() fggvnnyel


A preg_replace() hasznlata megegyezik az ereg_replace() hasznlatval, azzal a klnbsggel, hogy hozzfrnk a Perl tpus szablyos kifejezsek ltal knlt knyelmi lehetsgekhez. A preg_replace() bemenete egy szablyos kifejezs, egy csere-karakterlnc s egy forrslnc. Tallat esetn a mdostott karakterlncot, ellenkez esetben magt a forrslncot kapjuk vissza vltoztats nlkl. A kvetkez kdrszlet a nn/hh/ formtum dtumokat alaktja t /hh/nn formtumv: $szoveg = "25/12/99, 14/5/00"; $szoveg = preg_replace( "|\b(\d+)/(\d+)/(\d+)\b|", "\\3/\\2/\\1", $szoveg ); print "$szoveg<br>"; // azt rja ki, hogy "99/12/25, 00/5/14" Vegyk szre, hogy a szrkaraktert (|) hasznltuk hatroljelknt. Ezzel megtakartottuk a perjelek kikerlsre hasznland vltkaraktereket az illesztend mintban. A preg_replace() ugyangy tmogatja a visszautalsokat a csereszvegben, mint az ereg_replace(). A preg_replace() fggvnynek a forrslnc helyett karakterlncok egy tmbjt is tadhatjuk, az ebben az esetben minden tmbelemet egyesvel talakt. Ilyenkor a visszaadott rtk az talaktott karakterlncok tmbje lesz. Emellett a preg_replace() fggvnynek szablyos kifejezsek s csere-karakterlncok tmbjt is tadhatjuk. A szablyos kifejezseket egyenknt illeszti a forrslncra s a megfelel csereszveggel helyettesti. A kvetkez pldban az elz plda formtumait alaktjuk t, de emellett a forrslnc szerzi jogi (copyright) informcijt is mdostjuk: $szoveg = "25/12/99, 14/5/00. Copyright 1999"; $miket = array( "|\b(\d+)/(\d+)/(\d+)\b|", "/([Cc]opyright) 1999/" ); $mikre = array( "\\3/\\2/\\1", "\\1 2000" );

A szablyos kifejezsek hasznlata $szoveg = preg_replace( $miket, $mikre, $szoveg ); print "$szoveg<br>"; // azt rja ki, hogy "99/12/25, 00/5/14. Copyright 2000" Kt tmbt hozunk ltre. A $miket tmb kt szablyos kifejezst, a $mikre tmb pedig csere-karakterlncokat tartalmaz. A $miket tmb els eleme a $mikre tmb els elemvel helyettestdik, a msodik a msodikkal, s gy tovbb. Ha a csere-karakterlncok tmbje kevesebb elemet tartalmaz, mint a szablyos kifejezsek, a csere-karakterlnc nlkl marad szablyos kifejezseket a fggvny res karakterlncra cserli. Ha a preg_replace() fggvnynek szablyos kifejezsek egy tmbjt adjuk t, de csak egy cserelncot, akkor az a szablyos kifejezsek tmbjnek sszes mintjt ugyanazzal a csereszveggel helyettesti.

355

18

Mdost paramterek
A Perl tpus szablyos kifejezsek lehetv teszik, hogy mdost paramterek segtsgvel pontostsuk a minta illesztsi mdjt. JDONSG A mdost paramter olyan bet, amelyet a Perl tpus szablyos kifejezsek utols hatroljele utn runk, s amely tovbb finomtja szablyos kifejezseink jelentst. A Perl tpus szablyos kifejezsek mdost paramtereit a 18.4. tblzatban tallhatjuk.

18.4. tblzat A Perl tpus szablyos kifejezsek mdost paramterei


Minta i
e m s x

Lers Nem klnbzteti meg a kis- s nagybetket.


A preg_replace() cserelnct PHP-kdknt kezeli. A $ s a ^ az aktulis sor elejre s vgre illeszkedik. A soremelsre is illeszkedik (a soremelsek ltalban nem illeszkednek a .-ra). A karakterosztlyokon kvli elvlaszt karakterekre az olvashatsg rdekben nem illeszkedik. Ha elvlaszt karakterekre szeretnnk mintt illeszteni, hasznljuk a \s, \t, vagy a \ (fordtott perjelszkz) mintkat.

356

18. ra

18.4. tblzat. (folytats)


Minta A
E U

Lers Csak a karakterlnc elejn illeszkedik (ilyen megszorts nincs a Perlben).


Csak a karakterlnc vgn illeszkedik (ilyen megszorts nincs a Perlben). Kikapcsolja a szablyos kifejezsek mohsgt, azaz a lehet legkevesebb karaktert tartalmaz tallatokat adja vissza (ez a mdost sem tallhat meg Perlben).

Ahol ezek a megszortsok nem mondanak egymsnak ellent, egyszerre tbbet is hasznlhatunk bellk. Az x megszortst pldul arra hasznlhatjuk, hogy knnyebb legyen olvasni a szablyos kifejezseket, az i megszortst pedig arra, hogy mintnk kis- s nagybetktl fggetlenl illeszkedjk a szvegre. A / k \S* r /ix kifejezs pldul illeszkedik a "kar" s "KAR" szavakra, de a "K A R" szra mr nem. Az x-szel mdostott szablyos kifejezsek vltkarakter nlkli szkzei nem fognak illeszkedni semmire sem a forrslncban, a klnbsg csupn eszttikai lesz. Az m paramter akkor jhet jl, ha egy szveg tbb sorban szeretnnk hivatkozsi pontos mintra illeszteni. A ^ s $ mintk alaprtelmezs szerint a teljes karakterlnc elejt s vgt jelzik. A kvetkez kdrszletben az m paramterrel mdostjuk a $^ viselkedst: $szoveg = "nv: pter\nfoglalkozs: programoz\nszeme: kk\n"; preg_match_all( "/^\w+:\s+(.*)$/m", $szoveg, $tomb ); foreach ( $tomb[1] as $ertek ) print "$ertek<br>"; // kimenet: // pter // programoz // kk Egy olyan szablyos kifejezst hozunk ltre, amely olyan mintra illeszkedik, amelyben brmely szalkot karaktert vessz s tetszleges szm szkz kvet. Ezutn tetszleges szm karaktert kvet karakterlnc vge karakterre ($) illesztnk. Az m paramter miatt a $ az egyes sorok vgre illeszkedik a teljes karakterlnc vge helyett.

A szablyos kifejezsek hasznlata Az s paramter akkor jn jl, ha a . karakterrel szeretnnk tbbsoros karakterlncban karakterekre illeszteni. A kvetkez pldban megprblunk a karakterlnc els s utols szavra keresni: $szoveg = "kezdetknt indtsunk ezzel a sorral\ns gy egy kvetkeztetshez\n rkezhetnk el vgl\n"; preg_match( "/^(\w+).*?(\w+)$/", $szoveg, $tomb ); print "$tomb[1] $tomb[2]<br>"; Ez a kd semmit nem r ki. Br a szablyos kifejezs megtallja a szalkot karaktereket a karakterlnc kezdetnl, a . nem illeszkedik a szvegben tallhat soremelsre. Az s paramter ezen vltoztat: $szoveg = "kezdetknt indtsunk ezzel a sorral\ns gy egy kvetkeztetshez\n rkezhetnk el vgl\n"; preg_match( "/^(\w+).*?(\w+)$/s", $szoveg, $tomb ); print "$tomb[1] $tomb[2]<br>"; // azt rja ki, hogy "kezdetknt vgl" Az e paramter klnlegesen hasznos lehet szmunkra, hiszen lehetv teszi, hogy a preg_replace() fggvny csereszvegt PHP kdknt kezeljk. A fggvnyeknek paramterknt visszautalsokat vagy szmokbl ll listkat adhatunk t. A kvetkez pldban az e paramterrel adunk t illesztett szmokat egy fggvnynek, amely ugyanazt a dtumot ms formban adja vissza. <?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; // ezt rja ki: // 1999. 03. 18. // 2000. 07. 22. ?>

357

18

358

18. ra Hrom, perjelekkel elvlasztott szmhalmazt keresnk s a zrjelek hasznlatval rgztjk a megtallt szmokat. Mivel az e mdost paramtert hasznljuk, a cserelnc paramterbl meghvhatjuk az ltalunk meghatrozott datumAtalakito() fggvnyt, gy, hogy a hrom visszautalst adjuk t neki. A datumAtalakito() csupn fogja a szmbemenetet s egy jobban fest dtumm alaktja, amellyel aztn kicserli az eredetit.

sszefoglals
A szablyos kifejezsek hatalmas tmakrt alkotnak, mi csak felletesen ismerkedtnk meg velk ezen ra sorn. Arra viszont mr biztosan kpesek lesznk, hogy bonyolult karakterlncokat talljunk meg s cserljnk le egy szvegben. Megismerkedtnk az ereg() szablyoskifejezs-fggvnnyel, amellyel karakterlncokban mintkat kereshetnk, illetve az ereg_replace()-szel, amellyel egy minta sszes elfordulst cserlhetjk le. A karakterosztlyok hasznlatval karakterlncokat, a mennyisgjelzk hasznlatval tbb mintt, az elgazsokkal mintkat vagylagosan kereshetnk. Rszmintkat is kigyjthetnk s rjuk visszautalsokkal hivatkozhatunk. A Perl tpus szablyos kifejezsekben vltkarakterekkel hivatkozsi pontos illesztst krhetnk, de karakterosztlyok illesztsre is rendelkezsre llnak vltkarakterek. Ezenkvl a mdost paramterekkel kpesek vagyunk finomtani a Perl tpus szablyos kifejezsek viselkedsn.

Krdsek s vlaszok
A Perl tpus szablyos kifejezsek nagyon hatkonynak tnnek. Hol tallhat rluk bvebb informci? A szablyos kifejezsekrl a PHP weboldaln (http://www.php.net) tallhatunk nmi felvilgostst. Emellett mg a http://www.perl.com oldalain tallhatunk informcit, a Perl tpus szablyos kifejezsekhez pedig a http://www.perl.com/pub/doc/manual/html/pod/perlre.htm cmen s Tom Christiansen cikkben, a http://www.perl.com/pub/doc/manual/html/pod/perlfaq6.html cmen tallhatunk bevezetst.

A szablyos kifejezsek hasznlata

359

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Melyik fggvnyt hasznlnnk egy karakterlncban minta illesztsre, ha POSIX szablyos kifejezssel szeretnnk a mintt meghatrozni? 2. Milyen szablyos kifejezst hasznlnnk, ha a "b" bet legalbb egyszeri, de hatnl nem tbbszri elfordulsra szeretnnk keresni? 3. Hogyan hatroznnk meg a "d" s az "f" betk kz es karakterek karakterosztlyt? 4. Hogyan tagadnnk a 3. krdsben meghatrozott karaktertartomnyt? 5. Milyen formban keresnnk tetszleges szmra vagy a "bokor" szra? 6. Melyik POSIX szablyos kifejezs fggvnyt hasznlnnk egy megtallt minta lecserlsre? 7. A .bc* szablyos kifejezs mohn illeszkedik, azaz inkbb az "abc0000000bc" karakterlncra illeszkedik, mint az "abc"-re. A Perl tpus szablyos kifejezsekkel hogyan alaktannk t a fenti szablyos kifejezst gy, hogy a megtallt minta legels elfordulst keresse meg? 8. A Perl tpus szablyos kifejezseknl melyik fordtott perjeles karakterrel illesztnk elvlaszt karakterre? 9. Melyik Perl tpus szablyos kifejezst hasznlnnk, ha az a clunk, hogy egy minta sszes elfordulst megtalljuk? 10. Melyik mdost karaktert hasznlnnk egy Perl tpus szablyoskifejezsfggvnyben, ha kis- s nagybettl fggetlenl szeretnnk egy mintra illeszteni?

18

Feladatok
1. Gyjtsk ki az e-mail cmeket egy fjlbl. A cmeket troljuk egy tmbben s jelentsk meg az eredmnyt a bngszben. Nagy mennyisg adattal finomtsuk szablyos kifejezseinket.

19. RA
llapotok trolsa stikkel s GET tpus lekrdezsekkel
A HTTP llapot nlkli protokoll. Ez azt jelenti, hogy ahny oldalt a felhasznl letlt kiszolglnkrl, annyi nll kapcsolat ltesl, radsul az egyes oldalakon bell a kpek, kls fjlok letltsre is kln kapcsolatok nylnak. Msrszt viszont a felhasznlk s a weboldalak kszti krnyezetknt, azaz olyan trknt rzkelik a weboldalakat, amelyben egyetlen oldal is egy nagyobb egsz rsze. gy viszont nem meglep, hogy az oldalrl oldalra val informcitads mdszerei egyidsek magval a Vilghlval. Ezen az rn az informcitrols azon kt mdszervel fogunk megismerkedni, amelyek lehetv teszik, hogy egy adott oldalon tallhat adat a kvetkez oldalakon is elrhet legyen. Az ra sorn a kvetkezket tanuljuk meg: Mik a stik s hogyan mkdnek? Hogyan olvassuk a stiket?

362 Hogyan rjunk stiket?

19. ra

Hogyan troljuk adatbzisban a weboldalak lekrsi statisztikjt stik segtsgvel? Mik azok a GET md lekrsek? Hogyan rjunk olyan fggvnyt, amely egy asszociatv tmbt egy lekrdez karakterlncc alakt t?

Stik
A Netscape munkatrsai ltal kitlt csodasti (magic cookie) kifejezs mg a Netscape 1 aranykorbl szrmazik. A kifejezs pontos eredete mindmig vitk trgya, br meglehetsen valsznnek tnik, hogy a szerencsestinek valami kze lehetett hozz. Azta viszont mr ms bngszk is alkalmazzk ezt a szabvnyt. JDONSG A sti (cookie) kis mennyisg adat, amelyet a felhasznl bngszje trol egy kiszolgl vagy egy program krsnek eleget tve. Egy gp legfeljebb 20 stit trolhat a felhasznl bngszjben. Minden sti egy nevet, egy rtket, a lejrati idpontot s a gazdagpre s elrsi tra vonatkoz informcikat tartalmazza. Az egyes stik mrete legfeljebb 4 KB lehet. A sti rtkeinek belltsa utn csak az a szmtgp olvashatja az adatokat, amely azokat ltrehozta, ezzel is garantlva a felhasznl biztonsgt. A felhasznl azt is bellthatja bngszjben, hogy az rtestse az egyes stik ltrehozsnak krelmrl, vagy elutasthatja az sszes stikrelmet. Ezekbl addan a stiket mdjval kell hasznlni, nem lehet teljesen rjuk tmaszkodni a krnyezet megtervezsekor anlkl, hogy a felhasznlt elszr ne rtestennk. Mindezekkel egytt a stik kivlan alkalmasak arra, hogy kis mennyisg informcit troljunk velk, mialatt a felhasznl oldalrl-oldalra lpdel, vagy akr hosszabb tvon is, a webhely egyes ltogatsai kztt.

A stik felptse
A stik ltrehozsa ltalban a HTTP fejlcben trtnik (br a JavaScript kzvetlenl a bngszvel is ltre tudja hozni a stiket). Egy stibellt PHP program ilyesfle HTTP fejlcelemet kell, hogy ltrehozzon: Set-Cookie: zoldseg=articsoka; expires=Friday, 04-Feb-00 22:03:38 GMT; path=/; domain=kiskapu.hu

llapotok trolsa stikkel s GET tpus lekrdezsekkel Mint ahogy azt lthatjuk, a Set-Cookie fejlc egy nvrtk prt, egy greenwichi kzpid szerinti lejrati idpontot (expires), egy elrsi utat (path) s egy tartomnyt (domain) tartalmaz. A nv s az rtk URL felpts kell, hogy legyen. A lejrat mez (expires) arra ad utastst a bngsznek, hogy mikor felejtse el a stit. Az elrsi t a weboldalon azt a helyet jelli, amelynek elrsekor a stit vissza kell kldeni a kiszolglra. A tartomny mez azokat az internetes tartomnyokat jelli ki, ahov a stit el kell kldeni. A tartomny nem klnbzhet attl, ahonnan a stit kldtk, viszont egy bizonyos szint rugalmassgot is meghatrozhat. Az elz pldnl a bngsz a www.kiskapu.hu s a leeloo.kiskapu.hu kiszolglknak egyarnt hajland elkldeni a stit. A HTTP fejlcrl a tizenharmadik ra anyagban tbbet is olvashattunk. Ha a bngsz gy van belltva, hogy trolja a stiket, akkor az azokban trolt adatok a sti lejrtig elrhetk maradnak. Ha a felhasznl a bngszvel olyan oldalra jut, amely egyezik a stiben trolt elrsi tvonallal s tartomnnyal, akkor elkldi a stit a kiszolglnak. Ehhez ltalban az albbihoz hasonl fejlcelemet llt el: Cookie: zoldseg=articsoka gy aztn a PHP program hozzfrhet a stihez a HTTP_COOKIE krnyezeti vltozn keresztl (amely az sszes sti nevt s rtkt trolja), de a $zoldseg globlis vltozn keresztl vagy a $HTTP_COOKIE_VARS[zoldseg] globlis tmbvltoz segtsgvel is elrhetjk azt: print "$HTTP_COOKIE<BR>"; // azt rja ki, hogy "zoldseg=articsoka" print getenv("HTTP_COOKIE")."<br>"; // azt rja ki, hogy "zoldseg=articsoka" print "$zoldseg<br>"; // azt rja ki, hogy "articsoka" print "$HTTP_COOKIE_VARS["zoldseg"]<br>"; // azt rja ki, hogy "articsoka"

363

19

Stik belltsa a PHP-vel


A PHP-vel ktflekppen hozhatunk ltre egy stit. Egyrszt a kilencedik ra sorn megismert header() fggvny segtsgvel bellthatjuk a fejlc Set-Cookie sort. A header() egy karakterlncot vr, amit az oldal HTTP fejlcbe r. Mivel a fejlcek automatikusan kerlnek kirsra, a header() fggvnyt mg azeltt kell meghvnunk, mieltt brmi egyebet kldennk a bngsznek. Figyeljnk arra, hogy a PHP blokk kezdeleme el rt egyetlen szkz vagy jsor karakter is kimenetknt jelenik meg a bngszben.

364

19. ra header ("Set_Cookie: zoldseg=articsoka; expires=Friday, 04-Feb-00 22:03:38 GMT; path=/; domain=kiskapu.hu"); Br ez a mdszer nem tl bonyolult, mgis rnunk kell egy olyan fggvnyt, amely ellltja a fejlc szvegt. Ez persze nem tl rzs feladat, hiszen csak a megfelel formtum dtumot, illetve az URL formtum nvrtk prt kell ellltanunk. Kr azonban ezzel veszdnnk, mert ltezik egy olyan PHP fggvny, amely pontosan ezt vgzi el helyettnk. A setcookie() fggvny neve nmagrt beszl: a fejlc Set-Cookie sort lltja el. Ennek megfelelen azeltt kell mg meghvnunk, mieltt valamit kikldennk a bngsznek. A fggvny bemenett a sti neve, rtke, UNIX idblyeg formtumban megadott lejrata, elrsi tja, a feljogostott tartomny, valamint egy egsz szm alkotja. Ezt a legutols paramtert 1-re lltva biztosthatjuk, hogy a sti csak biztonsgos kapcsolaton keresztl tudjon kzlekedni. A sti nevn kvl egyik paramter sem ktelez. A 19.1. programban arra lthatunk pldt, ahogy a setcookie() fggvny segtsgvel belltunk egy stit.

19.1. program Sti rtknek belltsa s kiratsa


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: <?php setcookie( "zoldseg", "articsoka", time()+3600, "/", "kiskapu.hu", 0 ); ?> <html> <head> <title>19.1. program Sti rtknek belltsa s kiratsa</title> </head> <body> <?php if ( isset( $zoldseg ) ) print "<p>dv, az n ltal kivlasztott zldsg a(z) $zoldseg</p>"; else print "<p>dvzljk! Ez az n els ltogatsa.</p>"; ?> </body> </html>

llapotok trolsa stikkel s GET tpus lekrdezsekkel Br a program els lefuttatsakor mr belltjuk a stit, a $zoldseg vltoz ekkor mg nem jn ltre. A sti csak akkor lesz hozzfrhet, amikor a bngsz elkldi azt a kiszolglnak. Ez csak akkor kvetkezik be, ha a felhasznl jra megltogatja tartomnyunkat. A pldban egy "zoldseg" nev stit hozunk ltre, melynek rtke "articsoka". A time() fggvnnyel lekrdezzk a pillanatnyi idt, majd ebbl 3600-at hozzadva szmtjuk ki a lejrat idejt. (A 3600 msodpercben rtend, teht a sti 1 ra elteltvel fog elavulni.) tvonalknt a "/"-t adjuk meg, amibl az kvetkezik, hogy stink a webhely sszes oldalrl elrhet lesz. A tartomnyt "kiskapu.hu"-ra lltottuk, aminek kvetkeztben ennek a tartomnynak mindegyik kiszolglja jogosult a sti fogadsra (a www.kiskapu.hu teht ugyangy megkapja a stit, mint a leeloo.kiskapu.hu). Ha azt szeretnnk, hogy egy stihez csak az a kiszolgl frjen hozz, amelyik a stit ltrehoz programot szolgltatta, hasznljuk a $SERVER_NAME krnyezeti vltozt, ahelyett, hogy a tartomny, illetve kiszolglnevet beptennk a programba. Ez a megolds azzal az elnnyel is rendelkezik, hogy a programok mdosts nlkl tvihetk egy msik kiszolglra s ott is az elvrsoknak megfelelen fognak futni. Vgl egy nullt is tadunk a setcookie()-nak, jelezvn, hogy a stit nem biztonsgos kapcsolaton keresztl is el szabad kldeni. Br az els kivtelvel mindegyik paramter elhagyhat, hasznos, ha minden paramtert megadunk s csak a tartomny s biztonsg adatok meghatrozstl tekintnk el. Erre azrt van szksg, mert bizonyos bngszk csak az tvonal megadsa esetn kpesek a stik rendeltetsszer hasznlatra. Az tvonal elhagysval a sti hasznlatt az aktulis, illetve az alatta elhelyezked knyvtrak oldalai szmra korltozzuk. Ha a setcookie() szveges paramtereiknt ""-t, azaz res karakterlncot adunk t, a szm paramtereinek pedig 0-t, a fggvny ezeket a paramtereket nem veszi figyelembe.

365

19

Sti trlse
A stik trlsnek hivatalos mdja az, hogy a setcookie() fggvnyt egyetlen paramterrel, mgpedig a trlend sti nevvel hvjuk meg: setcookie( "zoldseg" ); Ebben a megoldsban nem bzhatunk meg teljesen, mert nem minden esetben mkdik kifogstalanul. Ezrt clszerbb, ha egy mltbeli dtummal j rtket adunk a stinek: setcookie( "zoldseg", "", time()-60, "/", "kiskapu.hu", 0); Ennek alkalmazsakor viszont gyelnnk kell, hogy a megadott tvonal, tartomny s biztonsgi paramter tkletesen egyezzen a sti ltrehozsakor megadottakkal.

366

19. ra

Munkamenet-azonost stik
Ha olyan stit szeretnnk ltrehozni, amely csak addig ltezik, amg a felhasznl be nem zrja a bngszt, csak annyi a teendnk, hogy a sti lettartamt nullra lltjuk. Amg ki nem lpnk a bngszbl, az gy ksztett stiket a kiszolgl gond nlkl megkapja, m ha bezrjuk a programot, a stik megsznnek, gy hiba indtjuk jra a bngszt, mr nem rjk el azokat. Ezen eljrs legfbb alkalmazsi terlete a felhasznlk azonostsa. A felhasznl elkldi a nevt s jelszavt, vlaszknt pedig egy olyan oldalt kap, amely egy stit hoz ltre a bngszben. Ezek utn a bngsz a stit minden szemlyes adatokat tartalmaz laphoz trtn hozzfrskor visszakldi a kiszolglnak, az pedig ennek hatsra engedlyezi a hozzfrst. Ilyen esetekben nem kvnatos, hogy a bngsz jraindtsa utn is hozzfrhessnk ezekhez a lapokhoz, mert nem lehetnk biztosak benne, hogy nem egy msik felhasznl indtotta el a bngszt. A munkamenet-azonostt hagyomnyosan sessionid-nek nevezik, a bngsz bezrsig l stit pedig session cookie-nak. setcookie( "session_id", "55435", 0 );

Plda: Webhelyhasznlat nyomon kvetse


Kpzeljk el, hogy egy tartalomszolgltat azzal bzott meg bennnket, hogy stik, valamint egy MySQL adatbzis segtsgvel kimutatst ksztsnk a ltogatkrl. Szksg van a ltogatk szmra, a ltogatsok alkalmval letlttt lapok szmnak tlagra s az olvask ltal a webhelyen tlttt tlagidre, ltogatkra lebontva. Az els dolgunk, hogy megrtessk megbznkkal a stik alkalmazsnak korltait. Nem mindegyik felhasznl bngszjben engedlyezett a stik hasznlata. Ilyen esetben a lekrt oldal mindig gy fog tnni, mintha ez lenne az adott felhasznl els ltogatsa. gy ht a kapott eredmnyeket kiss meghamistjk azok a bngszk, amelyek nem tudjk vagy nem akarjk kezelni a stiket. Tovbb abban sem lehetnk biztosak, hogy egy felhasznl mindig ugyanazt a bngszt hasznlja, s abban sem, hogy egy adott bngszn nem osztozik-e esetleg tbb ember. Ha megbznk mindezt tudomsul vette, nekiveselkedhetnk a tnyleges megvalstsnak. Egy mkd mintt kevesebb, mint 90 sorbl sszerakhatunk! Szksgnk lesz elszr is egy adatbzistblra, mely a 19.1-es tblzatban felsorolt mezkbl ll.

llapotok trolsa stikkel s GET tpus lekrdezsekkel

367

19.1. tblzat Adatbzismezk


Nv vendeg_azon Tpus egsz Lers Automatikusan nvekv mez, amely minden ltogat szmra egyedi azonostt llt el s trol.
A ltogat els ltogatsnak idblyege. A legutbb lekrt lap idpontjnak idblyege. Az elklnthet ltogatsok szma. A webhelyen tlttt id kzelt rtke. A ltogat sszes letltsi krelmeinek szma.

elso_latogatas utolso_latogatas latogatas_szam ossz_ido ossz_letoltes

egsz egsz egsz egsz egsz

19

A vendeg_naplo MySQL tbla ltrehozshoz a kvetkez CREATE utastsra lesz szksg: create table vendeg_naplo ( vendeg_azon INT NOT NULL AUTO_INCREMENT, PRIMARY KEY( vendeg_azon ), elso_latogatas INT, utolso_latogatas INT, latogatas_szam INT, ossz_ido INT, ossz_letoltes INT ); Most, hogy elksztettk a tblt, amivel dolgozhatunk, rnunk kell egy programot, amely megnyit egy adatbzis-kapcsolatot s kpes ellenrizni a sti jelenltt. Ha a sti nem ltezik, j sort hoz ltre a tblban s feltlti az j ltogat adataival. Ennek megvalstsa lthat a 19.2. pldban.

368

19. ra

19.2 program A MySQL adatbzist j felhasznl adataival bvt program


1: <?php 2: $adatbazis = mysql_connect( "localhost", "janos", "majomkenyerfa" ); 3: if ( ! $adatbazis ) 4: die( "Nem lehet a mysql-hez kapcsoldni!" ); 5: mysql_select_db( "minta", $adatbazis ) or die ( mysql_error() ); 6: if ( ! isset ( $vendeg_azon ) ) 7: $vendeg_allapot = ujvendeg( $adatbazis ); 8: else 9: print "rlnk, hogy ismt krnkben dvzlhetjk, $vendeg_azon<P>"; 10: function ujvendeg( $adatbazis ) 11: { 12: // egy j vendg! 13: $vendeg_adatok = array ( 14: "elso_latogatas" => time(), 15: "utolso_latogatas" => time(), 16: "latogatas_szam" => 1, 17: "ossz_ido" => 0, 18: "ossz_letoltes" => 1 19: ); 20: $lekerdezes = "INSERT INTO vendeg_naplo ( elso_latogatas, 21: utolso_latogatas, 22: latogatas_szam, 23: ossz_ido, 24: ossz_letoltes ) "; 25: $lekerdezes .= "values ( ". $vendeg_adatok["elso_latogatas"].", ". 26: $vendeg_adatok["utolso_latogatas"].", ". 27: $vendeg_adatok["latogatas_szam"].", ". 28: $vendeg_adatok["ossz_ido"].", ". 29: $vendeg_adatok["ossz_letoltes"]." )"; 30: $eredmeny = mysql_query( $lekerdezes ); 31: $vendeg_adatok["vendeg_azon"] = mysql_insert_id(); 32: setcookie( "vendeg_azon", $vendeg_adatok["vendeg_azon"], 33: time()+(60*60*24*365*10), "/" ); 34: return $vendeg_adatok; 35: } 36: ?>

llapotok trolsa stikkel s GET tpus lekrdezsekkel A szokvnyos mdon csatlakozunk a MySQL kiszolglhoz s kivlasztjuk azt az adatbzist, amelyben a vendeg_naplo tbla tallhat (a MySQL adatbziskiszolgl kezelst a tizenkettedik ra tartalmazza). Ellenrizzk a $vendeg_azon vltoz jelenltt, amely a felhasznlt azonost egyedi egsz szmot tartalmazza. Ha ez a vltoz nem ltezik, felttelezzk, hogy j felhasznlrl van sz s bejegyzshez meghvjuk az ujvendeg() nev fggvnyt. Az ujvendeg() fggvny egy hivatkozs-azonostt kr s egy tmbt ad vissza. A fggvnyben ltrehozunk egy $vendeg_adatok nev tmbt. A tmb elso_latogatas s utolso_latogatas elemeit a pillanatnyi idre lltjuk. Mivel ez az els ltogats, gy a latogatas_szam s az ossz_letoltes elemeket 1-re lltjuk. Az ossz_ido 0 lesz, hiszen ezen ltogats alkalmval mg nem telt el id. A ltrehozott tmb alapjn elksztjk a tblba illesztend j sort, gy, hogy a tmb mindegyik elemt a tbla azonos nev oszlopnak adjuk rtkl. Mivel a vendeg_azon mez automatikusan nvekszik, megadstl eltekinthetnk. A sti belltsakor azonban szksg lesz erre az jonnan ellltott azonostra. Ezt vlaszknt a mysql_insert_id() fggvnytl kaphatjuk meg. Most, hogy ellttuk az j ltogatt egy azonostval, nincs ms htra, mint kibvteni a tmbt az azonostval, amely gy mr megfelel az adatbzisrekordnak, amit az imnt ltrehoztunk. Vgs lpsknt ltrehozzuk a vendeg_azon nev stit egy setcookie() hvssal s visszaadjuk a $vendeg_adatok tmbt a hv programnak. Legkzelebb, amikor a ltogat mkdsbe hozza a programot, a PHP mr ltni fogja a $vendeg_azon vltozn keresztl a vendeg_azon stit. A program ezt gy rtkeli, hogy egy rgi ismers visszatrsrl van sz s ennek megfelelen frissti a vendeg_naplo tblt, majd dvzli a felhasznlt. A frissts elvgzshez meg kell mg vizsglnunk, hogy a program futst egy folyamatban lv bngszs eredmnyezte vagy j ltogats els lpsrl van sz. Ennek eldntsben egy globlis vltoz lesz segtsgnkre, mely egy msodpercben mrt idtartamot trol. Ha a program ltal rzkelt legutols letlts ideje az elbb emltett idtartamnl rgebbi, akkor a mostani letlts egy jabb ltogats kezdetnek tekintend, ellenkez esetben a folyamatban lv ltogats rsznek tekintjk. A 19.3. plda a regivendeg() fggvnnyel bvti a 19.2. programot.

369

19

370

19. ra

19.3 program Felhasznlkvet program stik s MySQL adatbzis felhasznlsval


1: <?php 2: $lhossz = 300; // a ltogats hossza 5 perc, msodpercben kifejezve 3: $adatbazis = mysql_connect( "localhost", "janos", "majomkenyerfa" ); 4: if ( ! $adatbazis ) 5: die( "Nem lehet a mysqld-hez kapcsoldni!" ); 6: mysql_select_db( "minta"", $adatbazis ) or die ( mysql_error() ); 7: if ( ! isset ( $vendeg_azon ) ) 8: $vendeg_allapot = ujvendeg( $adatbazis ); 9: else 10: { 11: $vendeg_allapot = regivendeg( $adatbazis, $vendeg_azon, $lhossz ); 12: print "rlnk, hogy ismt krnkben dvzlhetjk, $vendeg_azon<P>"; 13: } 14: function ujvendeg( $adatbazis ) 15: { 16: // egy j vendg! 17: $vendeg_adatok = array ( 18: "elso_latogatas" => time(), 19: "utolso_latogatas" => time(), 20: "latogatas_szam" => 1, 21: "ossz_ido" => 0, 22: "ossz_letoltes" => 1 23: ); 24: $lekerdezes = "INSERT INTO vendeg_naplo ( elso_latogatas, 25: utolso_latogatas, 26: latogatas_szam, 27: ossz_ido, 28: ossz_letoltes ) "; 29: $lekerdezes .= "values ( ". $vendeg_adatok["elso_latogatas"].", ". 30: $vendeg_adatok["utolso_latogatas"].", ". 31: $vendeg_adatok["latogatas_szam"].", ". 32: $vendeg_adatok["ossz_ido"].", ". 33: $vendeg_adatok["ossz_letoltes"]." )"; 34: $eredmeny = mysql_query( $lekerdezes ); 35: $vendeg_adatok["vendeg_azon"] = mysql_insert_id();

llapotok trolsa stikkel s GET tpus lekrdezsekkel

371

19.3 program folytats


36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: setcookie( "vendeg_azon", $vendeg_adatok["vendeg_azon"], time()+(60*60*24*365*10), "/" ); return $vendeg_adatok; } function regivendeg( $adatbazis, $vendeg_azon, $lhossz ) { // egy ismers vendg, aki mr jrt nlunk korbban! $lekerdezes = "SELECT * FROM vendeg_naplo WHERE vendeg_azon=$vendeg_azon"; $eredmeny = mysql_query( $lekerdezes ); if ( ! mysql_num_rows( $eredmeny ) ) // sti van ugyan, de azonost nincs teht mgiscsak j vendg return ujvendeg( $adatbazis ); $vendeg_adatok = mysql_fetch_array( $eredmeny, $adatbazis ); // ez most egy jabb letlts, teht nveljk a szmllt $vendeg_adatok["ossz_letoltes"]++; if ( ( $vendeg_adatok["utolso_latogatas"] + $lhossz ) > time() ) // mg mindig ugyanaz a ltogats, teht nveljk az sszidt. $vendeg_adatok["ossz_ido"] += ( time() - $vendeg_adatok["utolso_latogatas"] ); else // ez mr egy j ltogats, $vendeg_adatok["latogatas_szam"]++; // ennek megfelelen mdostjuk az adatbzist $lekerdezes = "UPDATE vendeg_naplo SET utolso_latogatas=".time().", "latogatas_szam=".$vendeg_adatok ["latogatas_szam"].", ". "ossz_ido=".$vendeg_adatok["ossz_ido"].", ". "ossz_letoltes=". $vendeg_adatok["ossz_letoltes"]." "; $lekerdezes .= "WHERE vendeg_azon=$vendeg_azon"; $eredmeny = mysql_query( $lekerdezes ); return $vendeg_adatok; } ?>

19

372

19. ra Lthat, hogy a programot az $lhossz nev vltozval bvtettk. Ebben adjuk meg azt az idtartamot, amely alapjn megtljk, hogy a letlts mely ltogatshoz tartozik. A $vendeg_azon vltoz jelenltnek rzkelse azt jelenti szmunkra, hogy kaptunk egy stit. Erre vlaszul meghvjuk a regivendeg() fggvnyt, tadva annak az adatbzisra hivatkoz, a $vendeg_azon s az $lhossz vltozt, amit 300 msodpercre, azaz 5 percre lltottunk. A regivendeg() fggvny els lpsknt lekrdezi a felhasznlrl trolt adatokat. Ezt egyszeren gy tesszk, hogy kikeressk a vendeg_naplo tbla azon sort, melyben a vendeg_azon mez egyenl a $vendeg_azon vltoz rtkvel. A mysql_query() ltal visszaadott sorok szmt megtudhatjuk, ha meghvjuk a mysql_num_rows() fggvnyt az eredmnysorok azonostjval. Ha a mysql_num_rows() vlasza 0, akkor mgis j felhasznlrl van sz, teht meg kell hvnunk az ujvendeg() fggvnyt. Tegyk fel, hogy talltunk egy megfelel sort, melynek azonostja egyezik a sti rtkvel. Ezt a sort a mysql_fetch_array() fggvnnyel emelhetjk t egy PHP tmbbe (esetnkben a $vendeg_adatok nevbe). A program mostani futsa egy oldal letltsnek kvetkezmnye, teht a $vendeg_adatok["ossz_letoltes"] vltoz rtkt eggyel nvelnnk kell, hogy rgztsk ezt a tnyt. Megvizsgljuk, hogy a $vendeg_adatok["utolso_latogatas"] s az $lhossz sszege a pillanatnyi idnl ksbbi idpont-e. Ha ksbbi, akkor az azt jelenti, hogy a legutbbi letlts ta kevesebb, mint $lhossz id telt el, vagyis a legutbbi ltogats mg folyamatban van s ez a letlts mg annak a rsze. Ennek tnyt gy rizzk meg, hogy a legutbbi letlts ta eltelt idt hozzadjuk a $vendeg_adatok["ossz_ido"] vltozhoz. Ha gy talltuk, hogy mr j ltogatsrl van sz, egyszeren nveljk a $vendeg_adatok["latogatas_szam"] vltoz rtkt. Befejezsl a $vendeg_adatok tmb tartalmval frisstjk a vendeg_naplo tblt s a hv program is megkapja ezt a tmbt. Br ezt kln nem emeltk ki, termszetesen az utolso_latogatas mezt is a pillanatnyi idhz igaztottuk. Most, hogy a feladaton tl vagyunk, rhatunk egy kis programot, hogy ellenrizzk, az elmlet valban mkdik-e a gyakorlatban. Elksztjk az allapotMegjelenites() fggvnyt, amely kiszmolja a lekr felhasznl tlagrtkeit s megjelenti azokat a bngszben. A valsgban persze komolyabb megjelens, tfogbb kpet kell adnunk a ltogatkrl, de a lnyeg megrtshez ez a plda is bven elegend. A fggvny megvalstst a 19.4. pldban talljuk. A korbbi pldk kdjhoz az include() fggvny alkalmazsval frhetnk hozz.

llapotok trolsa stikkel s GET tpus lekrdezsekkel

373

19.4 program A 19.3-as program ltal begyjttt letltsi statisztikk megjelentse


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: <?php include("19.3.program.php"); allapotMegjelenites(); function allapotMegjelenites() { global $vendeg_allapot; $letoltesek = sprintf( "%.2f", ($vendeg_allapot["ossz_letoltes"]/ /$vendeg_allapot["latogatas_szam"]) ); $idotartam = sprintf( "%.2f", ($vendeg_allapot["ossz_ido"]/ /$vendeg_allapot["latogatas_szam"]) ); print "<p>dvzljk! Az n azonostja". $vendeg_allapot["vendeg_azon"]."</p>\n\n"; print "<p>Az n ltogatsainak szma $vendeg_allapot["latogatas_szam"]."</p>\n\n"; print "<p>Letltsek tlagos szma ltogatsonknt: $letoltesek</p>\n\n"; print "<p>tlagos ltogatsi idtartam: $idotartam msodperc</p>\n\n"; } ?>

19

A 19.1 bra a 19.4 program kimenett mutatja. Az include() sorral biztostottuk, hogy a felhasznlkvet kd lefusson. Hasonl sorral kell bvtennk webhelynk minden olyan oldalt, melyet be szeretnnk vonni a statisztikba. Az allapotMegjelenites() fggvny a $vendeg_allapot globlis vltoz alapjn dolgozik. Ezt vagy az ujvendeg(), vagy a regivendeg() fggvny hozza ltre s tlti fel a vendeg_naplo tbla megfelel sornak rtkeivel. Azt, hogy egy felhasznl ltogatsonknt tlagosan hnyszor kattintott olyan hivatkozsra, mely a webhely valamelyik oldalra mutatott, gy szmoljuk ki, hogy elosztjuk a $vendeg_allapot["ossz_letoltes"] vltozt a ltogatsok szmval. Ugyanezzel az rtkkel a $vendeg_allapot["ossz_ido"]-t elosztva a ltogatsok tlagidejt kaphatjuk meg. Ezeket a szmokat az sprintf() segdletvel kerektjk kt tizedesjegyre, majd mondatokk formlva megjelentjk azokat a felhasznlnak.

374

19. ra Termszetesen a pldt gy is bvthetnnk, hogy a program rgztse a felhasznl rdekldsi terleteit a webhelyen bell, de akr naplztathatnnk a ltogatshoz hasznlt bngsz tpust vagy a ltogatk IP cmeit is. Hogy mire lehet mindezt hasznlni? Knnythetjk felhasznlink eligazodst webhelynkn, gy, hogy bngszsi szoksaikat kielemezve, vastag betvel kiemeljk a szmukra feltehetleg klnskpp rdekes mondanivalt.

19.1. kp
A hasznlati statisztika megjelentse

Lekrdez karakterlncok hasznlata


A stik hatalmas htrnya azok felhasznl-fggsge. Nem csak a felhasznl knye-kedvnek vagyunk kitve, ha stiket hasznlunk, de a felhasznl bngszjtl is fgg hasznlatuk. A felhasznl letilthatja a stik hasznlatt, a bngszk pedig nem mindig egyformn valstjk meg a szabvnyt. Egyikk-msikuk a stik kezelse terletn dokumentlt hibkkal is rendelkezik. Ha csak egy ltogats folyamn szeretnnk llapot-adatokat trolni, jobban jrunk, ha egy sokkal hagyomnyosabb megoldshoz folyamodunk. Ha egy rlapot a GET eljrssal kldnk el, akkor annak mezit s azok rtkeit URL kdolsban hozzillesztjk ahhoz a cmhez (URL-hez), ahov az rlapot kldjk. Az rtkek ekkor elrhetk lesznek a kiszolgl, illetve az ltala futtatott programok szmra. Vegynk pldaknt egy olyan rlapot, amely egy felhasznalo s egy nev mezt tartalmaz. Ekkor a lekrs a kvetkezkpp fog festeni: http://php.kiskapu.hu/proba5.php?nev= 344343&felhasznalo=Szy+Gyorgy

llapotok trolsa stikkel s GET tpus lekrdezsekkel Minden mez nevt egy egyenlsgjel (=) vlasztja el annak rtktl; ezeket a nvrtk prokat pedig S jelek (&) hatroljk. A PHP visszafejti a jeleket, a tallt adatokat a $HTTP_GET_VARS asszociatv tmbben teszi elrhetv a program szmra, s emellett a mezk nevvel azonos nev globlis vltozkat is ltrehoz, a megfelel tartalommal. A felhasznalo nev GET vltozhoz gy az albbi kt mdon frhetnk hozz: $HTTP_GET_VARS["felhasznalo"]; $felhasznalo; A GET lekrsek szerencsre nem csak rlapokkal kapcsolatban hasznlhatk; viszonylag knnyen kszthetnk mi is ilyen karakterlncokat, gy a fontos adatokat knnyedn tovbbthatjuk laprl lapra.

375

19

Lekrdez karakterlnc ksztse


Alapvet feladatunk a lekrdez karakterlncok ksztsekor, hogy a kulcsrtk prokat URL formra alaktsuk. Tegyk fel, hogy egy cmet (URL-t) szeretnnk tadni egy lapnak paramterknt, azaz egy lekrdez karakterlnc rszeknt. Erre a PHP urlencode() fggvnye hasznlhat, mely egy tetszs szerinti karakterlncot vr s annak kdolt vltozatval tr vissza: print urlencode("http://www.kiskapu.hu"); // azt rja ki, hogy http%3A%2F%2Fwww.kiskapu.hu Az URL kdols szvegek ellltsa gy nem okoz gondot, akr sajt GET lekrseket is sszerakhatunk. A kvetkez kdrszlet kt vltozbl pt fel egy lekrdez karakterlncot: <?php $erdeklodes = "sport"; $honlap = "http://www.kiskapu.hu"; $lekerdezes = "honlap=".urlencode( $honlap ); $lekerdezes .= "&erdeklodes=".urlencode( $erdeklodes ); ?> <A HREF="masiklap.php?<?print $lekerdezes ?>">Gyernk!</A> Ennek hatsra a bngszhz az URL mr a kdolt lekrdez karakterlnccal bvtve jut el: masiklap.php?honlap=http%3A%2F%2Fwww.kiskapu.hu& erdeklodes=sport

376

19. ra A honlap s az erdeklodes paramterek a masiklap.php programon bell ugyanilyen nev, URL-bl visszafejtett globlis vltozkknt lesznek elrhetk. Ez gy a problmnak kiss kezdetleges megoldsa, mert a vltoznevek kdba gyazsval megneheztjk a kd jrahasznostst. Ahhoz, hogy hatkonyan kldhessnk adatokat laprl-lapra, egyszerv kell tennnk a lekrdez karakterlncokat tartalmaz hivatkozsok ksztst. Ez klnsen fontos, ha meg szeretnnk tartani a PHP azon hasznos tulajdonsgt, miszerint a nem kifejezetten programozk is knnyedn eligazodhatnak rajta. A 19.5. plda egy olyan lsztring() nev fggvny megvalstst tartalmazza, amely a kapott asszociatv tmb alapjn elkszt s visszaad egy lekrdez karakterlncot.

19.5. program Lekrdez karakterlncot kszt fggvny


1: <html> 2: <head> 3: <title>19.5 program Lekrdez karakterlncot kszt fggvny</title> 4: </head> 5: <body> 6: <?php 7: function lsztring( $lekerdezes ) 8: { 9: global $QUERY_STRING; 10: if ( ! $lekerdezes ) return $QUERY_STRING; 11: $lsztring = ""; 12: foreach( $lekerdezes as $kulcs => $ertek ) 13: { 14: if ( strlen( $lsztring ) ) $lsztring .= "&"; 15: $lsztring .= urlencode( $kulcs ) . "=" . urlencode( $ertek ); 16: } 17: return $lsztring; 18: } 19: $lekerdezes = array ( "nev" => "Kis Lajos Bence", 20: "erdeklodes" => "Filmek (fleg mvszfilmek)", 21: "honlap" => "http://www.kiskapu.hu/lajos/" 22: ); 23: print lsztring( $lekerdezes );

llapotok trolsa stikkel s GET tpus lekrdezsekkel

377

19.5. program (folytats)


24: // azt rja ki, hogy nev=Kis+Lajos+Bence&erdeklodes= Filmek+%28f%F5leg+m%FBv%E9szfilmek 25: // %29&honlap=http%3A%2F%2Fwww.kiskapu.hu%2Flajos%2F 26: ?> 27: <p> 28: <a href="masiklap.php?<? print lsztring($lekerdezes) ?>">Gyernk!</a> 29: </p> 30: </body> 31: </html>

Az lsztring() egy asszociatv tmbt vr paramterknt, amit jelen esetben a $lekerdezes vltoz kpben adunk t neki. Ha a $lekerdezes mg nem kapott volna rtket, a programot tartalmaz lap lekrdez karakterlnct adjuk vissza, amit a $QUERY_STRING vltozval rhetnk el. Ezzel oldhatjuk meg azt, hogy a GET-tel tovbbtott, mdostatlan rlapadatok knnyedn tovbbadhatak legyenek ms lapok szmra. Ha a $lekerdezes tmb nem res, a visszaadand lekrdez karakterlncot az $lsztring vltozba helyezzk. A foreach segtsgvel sorra vesszk a tmb elemeit, gy, hogy azok a $kulcs s $ertek vltozkon keresztl legyenek elrhetk. A kulcsrtk prokat & jellel kell elvlasztanunk, gy ha nem a ciklus els lefutsnl tartunk azaz az $lsztring vltoz mr nem res , ezt a karaktert is hozztesszk a lekrdez karakterlnchoz. A $kulcs s $ertek vltozkat az urlencode() fggvnnyel kdolva s egy egyenlsgjellel (=) elvlasztva adjuk hozz az $lsztring vghez. Ezek utn mr csak vissza kell adnunk az sszelltott, kdolt karakterlncot. E fggvny alkalmazsval pr sornyi PHP kd is elg, hogy adatokat adhassunk t egyes lapjaink kztt.

19

378

19. ra

sszefoglals
Ezen az rn a weblapok kzti informcitads kt mdjval ismerkedhettnk meg. Segtsgkkel tbb oldalbl ll webes alkalmazsok alakthatk ki, melyek a felhasznlk ignyeit is figyelembe veszik. Tudjuk, hogyan hasznljuk a setcookie() fggvnyt stik ltrehozsra. Ennek kapcsn lthattuk, hogyan trolhatk adatok a webhely felhasznlinak szoksairl stik s egy adatbzis felhasznlsval. Lttunk lekrdez karakterlncokat is. Tudjuk, hogyan kell azokat kdolni s egy hasznos eszkzt is a magunknak mondhatunk, amely jelentsen egyszersti ezek hasznlatt.

Krdsek s vlaszok
Van e valamifle komoly biztonsgot vagy szemlyisgi jogokat srt velejrja a stik hasznlatnak? A kiszolgl csak a sajt tartomnyn bell lev gpek stijeihez frhet hozz. Azon tl, hogy a sti a felhasznl fjlrendszerben troldik, azzal semmifle tovbbi kapcsolatba nem kerl. Lehetsg van azonban arra, hogy stit lltsunk be egy kp letltsnek vlaszaknt. Teht ha sok webhely jelentet meg egy kls reklmszolgltat vagy szmll programot oldalain, ezek szolgltatja kpes lehet a ltogatk kvetsre klnbz webhelyek kztt is.

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Milyen fggvnnyel vehetjk r a weboldalunkat letlt felhasznl bngszjt, hogy ltrehozzon egy stit s trolja azt? 2. Hogyan trlhetjk a stiket? 3. Milyen fggvnnyel tehetnk egy tetszleges karakterlncot alkalmass arra, hogy lekrdez karakterlncban szerepelhessen? 4. Melyik beptett vltoz tartalmazza a lekrdez karakterlncot nyers formban? 5. A lekrdez karakterlnc formjban elkldtt nvrtk prok globlis vltozkknt vlnak elrhetv. Ltezik azonban egy tmb is, amely tartalmazza ket. Mi ennek a tmbnek a neve?

llapotok trolsa stikkel s GET tpus lekrdezsekkel

379

Feladatok
1. Tegyk lehetv, hogy a webhelynket megltogat felhasznl bellthassa a weboldalak httrsznt, valamint hogy megadhassa, milyen nven kszntsk a webhely oldalai. Oldjuk meg stikkel, hogy minden oldal ksznjn, illetve a megfelel httrsznnel jelenjen meg. 2. rjuk t az elbbi feladat programjt gy, hogy az adatokat lekrdez karakterlncban troljuk, ne stikben.

19

20. RA
llapotok trolsa munkamenet-fggvnyekkel
Az elz rban ttekintettk, hogy hogyan lehet sti vagy lekrdez karaktersorozat hasznlatval menteni az oldalak llapott. A PHP 4 ezeken kvl tovbbi lehetsgeket is nyjt, klnbz fggvnyei vannak a felhasznl llapotnak mentsre is. Ezen fggvnyek hasznlata nagyon hasonl az elz rban tanultakhoz, de mivel kzvetlenl a nyelvbe vannak ptve, az llapot mentse egyszer fggvnyhvsokkal vgezhet el. Ebben az rban a kvetkezkrl tanulunk: Mik azok a munkamenet-vltozk s hogyan hasznlhatk? Hogyan indtsunk el s folytassunk egy munkamenetet? Hogyan tartsuk nyilvn a munkamenetek vltozit? Hogyan semmistsnk meg egy munkamenetet? Hogyan trljk egy munkamenet egyes vltozit?

382

20. ra

Mik azok a munkamenet-fggvnyek?

A munkamenet-fggvnyekkel egyszeren vgezhetjk el azokat a mveleteket, amelyekrl az elz rban tanultunk. Ezek egy klnleges felhasznli azonostt biztostanak, amellyel oldalrl oldalra klnbz informcikat vihetnk t, hozzkapcsolva azokat ehhez az azonosthoz. Az elzekhez kpest igen nagy elny, hogy a fggvnyek hasznlatval kevesebb munka hrul rnk. Amikor a felhasznl lekr valamilyen munkamenetet tmogat oldalt, kap egy azonostt, vagy a rgebbi ltogatsakor szerzett meglv azonostja kerl felhasznlsra. Ezt kveten a munkamenethez kapcsolt sszes globlis vltoz elrhet lesz a kdban. A munkamenet-fggvnyek mindkt, az elz rban tanult mdszert tmogatjk. Alaprtelmezs szerint a stiket hasznljk, ugyanakkor az azonostkat minden, a sajt oldalunkra mutat kereszthivatkozsban elhelyezhetjk, gy biztostva, hogy az oldal a stiket nem tmogat bngszvel is hasznlhat legyen. A munkamenet llapott a rendszer ltalban egy ideiglenes fjlban trolja, de a megfelel modulok hasznlatval az adatokat adatbzisba is tehetjk.

Munkamenet indtsa a session_start() fggvnnyel


Hacsak nem vltoztattuk meg a php.ini fjlt, a munkameneteket mindig sajt magunknak kell elindtanunk, alapllapotban azok nem indulnak el automatikusan. A php.ini fjlban tallhat a kvetkez sor: session.auto_start = 0 Vltoztassuk a session.auto_start rtkt 1-re, gy a PHP dokumentumokban a munkamenetek rgtn elindulnak. Ha nem vltoztatjuk meg az rtket, mindig meg kell hvnunk a session_start() fggvnyt. Miutn a munkamenet elindult, a session_id() fggvnnyel rgtn hozzfrhetnk a felhasznl munkamenet-azonostjhoz. A session_id() fggvnnyel lekrdezhetjk vagy mdosthatjuk az azonostt. A 20.1. pldban tallhat program a munkamenet-azonostt rja ki a bngszbe.

llapotok trolsa munkamenet-fggvnyekkel

383

20.1. program Munkamenet indtsa vagy folytatsa


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: <?php session_start(); ?> <html> <head> <title>20.1. program Munkamenet indtsa vagy folytatsa</title> </head> <body> <?php print "<p>dvzljk! Az n munkamenet-azonostja " .session_id()."</p>\n\n"; ?> </body> </html>

A fenti program els lefutsa utn ltrehoz egy munkamenet-azonostt. Ha a felhasznl ksbb jratlti az oldalt, ugyanazt az azonostt kapja meg. Ehhez termszetesen szksges, hogy a felhasznl engedlyezze a stiket a bngszjben. Vizsgljuk meg a 20.1. plda kimenetnek fejlceit. A sti a kvetkezkben lett belltva: 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 Mivel a session_start() megprblja belltani a stit, amikor munkamenetet hoz ltre, el kell indtani, mieltt brmit kiratnnk a bngszvel. Vegyk szre, hogy nincs lejrati id. Ez azt jelenti, hogy a munkamenet csak addig tarthat, amg a bngsz aktv. Amikor a felhasznl lelltja a bngszt, a stit nem menti, de ez a viselkeds a php.ini fjl session.cookie_lifetime belltsnak megvltoztatsval mdosthat. Az alaprtelmezett bellts 0, itt kell a lejrati idt msodpercben megadni. Ezzel mindegyik munkamenetnek megadjuk a mkdsi hatridt.

20

384

20. ra

Munkamenet-vltozk
A munkamenet-azonost hozzrendelse a felhasznlhoz csak az els lps. Egy munkamenet sorn tetszleges szm globlis vltozt vezethetnk be, amelyeket ksbb brmelyik, a munkameneteket tmogat oldalunkrl elrhetnk. A vltoz bejegyzshez, bevezetshez a session_register() fggvnyt kell hasznlnunk. A session_register() fggvny paramtereiben karaktersorozatokat kell megadni, gy hatrozva meg egy vagy tbb bevezetend vltoz nevt. A fggvny visszatrsi rtke true, ha a bejegyzs sikeres volt. A fggvny paramtereiben csak a vltozk nevt kell megadni, nem pedig a vltozk rtkeit. A 20.2. pldban kt vltoz bejegyzst lthatjuk.

20.2. program Vltozk bejegyzse


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: <?php session_start(); ?> <html> <head> <title>20.2. program Vltozk bejegyzse</title> </head> <body> <?php session_register( "termek1" ); session_register( "termek2" ); $termek1 = "Ultrahangos csavarhz"; $termek2 = "HAL 2000"; print session_encode(); print "A vltozkat bejegyeztk"; ?> </body> </html>

A 20.2. pldban lthat kdnak nincs tl sok rtelme, amg a felhasznl be nem tlt egy j oldalt. A 20.3. pldban egy olyan PHP program lthat, amely a 20.2. pldban bejegyzett vltozkat hasznlja.

llapotok trolsa munkamenet-fggvnyekkel

385

20.3. program Bejegyzett vltozk hasznlata


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: <?php session_start(); ?> <html> <head> <title>20.3. program Bejegyzett vltozk hasznlata</title> </head> <body> <?php print "Az n ltal kivlasztott termkek:\n\n"; print "<ul><li>$termek1\n<li>$termek2\n</ul>\n"; ?> </body> </html>

A 20.3. program eredmnye a 20.1. brn lthat. Ltjuk, hogy az oldalrl hozzfrnk a msik programban bejegyzett $termek1 s $termek2 vltozkhoz.

20

20.1. bra
Bejegyzett vltozk hasznlata

Hogyan mkdik mindez? A PHP 4 a httrben folyamatosan fenntart egy ideiglenes fjlt a munkamenet szmra. A session_save_path() fggvny hasznlatval e fjl elrsi tjt derthetjk ki, de a fggvnynek egy knyvtr elrsi tjt is megadhatjuk. Ha ezt meghatrozzuk, az ideiglenes munkamenet-fjlok ezutn

386

20. ra ide kerlnek. Ha a fggvnyt paramter nlkl futtatjuk, visszatrsi rtke annak a knyvtrnak az elrsi tja lesz, ahov a rendszer az ideiglenes munkamenetfjlokat menti. A szerz rendszern a print session_save_path(); visszatrsi rtke /tmp. A /tmp knyvtr pldul a kvetkez fjlokat tartalmazhatja: sess_2638864e9216fee10fcb8a61db382909 sess_76cae8ac1231b11afa2c69935c11dd95 sess_bb50771a769c605ab77424d59c784ea0 Amikor megnyitjuk azt a fjlt, melynek neve a 20.1. pldban visszaadott munkamenet-azonostt tartalmazza, lthatjuk, hogyan troldnak a bejegyzett vltozk: termek1|s:22:"Ultrahangos csavarhz";termek2|s:8:"HAL 2000"; Amikor meghvjuk a session_register() fggvnyt, a PHP berja a fjlba a vltoz nevt s rtkt. Ksbb innen kapjuk meg a vltoz rtkt. Ha a session_register() fggvnnyel bejegyeztnk egy vltozt, annak a PHP program futsa sorn mdostott rtke a munkamenet-fjlban is meg fog vltozni. A 20.2. plda bemutatta a session_register() fggvny hasznlatt, de a fggvny mkdse nem tnik tl rugalmasnak. Mit tehetnk, ha a felhasznl tbbfle termket tartalmaz vltozkat szeretne bevezetni? Szerencsre a session_register() fggvny paramterben tmb tpus vltozt is megadhatunk. A 20.4. pldban a felhasznl tbb termk kzl vlaszthat. Ezutn munkamenetvltozkkal ltrehozunk egy egyszer bevsrlkosarat.

20.4. program Tmb tpus vltoz bejegyzse


1: 2: 3: 4: 5: 6: <?php session_start(); ?> <html> <head> <title>20.4. program Tmb tpus vltoz bejegyzse</title> 7: </head>

llapotok trolsa munkamenet-fggvnyekkel

387

20.4. program (folytats)


8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: <body> <h1>Termkbngsz lap</h1> <?php if ( isset( $termekek_urlap ) ) { $termekek = $termekek_urlap; session_register( "termekek" ); print "<p>A termkeit bejegyeztk!</p>; } ?><p> <form method="POST"> <select name="termekek_urlap[]" multiple size=3> <option> Ultrahangos csavarhz <option> HAL 2000 <option> Kalapcs <option> TV <option> Targonca </select> </p><p> <input type="submit" value="Rendben"> </form> </p> <a href="20.5.program.php">Tartalom</a> </body> </html>

20

Elszr elindtjuk a munkamenetet a session_start() fggvnnyel. Ezzel hozzfrnk minden korbban belltott munkamenet-vltozhoz. A HTML dokumentumon bell a FORM elem ACTION tulajdonsgt belltjuk a jelenlegi dokumentumra. Ltrehozunk egy termekek_urlap[] nev SELECT elemet, amely a termkek szmval megegyez OPTION sszetevt tartalmaz. Emlkezznk r, hogy a HTML dokumentum azon elemeinek, amelyek engedlyezik tbb elem kivlasztst, szgletes zrjellel egytt kell megadni a NAME paramtert. gy a felhasznl vlasztsa egy tmbbe kerl. A PHP kd blokkjban megvizsgljuk, hogy ltezik-e a $termekek_urlap tmb. Ha a vltoz ltezik, feltehetjk, hogy a krdvet kitltttk. Ezt a vltozt hozzrendeljk a $termekek vltozhoz, amit a session_register() fggvnnyel bejegyznk. A $termekek_urlap tmbt kzvetlenl nem jegyezzk be, mert ez egy ksbbi kitlts sorn tkzst okozhat az ugyanilyen nev, POST eljrssal rkezett vltozval.

388

20. ra A kd vgn megadunk egy hivatkozst, ahol bemutatjuk, hogy valban hozzfrnk a bejegyzett tmbhz. Ez a kd a 20.5. pldban tallhat.

20.5. program Hozzfrs bejegyzett tmb tpus vltozhoz


<?php session_start(); print session_encode(); //kdolt karaktersorozat kirsa ?> <html> <head> <title>20.5. program Hozzfrs bejegyzett tmb tpus vltozhoz</title> 8: </head> 9: <body> 10: <h1>Tartalom lap</h1> 11: <?php 12: if ( isset( $termekek ) ) 13: { 14: print "<b>A bevsrlkocsi tartalma:</b><ol>\n"; 15: foreach ( $termekek as $egytermek ) 16: print "<li>$egytermek"; 17: print "</ol>"; 18: } 19: ?> 20: <a href="20.4.program.php">Vissza a termkvlasztshoz</a> 21: </body> 22: </html> A session_start() hasznlatval folytatjuk a munkamenetet. Ellenrizzk, hogy ltezik-e a $termekek vltoz. Ha ltezik, elemeit egyenknt kirjuk a bngszbe. Termszetesen egy igazi bevsrlkosr-program megrsakor a termkeket rdemes adatbzisban, s nem a futtatand kdban trolni. A 20.4. s 20.5. plda csak azt mutatta be, hogyan rhet el egy tmb tpus vltoz egy msik oldalrl. 1: 2: 3: 4: 5: 6: 7:

llapotok trolsa munkamenet-fggvnyekkel

389

A munkamenet s a vltozk bejegyzsnek trlse

A munkameneteket s a bejegyzett vltozkat a session_destroy() fggvnnyel trlhetjk. A session_destroy() fggvnynek nincsenek paramterei, futtatshoz azonban szksges egy folyamatban lv munkamenet. A kvetkez kdrszlet ltrehoz, majd rgtn megsemmist egy munkamenetet: session_start(); session_destroy(); Amikor olyan oldalt tltnk be, amely egy munkamenetet vr, az mr nem ltja a korbban trlt munkamenetet, ezrt ltre kell hoznia egy jat. Minden korbban bejegyzett vltoz elvsz.

Valjban a session_destroy() fggvny nem semmisti meg a bejegyzett vltozkat. Abban a kdban, amelyben a session_destroy() fggvnyt futtattuk, a vltozk tovbbra is elrhetk. A kvetkez kdrszletben lthat, hogy az 5-re lltott $proba vltoz a session_destroy() meghvsa utn is elrhet marad. A munkamenet megszntetse nem trli a bejegyzett vltozkat. session_start(); session_register( "proba" ); $proba = 5; session_destroy(); print $proba; // kirja, hogy 5 A munkamenetbl a bejegyzett vltozkat a session_unset() fggvnnyel tvolthatjuk el. A session_unset() a munkamenet-fjlbl s a programbl is eltvoltja a vltozkat, ezrt vatosan hasznljuk. session_start(); session_register( proba ); $proba = 5; session_unset(); session_destroy(); print $proba; // nem r ki semmit. a $proba vltoz mr nem ltezik. A munkamenet megszntetse eltt meghvjuk a session_unset() fggvnyt, amely eltvoltja a $proba, s minden ms bejegyzett vltozt a memribl.

20

390

20. ra

Munkamenet-azonostk a lekrdez karakterlncban

ttekintettk a stin alapul munkamenetek kezelst. Tudnunk kell azonban, hogy ez nem a legbiztosabb mdszer. Nem felttelezhetjk ugyanis, hogy a ltogat bngszje tmogatja a stik hasznlatt. A problma elkerlse vgett ptsnk be programunkba egy, a munkamenet-azonost tovbbadsra alkalmas lekrdez karakterlncot. A PHP ltrehozza a SID llandt, ha a bngsz nem kldtt vissza azonostt tartalmaz stit. A SID nvrtk alak lland karakterlnc, amelyet begyazhatunk a munkamenetet tmogat oldalra mutat HTML hivatkozsokba: <a href="masik_lap.php?<? print SID; ?>">Msik lap</a> A bngszben ez mr gy jelenik meg: <a href="masik_lap.php?PHPSESSID= 08ecedf79fe34561fa82591401a01da1">Msik lap</a>

A munkamenet-azonost automatikusan tvtelre kerl, amikor a cloldalon meghvjuk a session_start() fggvnyt, s az sszes korbban bejegyzett vltoz a szoksos mdon elrhet lesz. Ha a PHP 4-et az --enable-trans-sid kapcsolval fordtottuk le a fenti lekrdez karakterlnc automatikusan hozzaddik minden HTML hivatkozshoz. Ez a lehetsg alapllapotban kikapcsolt, de hasznlatval kdjaink hordozhatbb vlnak.

Munkamenet-vltozk kdolsa s visszafejtse


Amikor megnztk a munkamenet-fjl tartalmt, lttuk, hogyan menti s kdolja a PHP a bejegyzett vltozkat. A kdolt karaktersorozathoz a session_encode() fggvny hasznlatval brmikor hozzfrhetnk. Ez hasznos lehet a munkamenetek nyomkvetsnl. A kvetkez kdrszletben lthatjuk, hogyan mkdik a session_encode() fggvny. session_start(); print session_encode()."<br>"; // minta eredmny: termekek|a:2:{i:0;s:8: "HAL 2000";i:1;s:8:"Targonca";} Lthat, hogy a fggvny trolsi alakjukban adja vissza a bejegyzett vltozkat, gy ellenrizhetjk, hogy a vltoz valban be lett-e jegyezve s rtke megfelel-e. A session_encode() fggvny hasznlatval bejegyzett vltozkat tartalmaz adatbzisokat is kszthetnk.

llapotok trolsa munkamenet-fggvnyekkel A session_decode() fggvny hasznlatval a vltozk kdolt formjbl visszanyerhetjk az rtkket. A kvetkez kdrszlet ezt mutatja be: session_start(); session_unset(); // nem szabad, hogy ltezzenek munkamenet-vltozk 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 A szoksos mdon elindtjuk a munkamenetet. Hogy tiszta lappal induljunk, a session_unset() fggvnnyel trljk az sszes korbban bejegyzett vltozt. Ezutn tadjuk a session_decode() fggvnynek a vltozk kdolt formjt. A fggvny prostja a vltozneveket a megfelel rtkekkel. Ezt ellenrizzk is: a $termekek tmb minden elemt kiratjuk.

391

20

Munkamenet-vltoz bejegyzsnek ellenrzse


Mint lttuk, a bejegyzett vltoz jelenltt az isset() fggvnnyel ellenrizhetjk, de ms mdon is megvizsglhatjuk a vltoz ltezst. Erre val a session_is_registered() fggvny. A fggvny paramterben egy vltoz nevt tartalmaz karakterlncot kell megadni, a visszatrsi rtk pedig true, ha a vltoz bejegyzett. if ( session_is_registered ( "termekek" ) ) print "A 'termekek' vltoz bejegyzett!"; Ez akkor lehet hasznos, ha biztosak akarunk lenni a vltoz forrsban, azaz, hogy a vltoz tnyleg a munkamenet bejegyzett vltozja vagy csak egy GET krelem eredmnyeknt kaptuk.

392

20. ra

sszefoglals

Ebben s az elz rban ttekintettk, hogyan menthetjk az llapotokat egy llapot nlkli protokollban. Klnfle mdszereket alkalmaztunk: stiket s lekrdez karakterlncokat hasznltunk, nha ezeket fjlokkal s adatbzisokkal tvztk. Mindegyik megkzeltsi mdnak megvannak a maga elnyei s htrnyai. A sti nem igazn megbzhat s nem trolhat sok informcit. Ezzel szemben hossz ideig fennmaradhat. Az adatok fjlban vagy adatbzisban val trolsa miatt a sebessg cskkenhet, ami gondot okoz egy npszer webhelyen. Ugyanakkor egy egyszer azonostval nagy mennyisg adathoz frhetnk hozz. A lekrdez karakterlnc a sti ellentte. Elg csnyn nz ki, de viszonylag nagy mennyisg informcit hordoz magban. Hasznlatrl a krlmnyek mrlegelse utn kell dnteni.

Ebben az rban megtanultuk, hogyan indtsunk el munkamenetet a session_start() fggvnnyel. Lttuk, hogyan jegyezhetnk be vltozkat a session_register() fggvnnyel, hogyan ellenrizhetjk a bejegyzst a session_is_registered() fggvnnyel, valamint hogyan semmisthetjk meg a vltozkat a session_unset() fggvnnyel. A munkamenet megsemmistsre a session_destroy() fggvnyt hasznltuk. Hogy minl tbb felhasznl rhesse el a munkamenetet tmogat krnyezetet, lekrdez karakterlncainkban hasznljuk a SID llandt a munkamenet-azonost tadsra.

Krdsek s vlaszok
Van valamilyen veszlye a munkamenet-fggvnyek hasznlatnak, amirl mg nem tudunk? A munkamenet-fggvnyek alapveten megbzhatk. De emlkezznk r, hogy a stik hasznlata nem lehetsges tbb tartomnyon keresztl. Ezrt, ha tbb tartomnynevet hasznlunk ugyanazon a kiszolgln (elektronikus kereskedelemi alkalmazsoknl ez gyakori), tiltsuk le a stik hasznlatt a session.use_cookies 0ra lltsval a php.ini fjlban.

llapotok trolsa munkamenet-fggvnyekkel

393

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Melyik fggvnyt hasznljuk egy munkamenet elindtsra? 2. Melyik fggvny adja vissza a jelenlegi munkamenet azonostjt? 3. Hogyan rendelhetnk vltozkat a munkamenethez? 4. Hogyan semmisthetjk meg a munkamenetet s trlhetjk el minden nyomt? 5. Hogyan semmisthetjk meg az sszes munkamenet-vltozt a fut programban s az egsz munkamenetben? 6. Mi a SID lland rtke? 7. Hogyan ellenrizhetjk, hogy a $proba nev vltoz be van-e jegyezve egy munkameneten bell?

20

Feladatok
1. Az elz ra Feladatok rszben ksztettnk egy programot, amely stit vagy lekrdez karakterlncot hasznl, hogy oldalrl oldalra vigye tovbb a felhasznl vlaszait. Ezutn a krnyezet minden oldala a belltott httrsznnel indult s nv szerint dvzlte a felhasznlt. Ksztsk el ezt a programot a PHP 4 munkamenet-fggvnyeivel. 2. Ksztsnk programot, amely munkamenet-fggvnyek hasznlatval emlkezik r, hogy a felhasznl a krnyezet mely oldalait ltogatta meg. Ksztsk el a felhasznl lpseit tartalmaz hivatkozsok sorozatt, hogy mozgsa nyomon kvethet legyen.

21. RA
Munka kiszolgli krnyezetben
A korbbi fejezetekben ttekintettk, hogyan trsaloghatunk tvoli szmtgpekkel s hogyan vehetnk t adatokat a felhasznltl. Ebben a fejezetben ismt kitekintnk, olyan eljrsokat tanulunk meg, amelyek kls programok sajt gpnkn val futtatsra hasznlhatk. A fejezet pldi Linux opercis rendszerre kszltek, de a legtbb alapelv felhasznlhat Microsoft Windows rendszerben is. A fejezetben a kvetkezket tekintjk t: Hogyan kzvettsnk adatokat a programok kztt? A hjparancsok vgrehajtsra s az eredmnyek megjelentsre milyen lehetsgeink vannak? Hogyan rhatunk biztonsgosabb PHP programokat?

396

21. ra

Folyamatok sszektse a popen() fggvnnyel

Ahogy a fjlokat nyitottuk meg rsra vagy olvassra az fopen() segtsgvel, ugyangy nyithatunk adatcsatornt kt folyamat kztt a popen() paranccsal. A popen() paramtereiben meg kell adni egy parancsot elrsi ttal, s azt, hogy rsi vagy olvassi mdban akarjuk hasznlni a fggvnyt. A popen() visszatrsi rtke az fopen() visszatrsi rtkhez hasonl fjlazonost. A popen()-nek a 'w' jelzvel adhatjuk meg, hogy rsi mdban, az 'r' jelzvel pedig azt, hogy olvassi mdban akarjuk hasznlni a fggvnyt. Ugyanazzal az adatcsatornval nem lehet egyszerre rni s olvasni is egy folyamatot. Amikor befejeztk a munkt a popen() ltal megnyitott folyamattal, a pclose() paranccsal le kell zrnunk az adatcsatornt. A pclose() fggvny paramterben egy rvnyes fjlazonostt kell megadni. A popen() hasznlata akkor javasolt, amikor egy folyamat kimenett sorrl sorra szeretnnk elemezni. A 21.1-es pldban a GNU who parancs kimenett elemezzk, s a kapott felhasznlneveket mailto hivatkozsokban hasznljuk fel.

21.1. program A who UNIX parancs kimenetnek olvassa a popen() segtsgvel


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: <html> <head> <title>21.1. program A who UNIX parancs kimenetnek olvassa a popen() segtsgvel</title> </head> <body> <h2>A rendszerbe bejelentkezett felhasznlk</h1> <?php $ph = popen( "who", "r" ) or die( "A 'who' paranccsal nem vehet fel kapcsolat" ); $kiszolgalo="www.kiskapu.hu"; while ( ! feof( $ph ) ) { $sor = fgets( $ph, 1024 ); if ( strlen( $sor ) <= 1 ) continue; $sor = ereg_replace( "^([a-zA-Z0-9_\-]+).*", "<a href=\"mailto:\\1@$kiszolgalo\">\\1</a><br>\n", $sor ); print "$sor"; }

Munka kiszolgli krnyezetben

397

21.1. program (folytats)


22: 23: 24: 25: pclose( $ph ); ?> </body> </html>

A who parancs eredmnynek kiolvasshoz szksgnk van egy fjlmutatra a popen() fggvnytl, gy a while utasts segtsgvel sorrl sorra elemezhetjk a kimenetet. Ha a sorban olvashat kimenet csupn egyetlen karakter, a while ciklus kvetkez lpsre ugrunk, kihagyva az elemzst, klnben az ereg_replace() fggvnnyel jabb HTML hivatkozssal s soremelssel bvtjk a vgeredmnyt. Vgl a pclose() fggvnnyel lezrjuk az adatcsatornt. A program egy lehetsges kimenete a 21.1. brn lthat.

21.1. bra
A who UNIX parancs kimenetnek olvassa

21

A popen() fggvny hasznlhat parancsok bemenetnek rsra is. Ez akkor hasznos, ha egy parancs a szabvnyos bemenetrl vr parancssori kapcsolkat. A 21.2. pldban azt lthatjuk, hogyan hasznlhatjuk a popen() fggvnyt a column parancs bemenetnek rsra.

398

21. ra

21.2. program A column parancs bemenetnek rsa a popen() fggvny segtsgvel


1: <html> 2: <head> 3: <title>21.2. program A column parancs bemenetnek rsa 4: a popen() fggvny segtsgvel</title> 5: </head> 6: <body> 7: <?php 8: $termekek = array( 9: array( "HAL 2000", 2, "piros" ), 10: array( "Modem", 3, "kk" ), 11: array( "Karra", 1, "rzsaszn" ), 12: array( "Ultrahangos csavarhz", 1, "narancssrga" ) 13: ); 14: $ph = popen( "column -tc 3 -s / > fizetve/3as_felhasznalo.txt", "w" ) 15: or die( "A 'column' paranccsal nem vehet fel kapcsolat" ); 16: foreach ( $termekek as $termek ) 17: fputs( $ph, join(/, $termek)."\n"); 18: pclose( $ph ); 19: ?> 20: </body> 21: </html>

A 21.2. pldban megfigyelhet, hogyan rhetk el s rhatk ASCII tblzatknt fjlba a tbbdimenzis tmbk elemei. A column parancs bemenethez adatcsatornt kapcsolunk, amin keresztl parancssori kapcsolkat kldnk. A t kapcsolval megadjuk, hogy tblzatt formzza a kimenetet, a c 3 megadja a szksges oszlopok szmt, a s / a /-t lltja be mezelvlasztknt. Megadjuk, hogy a vgeredmnyt a 3as_felhasznalo.txt fjlba rja. A fizetve knyvtrnak lteznie kell s a megfelel jogosultsg szksges, hogy a program rhasson bele. Most egyetlen utastssal egyszerre tbb dolgot tettnk. Meghvtuk a column programot s kimenett fjlba rtuk. Valjban parancsokat adtunk ki a hjnak: ez azt jelenti, hogy az adatcsatorna hasznlatval, egy folyamat futtatsval ms feladatokat is elindthatunk. A column kimenett pldul a mail parancs segtsgvel postzhatjuk valakinek:

Munka kiszolgli krnyezetben popen( "column -tc 3 -s / | mail kiskapu@kiskapu.hu", "w" ) gy elrhetjk, hogy a felhasznl ltal bert adatokkal rendszerparancsokat hajtsunk vgre PHP fggvnyekkel. Ennek nhny htrnyos tulajdonsgt mg ttekintjk az ra tovbbi rszben. Miutn rendelkeznk egy fjlazonostval, a $termekek tmb minden elemn vgiglpkednk. Minden elem maga is egy tmb, amit a join() fggvny segtsgvel karakterlncc alaktunk. Az res karakter helyett mezelvlasztknt a / karaktert vlasztjuk. Ez azrt szksges, mert ha res karakterek jelennnek meg a termkek tmbjben, az sszezavarn a column parancsot. Az talakts utn a karakterlncot s egy jsor karaktert runk ki az fputs() fggvnnyel. Vgl lezrjuk az adatcsatornt. A 3as_felhasznalo.txt fjlban a kvetkezk szerepelnek: HAL 2000 Modem Karra Ultrahangos csavarhz 2 3 1 1 piros kk rzsaszn narancssrga

399

A kdot hordozhatbb tehetjk, ha a szveg formzsra a sprintf() fggvnyt hasznljuk.

Parancsok vgrehajtsa az exec() fggvnnyel


Az exec() egyike azoknak a fggvnyeknek, amelyekkel parancsokat adhatunk ki a hjnak. A fggvny paramterben meg kell adni a futtatand program elrsi tjt. Ezen kvl megadhat mg egy tmb, mely a parancs kimenetnek sorait fogja tartalmazni s egy vltoz, amelybl a parancs visszatrsi rtke tudhat meg. Ha az exec() fggvnynek az 'ls al .' parancsot adjuk meg, akkor az aktulis knyvtr tartalmt jelenti meg. Ez lthat a 21.3. pldban.

21

21.3. program Knyvtrlista betltse a bngszbe


1: <html> 2: <head> 3: <title>21.3. program Knyvtrlista betltse a bngszbe </title> 4: </head> 5: <body>

400

21. ra

21.3. program (folytats)


6: 7: 8: 9: 10: 11: 12: 13: <?php exec( "ls -al .", $kimenet, $vissza ); print "<p>Visszatrsi rtk: $vissza</p>"; foreach ( $kimenet as $fajl ) print "$fajl<br>"; ?> </body> </html>

Ha az ls parancs sikeresen vgrehajtdik, a visszatrsi rtk 0 lesz. Ha a program a megadott knyvtrat nem tallja vagy az nem olvashat, a visszatrsi rtk 1. A vgeredmny szempontjbl nem tettnk semmi jat, hiszen az opendir() s a readdir() fggvnyekkel ugyanezt elrhettk volna, de elkpzelhet olyan eset, amikor rendszerparancsokkal vagy korbban megrt Perl programokkal sokkal gyorsabban megoldhatjuk a feladatot, mint PHP fggvnyekkel. Ha a PHP program kifejlesztsnek sebessge fontos szempont, esetleg rdemesebb a korbban megrt Perl program meghvsa mellett dnteni, mint tltetni azt PHP-be, legalbbis rvid tvon. Meg kell azonban jegyeznnk, hogy rendszerparancsok hasznlatval programjaink tbb memrit fogyasztanak s tbbnyire futsuk is lassabb.

21.2. bra
A knyvtrlista betltse a bngszbe az exec() fggvny segtsgvel

Munka kiszolgli krnyezetben

401

Kls programok futtatsa a system() fggvnnyel vagy a ` mveletjel segtsgvel


A system() fggvny az exec() fggvnyhez hasonlan kls programok indtsra hasznlhat. A fggvnynek meg kell adni a futtatand program elrsi tjt, valamint megadhat egy vltoz, amely a program visszatrsi rtkt tartalmazza majd. A system() fggvny a kimenetet kzvetlenl a bngszbe rja. A kvetkez kdrszlet a man parancs lerst adja meg: <?php print "<pre>"; system( "man man | col -b", $vissza ); print "</pre>"; ?> A PRE HTML elemet azrt adtuk meg, hogy a bngsz megtartsa a kimenet eredeti formtumt. A system() fggvnyt hasznltuk, hogy meghvjuk a man parancsot, ennek kimenett hozzkapcsoltuk a col parancshoz, amely ASCII-knt jraformzza a megjelen szveget. A visszatrsi rtket a $vissza vltozba mentjk. A system() kzvetlenl a bngszbe rja a kimenetet. Ugyanezt az eredmnyt rhetjk el a ` mveletjel hasznlatval. A kiadand parancsot egyszeren ilyen fordtott irny aposztrfok kz kell tennnk. Az gy megadott parancsot a rendszer vgrehajtja s visszatrsi rtkknt a parancs kimenett adja, amit kirhatunk vagy vltozban trolhatunk. me az elz plda ilyetn megvalstsa: print "<pre>"; print `man man | col -b`; print "</pre>"; Vegyk szre, hogy ebben a megvalstsban rgtn kirtuk a vgeredmnyt.

21

Biztonsgi rsek megszntetse az escapeshellcmd() fggvny hasznlatval


Az escapeshellcmd() fggvny ismertetse eltt tekintsk t, mivel szemben van szksgnk vdelemre. A plda erejig tegyk fel, hogy meg szeretnnk engedni a ltogatknak, hogy klnbz sgoldalakat tekinthessenek meg. Ha bekrjk egy oldal nevt, a felhasznl brmit berhat oda. A 21.4. pldban tallhat programot ne teleptsk, mert biztonsgi rst tartalmaz!

402

21. ra

21.4. program A man program meghvsa


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: <html> <head> <title>21.4. program A man program meghvsa. Ez a kd nem biztonsgos</title> </head> <body> <form> <input type="text" value="<?php print $manoldal; ?>" name="manoldal"> </form> <pre> <?php if ( isset($manoldal) ) system( "man $manoldal | col -b" ); ?> </pre> </body> </html>

Korbbi pldnkat egy szveges mezvel s a system() fggvnnyel egsztettk ki. Megbzhatnak tnik, UNIX rendszeren azonban a felhasznl a manoldal mezhz hozzadhatja sajt parancsait, gy hozzfrhet a kiszolgln szmra tiltott rszen lv adatokhoz is. Erre lthatunk pldt a 21.3. brn.

21.3. bra
A man program meghvsa

Munka kiszolgli krnyezetben A felhasznl az oldalon keresztl kiadta az xxx; ls al parancsot. Ezt a $manoldal vltozban troljuk. A program futsa kzben a system() fggvnynek a kvetkez parancsot kell vgrehajtania: "man xxx; ls -al | col -b" Vagyis meg kell jelentenie az xxx parancshoz tartoz sgoldalt, ami termszetesen nem ltezik. Ebben az esetben a col parancs bemenete a teljes knyvtrlista lesz. Ezzel a tmad kirathatja a rendszer brmelyik olvashat knyvtrnak tartalmt. A kvetkez utastssal pldul a /etc/passwd tartalmt kapja meg: xxx; cat /etc/passwd Br a jelszavak egy titkostott fjlban, az /etc/shadow-ban vannak trolva, amely csak a rendszergazda (root) ltal olvashat, ez mgis egy igen veszlyes biztonsgi rs. A legegyszerbben gy vdekezhetnk ellene, hogy soha nem engedlyezzk, hogy a felhasznlk kzvetlenl adjanak parancsot a rendszernek. Ennl kicsit tbb lehetsget ad, ha az escapeshellcmd() fggvnnyel fordtott perjel (\) karaktert adunk minden metakarakterhez, amit a felhasznl kiadhat. Az escapeshellcmd() fggvny paramtere egy karakterlnc, vgeredmnye pedig egy talaktott msolat. A korbbi kd biztonsgosabb vltozata a 21.5. pldban tallhat.

403

21.5. program A felhasznli bemenet javtsa az escapeshellcmd() fggvny hasznlatval


1: <html> 2: <head> 3: <title>21.5. program A felhasznli bemenet javtsa 4: az escapeshellcmd() fggvny hasznlatval</title> 5: </head> 6: <body> 7: <form> 8: <input type="text" value="<?php print $manoldal; ?>" name="manoldal"> 9: </form> 10: <pre> 11: <?php

21

404

21. ra

21.5. program (folytats)


12: 13: 14: 15: 16: 17: 18: 19: 20: if ( isset($manoldal) ) { $manoldal = escapeshellcmd( $manoldal ); system( "man $manoldal | col -b" ); } ?> </pre> </body> </html>

Ha a felhasznl most kiadja az xxx; cat etc/passwd parancsot, akkor a system() fggvny meghvsa eltt az escapeshellcmd() az xxx\; cat /etc/passwd paranccs alaktja azt, azaz a cat utasts sgjt kapjuk a jelszfjl helyett. A rendszer biztonsgt az escapeshellcmd() fggvny segtsgvel tovbb nvelhetjk. Lehetsg szerint kerljk azokat a helyzeteket, ahol a felhasznlk kzvetlenl a rendszernek adnak ki parancsokat. A programot mg biztonsgosabb tehetjk, ha listt ksztnk az elrhet sgoldalakrl s mg mieltt meghvnnk a system() fggvnyt, sszevetjk a felhasznl ltal bertakat ezzel a listval.

Kls programok futtatsa a passthru() fggvnnyel


A passthru() fggvny a system()-hez hasonl, azzal a klnbsggel, hogy a passthru()-ban kiadott parancs kimenete nem kerl tmeneti trba. gy olyan parancsok kiadsra is lehetsg nylik, amelyek kimenete nem szveges, hanem binris formtum. A passthru() fggvny paramtere egy rendszerparancs s egy elhagyhat vltoz. A vltozba kerl a kiadott parancs visszatrsi rtke. Lssunk egy pldt! Ksztsnk programot, amely a kpeket kicsinytett mintaknt jelenti meg s meghvhat HTML vagy PHP oldalalakrl is. A feladatot kls alkalmazsok hasznlatval oldjuk meg, gy a program nagyon egyszer lesz. A 21.6. pldban lthat, hogyan kldhetnk a kprl mintt a bngsznek.

Munka kiszolgli krnyezetben

405

21.6. program A passthru() fggvny hasznlata kpek megjelentsre


1: <?php 2: if ( isset($kep) && file_exists( $kep ) ) 3: { 4: header( "Content-type: image/gif" ); 5: passthru( "giftopnm $kep | pnmscale -xscale .5 -yscale .5 | ppmtogif" ); 6: } 7: else 8: print "A(z) $kep nev kp nem tallhat."; 9: ?>

Vegyk szre, hogy nem hasznltuk az escapeshellcmd() fggvnyt, ehelyett a felhasznl ltal megadott fjl ltezst ellenriztk a file_exists() fggvnnyel. Ha a $kep vltozban trolt kp nem ltezik, nem is prbljuk megjelenteni. A program mg biztonsgosabb tehet, ha csak bizonyos kiterjeszts fjlokat engedlyeznk s korltozzuk az elrhet knyvtrakat is. A passthru() hvsakor hrom alkalmazst indtunk el. Ha ezt a programot hasznlni akarjuk, rendszernkre teleptennk kell ezen alkalmazsokat s meg kell adni azok elrsi tjt. Elszr a giftopnm-nek tadjuk a $kep vltoz rtkt. Az beolvassa a GIF kpet s hordozhat formtumra alaktja. Ezt a kimenetet rkapcsoljuk a pnmscale bemenetre, amely 50 szzalkkal lekicsinyti a kpet. Ezt a kimenetet a ppmtogif bemenetre kapcsoljuk, amely visszaalaktja GIF formtumv, majd a kapott kpet megjelentjk a bngszben. A programot a kvetkez utastssal brmelyik weboldalrl meghvhatjuk: <img src="21.6.program.php?kep=<?php print urlencode("/utvonal/kep.gif") ?>">

21

Kls CGI program meghvsa a virtual() fggvnnyel


Ha egy oldalt HTML-rl PHP-re alaktunk, azt vesszk szre, hogy a kiszolgloldali beillesztsek nem mkdnek. Ha Apache modulknt futtatjuk a PHP-t, a virtual() fggvnnyel kls CGI programokat hvhatunk meg, pldul Perl vagy C nyelven rt szmllkat. Minden felhasznlt CGI programnak rvnyes HTTP fejlccel kell kezdenie a kimenett.

406

21. ra rjunk egy Perl CGI programot! Ne aggdjunk, ha nem ismerjk a Perlt. Ez a program egyszeren egy HTTP fejlcet r ki s minden rendelkezsre ll krnyezeti vltozt felsorol: #!/usr/bin/perl -w print "Content-type: text/html\n\n"; foreach ( keys %ENV ){ print "$_: $ENV{$_}<br>\n"; } Mentsk a programot a cgi-bin knyvtrba proba.pl nven. Ezutn a virtual() fggvnnyel a kvetkezkppen hvhatjuk meg: <?php virtual("/cgi-bin/proba.pl"); ?>

sszefoglals
Ebben a fejezetben ttekintettk, hogyan mkdhetnk egytt a hjjal s rajta keresztl a kls alkalmazsokkal. A PHP sok mindenre hasznlhat, de lehet, hogy kls programok hasznlatval az adott problma elegnsabb megoldshoz jutunk. Megtanultuk, hogyan kapcsolhatunk ssze alkalmazsokat a popen() fggvny segtsgvel. Ez akkor hasznos, amikor a programok a szabvnyos bemenetrl vrnak adatokat, de mi egy alkalmazs kimenetbl szeretnnk tovbbtani azokat. Megnztk, hogyan hasznlhat az exec() s a system() fggvny, valamint a fordtott irny aposztrf mveletjel a felhasznli utastsok kzvettsre a rendszermag fel. Lttuk, hogyan vdekezznk a betrsre hasznlhat utastsok ellen az escapeshellcmd() fggvny segtsgvel. Lttuk, hogyan fogadhatk binris adatok rendszerparancsoktl a passthru() fggvnnyel s hogy hogyan valsthatjuk meg a kiszolgloldali beillesztseket (SSI) a virtual() fggvnnyel.

Munka kiszolgli krnyezetben

407

Krdsek s vlaszok
Sokat emlegettk a biztonsgot ebben a fejezetben. Honnan tudhatunk meg tbbet a szksges biztonsgi vintzkedsekrl? A legbvebb szmtgpes biztonsggal foglalkoz forrs Lincoln Stein (a hres Perl modul, a CGI.pm szerzje) ltal fenntartott FAQ. Megtallhat a http://www.w3.org/Security/Faq/ cmen. rdemes a PHP kziknyv biztonsgrl szl rszt is tanulmnyozni. Mikor hasznljunk kls alkalmazsokat sajt PHP kdok helyett? Hrom szempontot kell megvizsglnunk: a hordozhatsgot, a fejlesztsi sebessget s a hatkonysgot. Ha sajt kdot hasznlunk kls programok helyett, programunk knnyebben tvihet lesz a klnbz rendszerek kztt. Egyszer feladatoknl, pldul knyvtr tartalmnak kiratsakor, sajt kddal oldjuk meg a problmt, gy cskkenthetjk a futsi idt, mivel nem kell minden futs alkalmval egy kls programot meghvnunk. Msrszrl nagyobb feladatoknl sokat segthetnek a ksz kls programok, mivel kpessgeiket nehz lenne megvalstani PHP-ben. Ezekben az esetekben egy kln erre a clra ksztett kls alkalmazs hasznlata javasolt.

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

21

Kvz
1. Melyik fggvnyt hasznljuk alkalmazsok sszekapcsolsra? 2. Hogyan olvasunk adatokat egy folyamat kimenetrl, miutn elindtottuk? 3. Hogyan runk adatokat egy folyamat bemenetre, miutn elindtottuk? 4. Az exec() fggvny kzvetlenl a bngszbe rja a vgeredmnyt? 5. Mit csinl a system() fggvny a vgrehajtott kls parancs kimenetvel? 6. Mi a fordtott irny aposztrf visszatrsi rtke? 7. Hogyan adhat ki biztonsgosan a felhasznl parancsokat a rendszerhjnak? 8. Hogyan hajthatunk vgre kls CGI programot a PHP programokbl?

408

21. ra

Feladatok
1. rjunk programot, amely a UNIX ps parancsnak segtsgvel megjelenti a bngszben a fut folyamatokat! (Megjegyezzk, hogy nem biztonsgos, ha a felhasznlk futtathatjk a programot!). 2. Nzzk meg a ps parancs sgjban a lehetsges parancssori kapcsolkat! Mdostsuk az elz programot, hogy a felhasznl a kapcsolk egy rszt hasznlhassa. Ne kldjnk ellenrizetlen utastsokat a rendszermagnak!

22. RA
Hibakeress
E knyv rsakor a PHP 4 semmilyen hibakeres eszkzt nem tartalmazott. A fejlesztk gretet tettek hibakeres szolgltatsok beptsre, pldul hogy a verem tartalmt nyomon kvethessk, ezrt elkpzelhet, hogy mire e knyv az Olvas kezbe kerl, a legfrissebb kiads mr tartalmaz valamilyen fejlettebb hibakeres eszkzt. Ebben a fejezetben a kdban rejl hibk feldertsnek nhny egyszer mdjt mutatjuk be. Az rban a kvetkez tmkkal foglalkozunk: A PHP belltsainak lekrdezse A PHP ltal automatikusan elrhetv tett vltozk Hibazenetek kirsa naplfjlba Az adatok nyomon kvetse a programban A gyakori hibk felfedezse Informcik a PHP-rl s adott programokrl

410

22. ra Ha egy program nem mkdik megfelelen, rdemes elszr is a PHP belltsait megvizsglnunk. Ezutn jhetnek a PHP ltal ltrehozott s a sajt vltozk, s ha mg mindig nem talljuk a hibt, akkor megvizsglhatjuk a forrskdot egy olyan eszkzzel, amely sznkiemelssel jelzi a nyelvtani elemeket gy hamar rbukkanhatunk a problms rszre. Ebben a rszben kt mdszert is megvizsglunk arra, hogyan szerezhetnk informcikat a hasznlt PHP-rtelmezrl s magrl a fut programrl.

A phpinfo()
A phpinfo() fggvny az egyik leghasznosabb hibakeres eszkz: rszletes informcikkal szolgl magrl a PHP-rl, a kiszolgli krnyezetrl s a fut program vltozirl. A fggvnynek nem kell tadnunk semmilyen paramtert s csak egy logikai rtket ad vissza, viszont egy csinos HTML oldalt kld a bngsznek. A phpinfo() kimenett a 22.1. brn lthatjuk.

22.1. bra
PHP informcik megjelentse

Az oldal tetejn a hasznlt PHP-vltozatrl, a webkiszolgl tpusrl, a rendszerrl s a szerzkrl tallunk informcikat. A kvetkez tblzat rszletezi a PHP belltsait ezeket a php.ini fjlban mdosthatjuk. Tegyk fel pldul, hogy van egy "felhasznalo" nev rlapmeznk, de a programban valamilyen okbl nem jn ltre a $felhasznalo vltoz. Vessnk egy pillantst a kvetkez belltsokra: track_vars On register_globals Off

Hibakeress Mr meg is talltuk a problma forrst. A track_vars hatsra a GET vltozk a $HTTP_GET_VARS[] tmbben troldnak, a POST vltozk a $HTTP_POST_VARS[] tmbben, mg a stik a $HTTP_COOKIE_VARS[] tmbben. Ez eddig rendben is van, a register_globals kikapcsolsa azonban azt jelenti, hogy a vltozk nem jnnek ltre globlis PHP vltozk formjban. Alapllapotban mindkt lehetsg engedlyezett. Ebben az esetben kt lehetsgnk van. Keressk meg a register_globals bejegyzst a php.ini fjlban s vltoztassuk On-ra. Nem tudjuk, merre keressk a php.ini fjlt? Nos, a phpinfo() tblzataiban errl is kaphatunk informcit. A msik lehetsgnk, hogy a "felhasznalo" mez tartalmra a program ne $felhasznaloknt, hanem $HTTP_POST_VARS["felhasznalo"]-knt hivatkozzunk. Egy olyan tblt is tallnunk kell, amely a felhasznli munkamenetek kezelsre vonatkoz belltsokat tartalmazza. Ha ez hinyzik, akkor a PHP-vltozatunkba nem fordtottuk bele a munkamenetek kezelsnek tmogatst. A tblzatban hasznos informcikat tallunk a munkamenetek kezelst megvalst kd hibakeresshez. Tegyk fel pldul, hogy olyan munkameneteket szeretnnk ltrehozni, amelyek bizonyos ideig fennmaradnak. Ha a munkamenet elvsz, amikor a felhasznl bezrja a bngsz ablakt, s a phpinfo() a kvetkez belltst mutatja: session.cookie_lifetime 0

411

mr meg is talltuk a problma forrst. A session.cookie_lifetime rtket kell tlltanunk a php.ini fjlban, annak megfelelen, hogy hny msodpercig szeretnnk fenntartani a munkameneteket. Ha a php.ini llomny a kvetkez sort tartalmazza: session.use_cookies 0

a stik nem engedlyezettek a munkamenetek kezelse sorn. Ebben az esetben az azonosts sorn a lekrdez karakterlncra kell hagyatkoznunk vagy mdostanunk kell a belltst a php.ini-ben. A phpinfo() a webkiszolglrl is rengeteg hasznos informcival szolgl, klnsen akkor, ha Apache fut a gpnkn. Lthatjuk pldul a programmal kapcsolatban forgalmazott sszes krs- s vlaszfejlcet, illetve a kiszolgl krnyezeti vltozit is (pldul HTTP_REFERER). Ha a PHP-t adatbzis-tmogatssal fordtottuk, az erre vonatkoz belltsokat is lthatjuk, pldul az alaprtelmezett felhasznlt, IP cmet s kaput.

22

412

22. ra Az egyik legfontosabb informciforrsunk lehet az a tbla, amelyben a PHP ltal ltrehozott globlis vltozk vannak felsorolva az rtkeikkel egytt. Lssunk erre egy pldt. A 22.1. plda egy egyszer programot tartalmaz, amely ltrehoz egy HTML rlapot s bellt egy stit.

22.1. program A phpinfo() fggvny kiprblsa


1: <?php 2: setcookie( "azonosito", "2344353463433", time()+3600, "/" ); 3: ?> 4: <html> 5: <head> 6: <title>22.1. program A phpinfo() fggvny kiprblsa</title> 7: </head> 8: <body> 9: <form action="<?php print "$PHP_SELF" ?>" METHOD="get""> 10: <input type="text" name="felhasznalo"> 11: <br> 12: <select name="termekek[]" multiple> 13: <option>Krumpli 14: <option>Sajt 15: <option>Kenyr 16: <option>Csirke 17: </select> 18: <br> 19: <input type="submit" value="Lssuk!"> 20: </form> 21: <p></p> 22: <hr> 23: <p></p> 24: <?php 25: phpinfo(); 26: ?> 27: </body> 28: </html> Ha a Lssuk! gombra kattintunk, a program megkapja a felhasznl ltal megadott adatokat s a sti is belltdik. Ha meghvjuk a phpinfo() fggvnyt, ltni fogjuk ezeket a vltozkat a kimenet lnyeges rszt a 22.2. brn lthatjuk.

Hibakeress

413

22.2. bra
Globlis vltozk elrse

Lthat, hogy a sti s a $HTTP_GET_VARS vltoz elrhet. Az rlap tartalmazott egy olyan listt is, amelybl tbb elemet is kivlaszthattunk a vltozk kztt a teljes tmb megjelenik. Nagyobb llegzet feladatoknl gyakran gondot okoz az rlapvltozk s a stik nyomon kvetse, ilyenkor a phpinfo() felbecslhetetlen segtsget nyjthat.

A forrskd megjelentse sznkiemelssel


Ha nem talljuk meg a problma forrst a phpinfo() fggvny segtsgvel, taln nem is a belltsokkal van baj. J tlet lehet egy jabb pillantst vetni a forrskdra. A PHP segtsgvel megtekinthetjk a program forrskdjt, radsul a kulcsszavakat, a karakterlncokat, a megjegyzseket s a HTML kdot sznkiemelssel is megjelenthetjk. Ha Apache kiszolglt hasznlunk, a belltfjlhoz (tbbnyire httpd.conf) kell hozzadnunk a kvetkez sort: AddType application/x-httpd-php-source .phps Ezutn minden .phps kiterjeszts fjl sznkiemelssel fog megjelenni a bngszablakban. Ha nincs jogunk megvltoztatni a kiszolgl belltllomnyt, hasznljuk a show_source() fggvnyt, amely a paramterl megadott fjlt sznkiemelssel jelenti meg a bngszablakban.

22

414

22. ra A 22.2. pldaprogram segtsgvel megtekinthetjk programjaink forrskdjt.

22.2. program Dokumentum forrsnak megjelentse


1: <html> 2: <head> 3: <title>22.2. program Dokumentum forrsnak megjelentse</title> 4: </head> 5: <body> 6: <form action="<?php print "$PHP_SELF" ?>" method="get"> 7: Krem a fjl nevt: 8: <input type="text" name="file" value="<?php print $file; ?>"> 9: <p></p><hr><p></p> 10: <?php 11: if ( isset( $file ) ) 12: show_source( $file ) or print "nem lehet megnyitni a kvetkez fjlt: \"$file\""; 13: ?> 14: </body> 15: </html> A 22.3. bra a 22.2. pldaprogramot mutatja mkds kzben.

22.3. bra
Sznkiemels hasznlata

Mirt hasznos ez a lehetsg? Hiszen megnzhetnnk a kdot megszokott szvegszerkesztnkkel is. A legnagyobb elny a sznkiemelsben rejlik. Igen knny szrevenni pldul az elgpelseket, hiszen ezeket nem kulcsszknt rtelmezi a megjelent, ezrt ms sznnel jelli.

Hibakeress Egy msik gyakori problma, hogy elg nehz nyomon kvetni egy flig nyitott idzjel-prt. Mivel a PHP az idzjel utni szveget karakterlncknt rtelmezi, gyakran rossz helyen jelzi a hibt. Az idzjelben lv karakterlncok szintn ms sznnel jelltek, gy ez a tpus hiba nagyon knnyen szrevehet. Ne tegyk ezt a programot elrhetv webhelynkn, mert gy brki belenzhet forrsainkba. Csak fejlesztskor hasznljuk ezt a kdot! A 22.1. tblzat a sznkiemelsek jelentst tartalmazza.

415

22.1. tblzat Sznkiemelsek


php.ini bejegyzs
highlight.string highlight.comment highlight.keyword

Alaprtelmezett szn Vrs


Narancs Zld

Kd
#DD0000 #FF8000 #007700

Jelents
Idzjelek s karakterlncok PHP megjegyzsek Mveletjelek, nyelvi elemek s a legtbb beptett fggvny Minden egyb PHP kd HTML kd

highlight.default highlight.html

Kk Fekete

#0000BB #000000

PHP hibazenetek
Mikzben e knyv segtsgvel elsajttottuk a PHP programozs alapjait, bizonyra elfordult, hogy hibazeneteket kaptunk a vrt eredmny helyett. Pldul elfelejtettnk zrjelbe tenni egy kifejezst vagy elgpeltk egy fggvny nevt. A hibazenetek nagyon fontosak a hibakeress sorn. lltsuk a php.ini fjlban a display_errors bejegyzst "On"-ra, ezzel biztosthatjuk, hogy a PHP elkldje a hibazeneteket a bngsznek. Ne feledjk, hogy a phpinfo() fggvny segtsgvel megnzhetjk, hogy be van-e kapcsolva ez a lehetsg. Miutn meggyzdtnk arrl, hogy programunk tudatni fogja velnk az esetleges hibkat, meg kell adnunk, hogy mennyire legyenek szigorak az zenetek. Ha be akarunk lltani egy alaprtelmezett szintet, rendeljnk a php.ini fjlban az error_reporting bejegyzshez egy szmot. Szerencsre nem kell fejben

22

416

22. ra tartanunk az sszes szmot, mivel rendelkezsnkre llnak azok az llandk, amelyeket a hibakezels szintjnek belltshoz hasznlhatunk. A klnbz rtkeket a 22.2. tblzat tartalmazza.

22.2. tblzat Hibakezelsi szintek


lland
E_ALL E_ERROR

Nv Mind
Hibk

Lers Mindenfle hiba


Vgzetes hibk (pldul memriakiosztsi problmk)

Mi trtnik? Fgg a hiba tpustl


Felhasznl rtestse s a program futsnak meglltsa rtesti a felhasznlt, de nem szaktja meg Felhasznl rtestse s a program futsnak meglltsa rtesti a felhasznlt s folytatja a program futtatst

E_WARNING

Figyelmeztetsek

Nem vgzetes hibk (pldul nem szab-

lyos paramtertads) a program futst


E_PARSE

rtelmez hiba

Az rtelmez nem rti az utastst

E_NOTICE

Megjegyzsek

Lehetsges problmaforrs (pldul egy kezdeti rtkkel el nem ltott vltoz)

E_CORE_ERROR

Bels hiba az rtel- Az rtelmez indtsa- Megszaktja mez indtsakor kor fellp vgzetes hibk az rtelmez indtst

E_CORE_WARNING Figyelmeztet

Az rtelmez indtsa- rtesti a felhasznlt s kor fellp nem vgzetes hibk folytatja a program futtatst

zenet az rtelmez indtsakor

Ezekkel a belltsokkal nem vltoztathatjuk meg, mi trtnjen a hiba felbukkansakor, csak abba van beleszlsunk, hogy a hibazenetet el akarjuk-e kldeni a bngsznek vagy sem. Termszetesen egyszerre tbb hibakezelsi szintet is engedlyezhetnk, ekkor az egyes szinteket a VAGY (|) jellel elvlasztva kell megadnunk. A kvetkez sor pldul engedlyezi a hibazenetek s a figyelmeztetsek megjelentst is: error_reporting = E_ERROR|E_WARNING

Hibakeress Ha a hibakezelst az sszes hibatpusra ki akarjuk terjeszteni, hasznljuk az E_ALL llandt. Mi a teend akkor, ha az sszes tpust engedlyezni szeretnnk, kivve egyet? A kvetkez sor ppen ezt valstja meg: error_reporting = E_ALL & ~E_NOTICE Az rtelmez a megjegyzseken kvl minden felmerl zenetet elkld a bngsznek. Az E_ERROR|E_WARNING s az E_ALL&~E_NOTICE tulajdonkppen kettes szmrendszerbeli aritmetikai mveletek, melyek eredmnye egy j hibakezelsi szintet megad szm. A kettes szmrendszerbeli aritmetikval ebben a knyvben nem foglalkozunk, de a mdszer ettl mg remlhetleg rthet marad. A php.ini belltst az error_reporting() fggvnnyel brlhatjuk fell, melynek bemen paramtere a hibakezelsi szintet megad egsz szm, visszatrsi rtke pedig a megelz hibakezelsi bellts. Termszetesen ennl a fggvnynl is hasznlhatjuk az elzekben megismert llandkat. Lssunk egy pldt egy olyan esetre, ahol a hibakezelsi szint mdostsa a segtsgnkre lehet. Lssuk, szrevesszk-e a szndkolt hibt a 22.3. programban.

417

22.3. program Egy szndkos hiba


1: 2: 3: 4: 5: 6: 7: 8: 9: <?php error_reporting( E_ERROR|E_WARNING|E_PARSE ); $flag = 45; if ( $flg == 45 ) { print "Tudom, hogy a \$flag vltoz rtke 45"; } else { print "Tudom, hogy a \$flag vltoz rtke NEM 45"; }; ?>

22

Mint lthat, a $flag vltoz rtkt akarjuk vizsglni, de elgpeltk. Nincs vgzetes hiba a programban, gy minden tovbbi nlkl lefut s az E_ERROR|E_WARNING|E_PARSE hibakezelsi bellts mellett mg csak zenetet sem kld a bngsznek. A kd bekerl a programba s a lehet legrosszabb pillanatban mkdsbe lp. Ha azonban az error_reporting() fggvnynek az E_ERROR|E_WARNING|E_PARSE|E_NOTICE rtket adnnk t (ez magban foglalja a megjegyzsek elkldst is), a program a kvetkez kimenetet klden:

418

22. ra Warning: Undefined variable: flg in /home/httpd/htdocs/ peldak/22.3.program.php on line 4 Tudom, hogy a $flag vltoz rtke NEM 45 Azaz: Figyelem: Nem meghatrozott vltoz: flg a /home/httpd/htdocs/ peldak/22.3.program.php fjlban a 4. sorban Tudom, hogy a $flag vltoz rtke NEM 45 Az zenetbl nem csak az derl ki szmunkra, hogy valami nincs rendben, de mg a problms sor szmt is megtudtuk. Ugyanezt a hatst gy is elrhetjk, ha az error_reporting() fggvnynek az E_ALL llandt adjuk t paramterknt, ennek azonban lehetnek nem kvnt mellkhatsai is. Elkpzelhet az is, hogy szndkosan alkalmazunk nem meghatrozott vltozkat. Vegyk pldul a kvetkez kdrszletet: <INPUT TYPE="text" NAME="felhasznalo" VALUE="<? print $felhasznalo; ?>"> Itt azt hasznljuk ki, hogy ha egy nem meghatrozott vltoz rtkt ratjuk ki, akkor annak hasonl a hatsa ahhoz, mintha egy res karakterlncot jelentennk meg (tulajdonkppen semmilyen hatsa nincs). A "felhasznalo" mez egy elzleg elkldtt rtket vagy semmit sem tartalmaz. Ha a megjegyzsek elkldst is engedlyeztk, hibazenetet kapunk.

Hibazenetek kirsa naplfjlba


Azok a hibk, amelyekre eddig vadsztunk, nagyobb rszben azonnali, fejleszts kzben keletkez hibk voltak. Vannak azonban olyan problmk is, amelyek ksbb jnnek el, pldul azrt, mert megvltozik a futtat krnyezet. Tegyk fel pldul, hogy szksgnk van egy programra, amely a felhasznl ltal kitlttt rlap adatait rja fjlba. Elksztjk a programot, kiprbljuk, mrjk a teljestmnyt les krlmnyek kztt, majd magra hagyjuk, hogy vgezze a feladatt. Nhny httel ksbb azonban vletlenl trljk azt a knyvtrat, amely az adott fjlt tartalmazza. A PHP error_log() fggvnye pontosan az ilyen esetekre kifejlesztett hibakeres eszkz. Ez egy beptett fggvny, amellyel a kiszolgl naplfjljba vagy egy ltalunk megadott fjlba naplzhatjuk a felmerl hibkat. Az error_log() fggvnynek kt bemen paramtere van: egy karakterlnc, amely a hiba szvegt tartalmazza s egy egsz szm, amely a hiba tpust rja le. A hiba tpustl fggen egy tovbbi paramtert is meg kell adnunk az error_log() fggvnynek: egy elrsi utat vagy egy e-mail cmet.

Hibakeress A 22.3. tblzat az elrhet hibatpusokat sorolja fel.

419

22.3. tblzat Az error_log() fggvny hibatpusai


rtk 0
1 3

Lers A hibazenetet a php.ini fjl error_log bejegyzsnl megadott fjlba kell kirni.
A hibazenetet a harmadik paramterben megadott e-mail cmre kell kldeni. A hibazenetet a harmadik paramterben megadott fjlba kell kirni.

Ha hibanaplzst szeretnnk, adjunk meg egy naplfjlt a php.ini error_log bejegyzsnl. Termszetesen a phpinfo() fggvnnyel megnzhetjk, van-e mr ilyen bellts a php.ini fjlban. Ha nincs, adjuk hozz a fjlhoz pldul a kvetkez bejegyzst: error_log = /home/httpd/logs/php_errors Ha NT vagy Unix opercis rendszert hasznlunk, a "syslog" karakterlncot is hozzrendelhetjk az error_log bejegyzshez. Ekkor a 0-s hibatpussal meghvott error_log() hibazenetek a rendszernaplba (Unix), illetve az esemnynaplba (NT) kerlnek. A kvetkez kdrszlet egy hibazenetet hoz ltre, ha nem tudunk megnyitni egy fjlt: fopen( "./fontos.txt", "a" ) or error_log( __FILE__.", ".__LINE__.". sor: Nem lehet megnyitni a kvetkez fjlt: ./fontos.txt", 0 ); A hibazenet a __FILE__ s __LINE__ llandkat hasznlja, amelyek az ppen fut program elrsi tjt, illetve az aktulis sor szmt tartalmazzk. A 0-s hibatpussal azt adjuk meg, hogy a hibazenet a php.ini fjlban megadott helyre kerljn. Ezek alapjn valami ilyesmi bejegyzs kerl a naplfjlba: /home/httpd/htdocs/proba5.php, 4. sor: Nem lehet megnyitni a kvetkez fjlt: ./fontos.txt Ha a hibazenetet adott fjlba akarjuk kikldeni, hasznljuk a 3-as hibatpus paramtert:

22

420

22. ra if ( ! $megvan = mysql_connect( "localhost", "jozsi", "valami" ) ) { error_log( date("d/m/Y H I")." Nem lehet csatlakozni az adatbzishoz", 3, "dbhiba.txt" ); return false; } Ha 3-as tpus hibazenetet hozunk ltre, egy harmadik paramterben azt is meg kell adnunk az error_log() fggvnynek, hogy hov kerljn a hibazenet. Az error_log() fggvnynek azt is megadhatjuk, hogy a hibazenetet egy e-mail cmre postzza. Ehhez az 1-es tpuskdot kell hasznlnunk: if ( ! file_exists( "kritikus.txt" ) ) or error_log( ", nem! kritikus.txt-nek vge van!", 1, "veszeset@kritikus.hu" ); Ha 1-es tpus hibazenetet kldnk, az error_log() harmadik paramterben meg kell adnunk az e-mail cmet is.

A hibazenet elfogsa
Ha hibazeneteket runk egy fjlba vagy elektronikus levlben kldjk el azokat, hasznos lehet, ha hozzfrnk a PHP ltal ellltott hibazenethez. Ehhez a php.ini fjlban a track_errors bejegyzst "On"-ra kell lltanunk ennek hatsra a legutols PHP hibazenet bekerl a $php_errormsg vltozba (hasonlan a Perl $! vltozjhoz). A $php_errormsg vltoz felhasznlsval a hibazeneteket s naplbejegyzseket beszdesebb tehetjk. A kvetkez kdrszlet ltal ltrehozott hibazenet mr sokkal hasznlhatbb, mint az elzek: fopen( "./fontos.txt", "a" ) or error_log( __FILE__.", ".__LINE__.". sor: ".$php_errormsg, 0 ); Az zenet gy fog festeni: /home/httpd/htdocs/proba.php, 21. sor: fopen("./fontos.txt","a") - Permission denied

Hibakeress

421

Kzi hibakeress

Mindig nagyon nehz azonban az olyan hibk kijavtsa, amelyek nem vltanak ki hibazenetet.

A hibakeress egyik kzenfekv mdja, ha megtzdeljk a kdunkat print utastsokkal s kiratjuk a fontosabb vltozk rtkt. A futs sorn a vltozk ugyanis gyakran nem vrt rtkeket vesznek fel Egy jellemz nyomkvet sor: print "<p>\$valtozo: $valtozo</p>"; Ez egy gyors prba, amit beszrhatunk a programba, a $valtozo rtknek ellenrzsre. Termszetesen a fent alkalmazott mdszer nem ktelez rvny mindenki kialakthatja a sajt mdszert, pldul: print "<p>".__LINE__.": \$teszt rtke: $teszt</p>";

Taln a legknyelmesebb mdszer, ha runk egy fggvnyt a vltozk rtknek nyomon kvetsre s az include() hasznlatval elrhetv tesszk a fejlesztsi szakaszban. A 22.4. plda egy olyan fggvnyt tartalmaz, amely lehetv teszi a fejleszt ltal megadott formtum nyomkvetsi zenetek megjelentst.

22.4. program Formzott nyomkvetsi zenetek megjelentse


1: <?php 2: function debug( $sor, $uzenet) 3: { 4: static $hivasok = 1; 5: print "<P><HR>\n"; 6: print "DEBUG $hivasok: $sor. sor: $uzenet<br>"; 7: $argumentumok = func_get_args(); 8: if ( count( $argumentumok ) % 2 ) 9: print "Pratlan szm paramter!<BR>"; 10: else 11: { 12: for ( $x=2; $x< count($argumentumok); $x += 2 ) 13: { 14: print "&nbsp;&nbsp; \$$argumentumok[$x]: " .$argumentumok[$x+1];

22

422

22. ra

22.4. program (folytats)


15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: print " .... (".gettype( $argumentumok[$x+1] ).")<BR>\n"; }

} print "<hr><p></p>\n"; $hivasok++; } $proba = 55; debug( __LINE__, "Els zenet:", "proba", $proba ); $teszt = 66; $proba2 = $proba/2; debug( __LINE__, "Msodik zenet", "proba", $proba, "proba2", $proba2 ); 26: ?>

A debug() fggvnynek egy sorszmot, egy zenetet, illetve tetszleges szm nvrtk prt adhatunk t. A sor szmt s az zenetet kirni a feladat knnyebbik rsze. Ezutn ki kell hasznlnunk a PHP 4 azon tulajdonsgt, hogy egy fggvnyt vltoz szm paramterrel is meghvhatunk. A func_get_args() ltal visszaadott tmb fggvnynk sszes paramtert tartalmazza ezeket a vltozkat tltjk be az $argumentumok tmbbe. Mivel nvrtk prokat vrunk, hibazenetet kell adnunk, ha pratlan szm elem rkezik a tmbben. Egybknt vgiglpkednk a tmb sszes elemn (a harmadikkal kezdve) s kiratjuk az sszes prt a vltoz adattpusval egytt. A 22.4. bra a 22.4. program kimenett mutatja.

22.4. bra
A debug() fggvny hasznlata

Hibakeress

423

Gyakori hibk
Mindannyian kvetnk el hibkat, klnsen akkor, ha vszesen kzeledik a leadsi hatrid. Vannak olyan csapdk, amelyekbe elbb-utbb minden programoz beleesik. szrevesszk a hibt a kvetkez kdrszletben? $valtozo=0; while ( $valtozo < 42 ); { print "$valtozo<BR>"; $valtozo++; } A kapkods sokszor vezet hibhoz pldul az utastssort jell pontosvesszt gyakran kitesszk olyan helyeken is, ahol nem kellene. gy kerlhetett a fenti while kifejezs mg is pontosvessz, ami azt jelzi az rtelmeznek, hogy a ciklus trzse res a $valtozo rtke soha nem fog nni, ezrt a program vgtelen ciklusba kerl. Lssunk mg egy pldt: $ertek = 1; while ( $ertek != 50 ) { print $ertek; $ertek+=2; } Az elltesztel ismtlses vezrlsi szerkezet ciklustrzsnek vgrehajtsa a zrjelben tallhat kifejezs logikai rtktl fgg. A fenti pldban ez a kifejezs csak akkor lesz hamis, ha az $ertek vltoz rtke 50. Vagyis a ciklustrzs addig ismtldik, amg az $ertek rtke nem 50. Csakhogy ez soha nem fog bekvetkezni, mivel a vltoz rtke 1-rl indul s minden lpsben kettvel nvekszik vagyis csak pratlan rtkeket vesz fel. Ismt sikerlt vgtelen ciklusba ejtennk a PHP-t. A kvetkez kdrszletben rejl hiba elg alattomos: if ( $proba = 4 ) { print "<P>A \$proba rtke 4</P>\n"; }

22

424

22. ra A vgrehajtst vezrl logikai kifejezsben nyilvnvalan ellenrizni akartuk a $proba vltoz rtkt. A kd azonban ehelyett 4-et rendel a $proba-hoz. Mivel a hozzrendels mint kifejezs rtke a jobb oldali operandussal egyenl (jelen esetben 4-gyel), a logikai kifejezs rtke a $proba-tl fggetlenl mindig igaz lesz. Ezt a tpus hibt azrt nehz felfedezni, mert semmilyen zenetet nem hoz ltre, a program egyszeren nem gy fog mkdni, ahogyan azt elvrjuk. A karakterlncok kezelse sorn szintn elkvethetnk tpushibkat. Az albbi elg gyakori: $datum = "A mai dtum: . date('d/m/Y H I); print $datum; Mivel nem zrtuk le az idzjelet, az rtelmeznek fogalma sincs, hol vgzdik a karakterlnc. Ez szinte mindig hibajelzssel jr, de nehzkes visszakeresni, mivel gyakran rossz sorszmot kapunk. A zrjelprok hibs kezelse szintn hasonl jelensghez vezet. A kvetkez hibt viszont elg knny megtallni: print "n a $tartomany-rl "$felhasznalo"-kent jelentkezett be"; Ha idzjelet akarunk kiratni, jeleznnk kell az rtelmeznek, hogy itt nem klnleges karakterknt kell kezelnie. Az elbbi kdrszlet a kvetkezkppen fest helyesen: print "n a $tartomany-rl \"$felhasznalo\"-kent jelentkezett be"; sszefoglalva, ebben a rszben a kvetkez gyakori hibatpusokkal foglalkoztunk: res ciklustrzs ltrehozsa hibsan alkalmazott pontosvesszvel. Vgtelen ciklus ltrehozsa hibs vezrlfelttellel. Hozzrendels hasznlata az egyenl logikai mveletjel helyett. Levdetlen idzjelek hasznlata miatt elcsszott karakterlnc-hatrok.

Hibakeress

425

sszefoglals
A fejleszts taln egyik leghltlanabb rsze a hibakeress. A megfelel mdszerekkel azonban megknnythetjk az letnket. Ebben az rban tanultunk arrl, hogy a phpinfo() fggvny segtsgvel hogyan nyerhetnk informcikat a rendszer belltsairl s a krnyezeti vltozkrl. Az error_log() fggvnnyel hibazeneteket rtunk ki fjlba s kldtnk el elektronikus levlben. Tanultunk a kzi hibakeressrl a fontosabb vltozk rtknek kiratsval s rtunk egy fggvnyt a feladat megknnytsre. Ha ismerjk az adatokat, amelyekkel programunk dolgozik, viszonylag knnyen s gyorsan megtallhatjuk a hibkat. Vgl megnztnk nhny olyan tpushibt, amelyek mg a tapasztaltabb programozk lett is megkesertik.

Krdsek s vlaszok
Ltezik mdszer, amellyel cskkenthetjk a kdba kerl hibkat? Legynk szemflesek! Tulajdonkppen szinte lehetetlen egy olyan nagyobb llegzet programot ltrehozni, amely elsre tkletesen mkdik. Hasznljunk modulris tervezst, hogy gyorsan elklnthessk a hibt tartalmaz kdrszletet. Olyan gyakran ellenrizzk a kdot, amilyen gyakran csak lehetsges. Rossz megkzelts, ha megrjuk a programot, elindtjuk, azutn vrjuk, mi trtnik. Oldjunk meg egy rszfeladatot (lehetleg fggvnyek formjban), majd prbljuk ki az elkszlt kdot. Ha tkletesen mkdik, mehetnk a kvetkez rszfeladatra. Prbljunk bolondbiztos kdot kszteni s ellenrizzk mkdst szlssges krlmnyek kztt. Ha az egyik leglnyegesebb lps pldul az adatok kirsa egy megadott fjlba, nzzk meg, mi trtnik, ha a fjl hinyzik.

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

22

Kvz
1. Melyik fggvnnyel kaphatunk hasznos informcikat a PHP-rl s a rendszernkrl? 2. Melyik fggvnnyel jelenthetjk meg a sznekkel kiemelt forrskdot a bngszablakban?

426

22. ra 3. Melyik php.ini bejegyzssel szablyozhatjuk a hibazenetek kijelzsnek szintjt? 4. Melyik fggvnnyel brlhatjuk fell ezt a belltst? 5. Melyik fggvnnyel naplzhatjuk a hibkat? 6. Melyik beptett vltoz tartalmazza a hibazenetet, ha a track_errors bejegyzs engedlyezett a php.ini fjlban?

Feladatok
1. Vizsgljuk meg eddig elkszlt programjaink kdjt s felptst az ebben az rban tanult mdszerek segtsgvel.

IV. RSZ
sszefoglal plda
23. ra Teljes plda (els rsz) 24. ra Teljes plda (msodik rsz)

23. RA
Teljes plda (els rsz)
Ha figyelmesen kvettk az egyes rk anyagt, j alapokkal rendelkeznk a PHP programozshoz. Ebben s a kvetkez rban egy teljes, mkd programot ksztnk, amely az elz rkban trgyalt eljrsokbl ptkezik. Az rban a kvetkezket tanuljuk meg: Hogyan ksztsnk tervet? Hogyan hasznljuk az include() nyelvi szerkezetet, hogy fggvnyknyvtrakat s jrahasznosthat navigcis elemeket ksztsnk? Hogyan tartsuk nyilvn az llapotokat GET tpus lekrdezsekkel, adatbzisokkal s munkamenet-fggvnyekkel? Hogyan vlasszuk el a HTML s a PHP kdot, hogy a programozsban jratlan grafikus is dolgozhasson az oldalon? Hogyan vdjk meg szolgltatsunk oldalait felhasznl-azonostssal?

430

23. ra

A feladat rvid lersa

Tegyk fel, hogy egy kzssgi webhely tulajdonosai felkrtek bennnket, hogy ksztsnk el egy kis interaktv esemnynaptrt az ltaluk kiszolglt kisvros szmra. Klubok s egyttesek jegyeztethetik be magukat, hogy reklmozzk rendezvnyeiket. A webhely felhasznli ezutn klnbz formkban kirathatjk majd az adatbzist, hogy lssk, milyen rendezvnyek lesznek a vrosban. A felhasznlk kpesek lesznek a lista szktsre a klubok tpusa vagy akr a szervezett rendezvny helye szerint is.

Az oldalak felptse
Mieltt akr egy sor kdot is rnnk, el kell dntennk, hogyan fog mkdni programunk. Milyen mdon fogjk elrni a felhasznlk a rendszer klnbz elemeit? Milyen oldalakra van szksgnk? A program termszetesen kt rszre tagoldik. Az els a tagok szmra kialaktott terlet, amely a klubok informciinak kezelsre, j esemnyek hozzadsra szolgl majd. A msodik a felhasznlk terlete, ahol az adatbzison lekrdezseket kell majd vgrehajtani. A tovbbiakban tagoknak nevezzk azokat a szemlyeket, akik klubjukat bejegyezve felgyeleti feladatokat ltnak el, s felhasznlknak azokat az rdekldket, akik a listkat bngszve barangolnak a klubok s esemnyek kztt.

A 23.1. bra az alkalmazs felptst mutatja.

23.1. bra
Az alkalmazs felptse

Teljes plda (els rsz) Az j tagok a csatlakozas.php oldalon csatlakozhatnak a rendszerhez (itt jegyeztethetik be magukat a tagok kz), egy nvjelsz pr megadsval. Ha a vlasztott nv mg nem foglalt, a leend tag a klubfrissites.php oldalra kerl, ahol egy rlapon meg kell adnia a klubrl a szksges informcikat. Amg ki nem tlti ezt az rlapot, nem vihet be j rendezvnyeket a rendszerbe. Ha a tag a hozz tartoz klub adatait sikeresen bevitte, a tagok menjhez kerl (tagmenu.php), ahonnan a tagok rszre ksztett valamennyi oldal elrhet. A mr bejegyzett tagok a belp oldalrl indulnak (belepes.php). Ha a megadott nv s jelsz helyesnek bizonyult, egyenesen a tagmenu.php oldalra kerlnek. A men oldalrl indulva a tagok j rendezvnyeket adhatnak a rendszerhez (esemenyfrissites.php) s megtekinthetik az adatbzisban lev rendezvnyeik listjt (esemenylista.php). A klub adatait a klubfrissites.php oldalon brmikor mdosthatjk. Minden felhasznl kpes lesz az esemnyek hnapok, napok, tpusok s terletek alapjn trtn rendezett kiratsra, egyetlen PHP oldal segtsgvel (esemenyekinfo.php). Lehetsg lesz a klubok felsoroltatsra is, terlet vagy tpus alapjn (klubokinfo.php). Vgl a felhasznlk egy klubra vagy esemnyre kattintva bvebb informcikat tudhatnak meg (esemenyinfo.php, klubinfo.php).

431

Az adatbzis kialaktsa
Az alkalmazs adatainak trolshoz ltre kell hoznunk a szervezo adatbzist s ebben ngy tblt: klubok, esemenyek, teruletek, tipusok. Nyilvnval, hogy a klubok s rendezvnyek adatait kln tblkban kell trolnunk, hiszen egy klubhoz tbb rendezvny is tartozhat. A terletek s tpusok szmra kialaktott tblk jelentsen megknnytik a listzshoz s adatbevitelhez szksges lenyl menk kialaktst. A tblkat SQL parancsokkal hozzuk ltre, kzi ton. A klubok tbla a kvetkezkppen hozhat ltre: CREATE TABLE klubok ( 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

432

23. ra A tagok a klubnev, email, ismerteto, nev s jelszo mezk adatait fogjk megadni. A tipus s terulet mezk rtelemszeren a tipusok s teruletek megfelel soraira vonatkoz azonostkat tartalmazzk majd. Az esemenyek tbla az esemnyekre vonatkoz valamennyi informcit tartalmazza: CREATE TABLE esemenyek ( eazonosito INT NOT NULL AUTO_INCREMENT PRIMARY KEY, etipus CHAR(3), eterulet CHAR(3), edatum INT, enev VARCHAR(100), ehelyszin VARCHAR(100), ecim VARCHAR(255), eirsz CHAR(4), eismerteto BLOB, eklub INT NOT NULL ); Vegyk szre, hogy ez a tbla is tartalmaz etipus s eterulet mezket, hiszen elfordulhat, hogy egy klub a vros szaki rszn tallhat, de valamelyik rendezvnyt a dli vrosrszben tartja. Egy trsadalmi csoport tarthat oktatsi szeminriumot, de politikai tallkozt is. Az eklub mez annak a klubnak az azonositszmt tartalmazza, amelyik az adott esemny szervezje. A kapcsolat arra hasznlhat fel, hogy egy klub sszes rendezvnyt felsoroljuk, illetve hogy elrjk az esemnyhez kthet klub adatait. A teruletek s tipusok tblk igen egyszerek: CREATE TABLE teruletek ( azonosito CHAR(3), terulet VARCHAR(30)); CREATE TABLE tipusok ( azonosito CHAR(3), tipus VARCHAR(30)); A tagok szmra nem adunk lehetsget ezen tblk mdostsra, inkbb elre meghatrozott csoportokat alaktunk ki, melyeket INSERT SQL parancsokkal adunk a tblkhoz. A tagok ezekbl a listkbl vlaszthatnak majd. INSERT INTO tipusok (azonosito, tipus) VALUES ("CSA", "Csaldi"); A 23.1. s 23.2. tblzatban az emltett tblkba illesztend adatok lthatk.

Teljes plda (els rsz)

433

23.1. tblzat A teruletek tblhoz adott adatok


azonosito ESZ DEL KEL NYU terulet szak Dl Kelet Nyugat

23.2. tblzat A tipusok tblhoz adott adatok


azonosito ZEN CSA TRS KZS tipus Zenei Csaldi Trsadalmi Kzssgi

Tervezsi dntsnk
Az elz bekezdsekben mr lttuk, milyen szerkezet alkalmazst ksztnk. gy dntttnk, hogy a klnbz szolgltatsokhoz klnbz PHP programokat ksztnk, ahelyett, hogy egyetlen hatalmas programot ptennk fel, amely a krlmnyeknek megfelelen ms-ms oldalakat szolgltat. Ennek a dntsnek termszetesen vannak elnyei s htrnyai is. Ha egy ilyen dinamikus krnyezetet tbb oldalbl ptnk fel, a kdok ismtlsnek hibjba eshetnk s a program nvekedsvel megnehezthetjk a fejlesztk dolgt. Msrszt viszont a befejezett prototpust tadhatjuk grafikusainknak, akik majdnem gy kezelhetik azt, mintha pusztn HTML kdot tartalmazna.

A tagoknak sznt oldalak


Most mr itt az ideje, hogy megkezdjk a kd rst. Az ra tovbbi rszben az alkalmazs tagoknak sznt oldalait ksztjk el. J tlet ezekkel kezdeni, mivel gy knnyebben vihetnk be prbaadatokat a rendszerbe. Mieltt azonban az adatbevitelt megkezdhetnnk, kpesnek kell lennnk a tagok felvtelre.

23

434

23. ra

csatlakozas.php s adatbazis.inc
A csatlakozas.php tartalmazza azt az rlapot, amelyen keresztl az j tagok egy nv s jelsz segtsgvel bejegyeztethetik klubjukat a rendszerbe. Ahhoz, hogy felvehessk az adatokat s kiszrhessk az ismtldseket, elszr meg kell nyitnunk egy kapcsolatot az adatbzis fel. Ez az ilyen alkalmazsoknak annyira jellemz eleme, hogy clszer kln fggvnyt kszteni erre a clra, melyet jelen esetben egy kls llomnyban fogunk trolni. Ezt a kls fjlt ksbb minden oldalon az include() nyelvi elemmel illesztjk a kdba. Tulajdonkppen minden adatbzissal kapcsolatos fggvnyt ebben trolunk majd, ezrt az adatbazis.inc nevet kapja, szerepe s a beilleszts mdja utn. Ezzel a fjllal a tovbbi PHP oldalakat mindennem SQL parancstl mentestjk. Az adatbzissal kapcsolatot tart kdok kln fjlba helyezse knnyebb teszi a program ksbbi mdostst vagy ms adatbzismotorra val tltetst. Elfordulhat, hogy ksbb jra kell rnunk a fggvnyeket, de a hv kdok mdostsra nem lesz szksg. Hozzuk ltre a fggvnyt, amely vgrehajtja a csatlakozst:

23.1. program Rszlet az adatbazis.inc fjlbl


1: $kapcsolat; 2: dbCsatlakozas(); 3: function dbCsatlakozas() 4: { 5: global $kapcsolat; 6: $kapcsolat = mysql_connect( "localhost", "felhasznalo", "jelszo" ); 7: if ( ! $kapcsolat ) 8: die( "Nem lehet csatlakozni a MySQL-hez" ); 9: mysql_select_db( "szervezo", $kapcsolat ) 10: or die ( "Nem lehet megnyitni az adatbzist: ".mysql_error() ); 11: } A dbCsatlakozas() fggvny a $kapcsolat globlis vltozt hasznlja arra, hogy a mysql_connect() ltal visszaadott kapcsolatazonostt trolja. Mivel a vltoz globlis, a tbbi adatbzisfggvny is elrheti. Nem csupn a MySQL kiszolglhoz csatlakozunk ebben a fggvnyben, hanem megprbljuk kivlasztani a szervezo adatbzist is. Mivel ezen mveletek sikere dnt fontossg a teljes alkalmazs mkdse szempontjbl, a mysql_connect() vagy mysql_select_db() vgrehajtsnak kudarca esetn befejezzk a program futst.

Teljes plda (els rsz) A munkamenetek kvetse s az azonostssal kapcsolatos feladatokat ellt fggvnyek szmra egy jabb kls llomnyt hasznlunk. A munkamenet-fggvnyeket arra hasznljuk, hogy egy $munkamenet nev asszociatv tmbt rizznk meg krsrl krsre. A kozosfv.inc llomny session_start() fggvnye arra szolgl, hogy megkezdjnk vagy folytassunk egy munkamenetet, a vltoznkat pedig a session_register() fggvnnyel rendeljk ehhez:

435

23.2. program Rszlet a kozosfv.inc fjlbl


1: session_start(); 2: session_register( "munkamenet" );

Emlkezznk r, hogy minden PHP kd, amit ezen kls fjlokba runk, PHP blokk kezd (<?php) s zr (?>) elemek kztt kell, hogy legyen. rtelmetlen bonyoltsnak tnhet, hogy a klnbz szolgltatsokat kls llomnyokba helyezzk, de ez rengeteg kdismtlstl kml majd meg bennnket, amikor oldalainkat elksztjk. Most mr kszen llunk a csatlakozas.php oldal megrsra.

23.3. program csatlakozas.php


1: <?php 2: include("adatbazis.inc"); 3: include("kozosfv.inc"); 4: 5: $uzenet=""; 6: 7: if ( isset( $mitkelltenni ) && $mitkelltenni=="csatlakozas") 8: { 9: if ( empty( $urlap["nev"] ) || 10: empty( $urlap["jelszo"] ) || 11: empty( $urlap["jelszo2"] ) ) 12: $uzenet .= "Ki kell tltenie minden mezt!<br>\n"; 13: 14: if ( $urlap["jelszo"] != $urlap["jelszo2"] ) 15: $uzenet .= "A jelszavak nem egyeznek!<br>\n"; 16:

23

436

23. ra

23.3. program (folytats)


17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: if ( strlen( $urlap["jelszo"] ) > 8 ) $uzenet .= "A jelsz hossza legfeljebb 8 karakter lehet!<br>\n"; if ( strlen( $urlap["nev"] ) > 8 ) $uzenet .= "A tagsgi nv hossza legfeljebb 8 karakter lehet!<br>\n"; if ( sorLekeres( "klubok", "nev", $urlap["nev"] ) ) $uzenet .= "A megadott tagsgi nven.\"" $urlap["nev"] ."\" mr van bejegyzett tagunk. Krjk, adjon meg ms nevet!<br>\n"; if ( $uzenet == "" ) // nem talltunk hibt { $azon = ujTag( $urlap["nev"], $urlap["jelszo"] ); munkamenetFeltoltes( $azon, $urlap["nev"], $urlap["jelszo"] ); header( "Location: klubfrissites.php?".SID ); exit; }

?>

<html> <head> <title>Csatlakozs</title> </head> <body> <?php include("kozosnav.inc"); ?> <p> <h1>Csatlakozs</h1>

Teljes plda (els rsz)

437

23.3. program (folytats)


52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: <?php if ( $uzenet != "" ) { print "<b>$uzenet</b><p>"; } ?> <p> <form action="<?php print $PHP_SELF;?>"> <input type="hidden" name="mitkelltenni" value="csatlakozas"> <input type="hidden" name="<?php print session_name() ?>" value="<?php print session_id() ?>"> Tagsgi nv: <br> <input type="text" name="urlap[nev]" value="<?php print $urlap["nev"] ?>" maxlength=8> </p> <p> Jelsz: <br> <input type="password" name="urlap[jelszo]" value="" maxlength=8> </p> <p> Jelsz megersts: <br> <input type="password" name="urlap[jelszo2]" value="" maxlength=8> </p> <p> <input type="submit" value="Rendben"> </p> </form> </body> </html>

23

Elszr az include() hasznlatval beillesztjk a kls llomnyokat, teht azonnal rendelkezsnkre ll egy adatbziskapcsolat s egy aktv munkamenet. Ltrehozunk egy $uzenet nev vltozt. Ezzel a ketts cl vltozval mg

438

23. ra szmos ms oldalon tallkozni fogunk. Az $uzenet clja egyrszt, hogy tartalmazza a hibazenetet, amit ksbb kirhatunk a bngsz szmra, msrszt hasznlhatjuk feltteles kifejezsekben, hogy ellenrizzk, volt-e hibazenet vagy sem. Ha a vltoz res marad, felttelezhetjk, hogy minden ellenrzs sikeresen vgrehajtdott. Ezutn a $mitkelltenni vltoz ltezst s tartalmt vizsgljuk. Ez is olyan elem, amely tbbszr felbukkan majd az alkalmazsban. Minden ltalunk ksztett rlapon belltunk egy mitkelltenni nev rejtett elemet s egy, az adott szolgltatsra vonatkoz rtket adunk neki. Ha PHP programunkban a $mitkelltenni vltoz ltezik s a vrt rtk tallhat benne, biztosak lehetnk abban, hogy az rlapot kitlttte valaki, gy folytathatjuk a programot az rlap adatainak ellenrzsvel. Ha a vltoz nem ltezik, tudhatjuk, hogy a ltogat egy hivatkozson keresztl vagy a bngszjben lv knyvjelz rvn rkezett az oldalra s nem tlttte ki az rlapot. Egyelre ugorjunk a HTML rsz trgyalsra. A body HTML elemen bell elszr egy jabb kls fjlt illesztnk be, amely a klnbz oldalakra mutat hivatkozsokat tartalmazza. Clszer mr a kezdetektl beilleszteni a navigcis svot, mivel ez megknnyti az alkalmazs ellenrzst, ahogy folyamatosan fejlesztjk azt. A navigcis elemeket a kozosnav.inc nev llomnyban helyezzk el. Egyelre ez a fjl csak a ltogatk szmra is elrhet oldalakra mutat hivatkozsokat tartalmazza.

23.4. program Rszlet a kozosnav.inc fjlbl


1: <p> 2: <a href="klubokinfo.php?<?php print SID ?>">Klubinformcik</a> | 3: <a href="esemenyekinfo.php?<?php print SID ?>">Esemnyinformcik</a> | 4: <a href="csatlakozas.php?<?php print SID ?>">Csatlakozs</a> | 5: <a href="belepes.php?<?php print SID ?>">Belps</a> | 6: <a href="index.php?<?php print SID ?>">Honlap</a> 7: </p>

Azzal, hogy a navigcis elemeket kln llomnyba helyezzk, egyetlen mozdulattal mdosthatjuk a hivatkozsokat, illetve az elemek kinzett a teljes alkalmazsra vonatkozan.

Teljes plda (els rsz) Visszatrve a csatlakozas.php oldalra, miutn kirjuk az oldal cmsort, ellenrizzk az $uzenet vltozt. Ha nem res, kirjuk a tartalmt a bngsz szmra. Az sszegyjttt hibazenetek kirsval jelezhetjk a tagnak, hogy a bevitt adatok nem dolgozhatk fel. A HTML rlap elemei kztt hrom lthat mezt hoztunk ltre, az urlap[nev], urlap[jelszo] s urlap[jelszo2] mezket. Azrt hasznljuk ezeket az elsre esetleg furcsnak ltsz elnevezseket, mert a PHP az gy megadott nevekkel rkez rtkeket egy asszociatv tmbbe rendezi, amit $urlap nven rhetnk majd el. Ez megv bennnket attl, hogy a globlis vltozk krnyezett beszennyezzk, azaz feleslegesen sok globlis vltozt hozzunk ltre. Programjainkban gy minden munkamenet-rtk a $munkamenet asszociatv tmbben, az rlaprtkek pedig az $urlap asszociatv tmbben rhetk el. Ez megvd bennnket a vltozk tkzstl. Clszer a lehet legkevesebbre cskkenteni a globlis vltozk szmt egy ilyen mret programban, hogy megelzzk a kavarodst. A tovbbiakban minden rlapot tartalmaz oldalon az $urlap tmbbel fogunk tallkozni. Az rlapban ltrehozzuk a mr korbban emltett mitkelltenni rejtett elemet is, valamint egy msikat, amely a munkamenet nevt s rtkt tartalmazza majd. Az alkalmazs elksztse sorn mindig oldalrl-oldalra fogjuk adni a munkamenetazonostt, mivel nem kvnjuk elveszteni azokat a ltogatkat, akik nem tudnak vagy nem akarnak stiket fogadni. Ha munkameneteket hasznl programokat ellenrznk, clszer kikapcsolni a bngszben a stik elfogadst. gy pontosan tudni fogjuk, hogy a munkamenet azonostjt sikeresen t tudjuk-e adni oldalrl oldalra ezen szolgltats nlkl is vagy sem.

439

Most, hogy megnztk a HTML rlapot, rtrhetnk arra a kdra, amely a bemen adatok ellenrzst vgzi. Elszr meg kell bizonyosodnunk rla, hogy a leend tag valban kitlttte-e az sszes mezt s hogy egyik mez hossza sem haladja meg a nyolc karaktert. Ezutn meghvjuk az j sorLekeres() fggvnyt. Ez azon fggvnyek egyike, amelyek az adatbazis.inc fjlban tallhatk. Els paramtere egy tblanv, a msodik egy meznv, a harmadik egy rtk. Ezen adatok alapjn a fggvny egy illeszked sort keres az adatbzisban, visszaadva azt egy tmbben.

23

440

23. ra

23.5. program Rszlet az adatbazis.inc fjlbl


1: function sorLekeres( $tabla, $mezonev, $mezoertek ) 2: { 3: global $kapcsolat; 4: $eredmeny = mysql_query( "SELECT * FROM $tabla WHERE $mezonev='$mezoertek'", $kapcsolat ); 5: if ( ! $eredmeny ) 6: die ( "sorLekeres hiba: ".mysql_error() ); 7: return mysql_fetch_array( $eredmeny ); 8: }

A fggvnynek a klubok tblanevet, a nev meznevet s a ltogatk ltal bevitt $urlap["nev"] mezrtket adjuk t. Ha a mysql_fetch_array() nem res tmbt ad vissza, tudhatjuk, hogy egy ilyen belpsi nvvel rendelkez tag mr van a rendszerben, ezrt hibazenetet kell adnunk. Ha az ellenrzsek utn az $uzenet vltoz mg mindig res, ltrehozhatjuk az j tagot a bevitt adatokkal. Ez kt lpsbl tevdik ssze. Elszr is frissteni kell az adatbzist. Ehhez egy j fggvny tartozik az adatbazis.inc llomnybl, ujTag() nven:

23.6. program Rszlet az adatbazis.inc fjlbl


1: function ujTag( $nev, $jelszo ) 2: { 3: global $kapcsolat; 4: $eredmeny = mysql_query( "INSERT INTO klubok (nev, jelszo) 5: VALUES('$nev', '$jelszo')", $kapcsolat); 6: return mysql_insert_id( $kapcsolat ); 7: }

A fggvny egy nv s egy jelsz paramtert vr, majd ezeket j sorknt felveszi a klubok tbljba. A fggvny a mysql_insert_id()-t hasznlja, hogy megkapja a felvett j tag azonostjt.

Teljes plda (els rsz) Mivel mr rendelkeznk az j tag azonostjval, meghvhatjuk a felvtelhez szksges jabb fggvnyt, ami a kozosfv.inc fjlban tallhat. A munkamenetFeltoltes() fggvny egy azonostt, egy belpsi nevet s egy jelszt vr paramterl s hozzadja azokat a $munkamenet tmbhz. gy ezek az rtkek mr elrhetek lesznek minden munkamenetet kezel oldalunk szmra. Ezzel kpesek lesznk a tag azonostsra a tovbbi oldalakon is.

441

23.7. program Rszlet a kozosfv.inc fjlbl


1: function munkamenetFeltoltes( $azonosito, $nev, $jelszo ) 2: { 3: global $munkamenet; 4: $munkamenet["azonosito"] = $azonosito; 5: $munkamenet["nev"] = $nev; 6: $munkamenet["jelszo"] = $jelszo; 7: $munkamenet["belepett"] = true; 8: }

Az azonost, nv s jelsz megadsa mellett a belpsi llapotot jelz rtket (belepett) is belltjuk a munkameneteket kezel oldalaink szmra. Vgl, miutn a csatlakozas.php oldal frisstette az adatbzist s a munkamenethez rendelt rtkeket, tjra engedhetjk j tagunkat. Meghvjuk a header() fggvnyt, tirnytva a bngszt a klubfrissites.php oldalra, ahol a tagnak be kell majd lltania az jonnan bejegyzett klub rszletes adatait. A csatlakozas.php kimenett a 23.2. brn lthatjuk.

23.2. bra
A csatlakozas.php kimenete

23

442

23. ra

klubfrissites.php
Ez az oldal ketts clt szolgl. Egyrszt az j tagoknak itt kell megadniuk a klub rszletes adatait, a bejegyzett tagok pedig itt mdosthatjk ezeket.

23.8. program klubfrissites.php


1: <?php 2: include("adatbazis.inc"); 3: include("kozosfv.inc"); 4: 5: $klub_sor = azonositas(); 6: 7: $uzenet = ""; 8: 9: if ( isset( $mitkelltenni ) && $mitkelltenni=="frissites" ) 10: { 11: if ( empty( $urlap["klubnev"] ) ) 12: $uzenet .="A klubnv mez nincs kitltve!<br>\n"; 13: 14: if ( ! sorLekeres( teruletek, azonosito, $urlap["terulet"] ) ) 15: $uzenet .= "KRITIKUS HIBA: A terlet kdja nem tallhat!<br>"; 16: 17: if ( ! sorLekeres( "tipusok", "azonosito", $urlap["tipus"] ) ) 18: $uzenet .= "KRITIKUS HIBA: A tpus kdja nem tallhat!<br>"; 19: 20: if ( $uzenet == "" ) 21: { 22: klubFrissites( $munkamenet["azonosito"], $urlap["klubnev"], $urlap["terulet"], 23: $urlap["tipus"], $urlap["email"], $urlap["ismerteto"] ); 24: header("Location: tagmenu.php?".SID); 25: exit; 26: } 27: }

Teljes plda (els rsz)

443

23.8. program (folytats)


28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: else { $urlap = $klub_sor; }

?>

<html> <head> <title>Klubinformcik frisstse</title> </head> <body> <?php include("kozosnav.inc"); ?> <h1>Klubinformcik frisstse</h1> <?php if ( $uzenet != "" ) { print "<b>$uzenet</b><p>"; } ?> <form action="<?php print $PHP_SELF;?>"> <input type="hidden" name="mitkelltenni" value="frissites"> <input type="hidden" name="<?php print session_name() ?>" value="<?php print session_id() ?>"> <p> Klub neve: <br> <input type="text" name="urlap[klubnev]" value="<?php print stripslashes($urlap["klubnev"]) ?>"> </p> <p> Klub helye: <br> <select name="urlap[terulet]"> <?php optionLista( "teruletek", $urlap["terulet"] ) ?>

23

444

23. ra

23.8. program (folytats)


65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: </select> </p> <p> Klub tpusa: <br> <select name="urlap[tipus]"> <?php optionLista( "tipusok", $urlap["tipus"])?> </select> </p> <p> Kapcsolattart e-mail cme: <br> <input type="text" name="urlap[email]" value="<?php print stripslashes($urlap["email"]) ?>"> </p> <p> Klub ismertetje: <br> <textarea name="urlap[ismerteto]" rows=5 cols=30 wrap="virtual"> <?php print stripslashes($urlap["ismerteto"]) ?> </textarea> </p> <p> <input type="submit" value="Rendben"> </p> </form> </body> </html>

Beillesztjk az adatbazis.inc s kozosfv.inc nev kls llomnyainkat, gy rgtn ksz adatbziskapcsolattal s munkamenettel kezdjk az oldalt. Ezutn meghvjuk az j azonositas() nev fggvnyt, ami a kozosfv.inc fjlban tallhat. Ez sszehasonltja a munkamenet adatait az adatbzissal.

23.9. program Rszlet a kozosfv.inc fjlbl


1: function azonositas( ) 2: { 3: global $munkamenet, $belepett; 4: $munkamenet["belepett"] = false;

Teljes plda (els rsz)

445

23.9. program (folytats)


5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: $klub_sor = sorLekeres( "klubok", "azonosito", $munkamenet["azonosito"] ); if ( ! $klub_sor || $klub_sor["nev"] != $munkamenet["nev"] || $klub_sor["jelszo"] != $munkamenet["jelszo"] ) { header( "Location: belepes.php" ); exit; } $munkamenet["belepett"] = true; return $klub_sor; }

Az azonositas() jl tlthat fggvny. A $munkamenet["azonosito"] elemt hasznljuk arra, hogy a sorLekeres() fggvny segtsgvel lekrjk a klubhoz tartoz sort az adatbzisbl. Ezt a $klub_sor asszociatv tmbben troljuk s ellenrizzk a nev s jelszo elemek egyezst a $munkamenet megfelel tmbelemeivel. Ha nem egyeznek, a belepes.php oldalra kldjk a tagot. Mirt vllaljuk fel az adatbzis lekrdezsnek kltsgt az azonostshoz? Mirt nem egyszerstjk a problmt a belepett elem ellenrzsre? Ez visszalseknek engedne teret, mivel egy rosszindulat ltogat egyszeren hozzadhatna az oldal cmhez egy ilyen rszt: munkamenet%5Bbelepett%5D=1&munkamenet%5Bazonosito%5D=1 gy tvve az 1-es azonostval rendelkez tag fltt az irnytst, a PHP ugyanis ezt a $munkamenet tmbb alaktja, amely egy felletesebb ellenrzsen tljuthatna. A rosszindulat ltogat most is alkalmazhat egy hasonl trkkt, hogy belpst nyerjen, de mivel az adatbzisban lv nvvel s jelszval trtn egyezst vizsgljuk, a hamistott $munkamenet vltoznak helyes tartalommal kell rendelkeznie, gy pedig felesleges a csals. Az azonositas() fggvny mellktermke a visszaadott tmb, amely a krdses klubrl az adatbzisban tallhat sszes adatot tartalmazza. Ksbb az oldalak ezt az informcit sajt cljaikra hasznlhatjk fel. Miutn az azonositas() fggvny visszatr a klub adatait tartalmaz tmbbel, ezt a $klub_sor vltoznak adjuk rtkl. Ismtelten ugorjunk a HTML rszre. Itt elszr a kozosnav.inc llomnyt illesztjk be. Ebben a fjlban azonban tovbblpnk az eddigieknl s szerepeltetjk a tagok menjt is:

23

446

23. ra

23.10. program kozosnav.inc


1: <p> 2: <a href="klubokinfo.php?<?php print SID ?>"> Klubinformcik</a> | 3: <a href="esemenyekinfo.php?<?php print SID ?>"> Esemnyinformcik</a> | 4: <a href="csatlakozas.php?<?php print SID ?>"> Csatlakozs</a> | 5: <a href="belepes.php?<?php print SID ?>">Belps</a> | 6: <a href="index.php?<?php print SID ?>">Honlap</a> 7: </p> 8: <?php 9: if ( $munkamenet["belepett"] ) 10: { 11: ?> 12: <p> 13: <A HREF="klubfrissites.php?<?php print SID ?>> Klub rszletei</A> | 14: <A HREF="esemenylista.php?<?php print SID ?>"> Bejegyzett esemnyek</A> | 15: <A HREF="esemenyfrissites.php?<?php print SID ?>"> j esemny</A> | 16: <A HREF="tagmenu.php?<?php print SID ?>"> Tagok honlapja</A> 17: </p> 18: <? 19: } 20: ?> 21: <hr>

Ha a $munkamenet["belepett"] igazra van lltva, a csak tagok szmra megjelentend hivatkozsokat is kirjuk. Vegyk szre, hogy minden hivatkozsban megadjuk a SID llandt. Ez tartalmazza a munkamenet nevt s azonostjt, gy biztostjuk, hogy az azonost oldalrl-oldalra taddjon, mg akkor is, ha a stik nincsenek bekapcsolva. A klubfrissites.php oldal rlapja igazn figyelemremlt. Az eddigieknek megfelelen a mitkelltenni s a munkamenetet azonost rejtett mezket is felvesszk az rlapba. Szvegmezket biztostunk a klub neve, ismertetje s a kapcsolattart elektronikus levlcme szmra. A klubtpusok s terletek lenyl meninek ellltsra egy j fggvny, az optionLista() szolgl.

Teljes plda (els rsz)

447

23.11. program Rszlet az adatbazis.inc fjlbl


1: function optionLista( $tabla, $azon ) 2: { 3: global $kapcsolat; 4: $eredmeny = mysql_query( "SELECT * FROM $tabla", $kapcsolat ); 5: if ( ! $eredmeny ) 6: { 7: print "Nem lehet megnyitni: $tabla<p>"; 8: return false; 9: } 10: while ( $egy_sor = mysql_fetch_row( $eredmeny ) ){ 11: print "<option value=\"$egy_sor[0]\""; 12: if ( $azon == $egy_sor[0] ) 13: print "SELECTED"; 14: print ">$egy_sor[1]\n"; 15: } 16: }

A fggvny a $tabla paramtert hasznlja, hogy kivlasszon minden sort a teruletek vagy tipusok tblbl. Ezutn vgiglpked minden soron az eredmnytblban, kirva egy HTML option elemet a bngsz szmra. Ha a mysql_fetch_array() ltal visszaadott tmb els eleme egyezik az $azon paramterben megadott azonostval, a SELECTED karakterlncot is kirja. Ezzel biztostjuk, hogy a megfelel elem kerl alapbelltsban kivlasztsra az rlapon. A PHP kdban, ahol ellenrizzk a bevitt adatokat, els felttelnk az urlap["klubnev"] kitltttsgnek tnyt vizsglja. Ezutn az urlap["terulet"] s urlap["tipus"] rtkek helyessgt ellenrizzk. Ha az $uzenet vltoz ezeket kveten res marad, tudjuk, hogy az adatok a meghatrozott feltteleknek eleget tesznek, ezrt tadjuk azokat egy j fggvnynek, a klubFrissites()-nek, amely vgrehajtja a szksges mdostst az adatbzisban. A fggvny egy klubazonostt, egy klubnevet, egy terletet, egy tpust, egy e-mail cmet s egy ismertett vr a klubok tbla szmra.

23

448

23. ra

23.12. program Rszlet az adatbazis.inc fjlbl


1: function klubFrissites( $azonosito, $klubnev, $terulet, $tipus, $email, $ismerteto ) 2: { 3: global $kapcsolat; 4: $lekeres = "UPDATE klubok set klubnev='$klubnev', terulet='$terulet', tipus='$tipus', 5: email='$email', ismerteto='$ismerteto' WHERE azonosito='$azonosito'"; 6: $eredmeny = mysql_query( $lekeres, $kapcsolat ); 7: if ( ! $eredmeny ) 8: die ( "klubFrissites hiba: ".mysql_error() ); 9: }

Miutn a sort frisstettk, a tagot a tagmenu.php oldalra kldhetjk. Ha a tag az oldalt egy hivatkozsra kattintva vagy a bngszjben lv knyvjelzvel rte el, a $mitkelltenni vltoz nem kerl belltsra s az ellenrzst s frisstst vgz kd nem hajtdik vgre. Mg mindig van azonban egy feladatunk. A $klub_sor asszociatv tmb tartalmazza a klub adatait, amit az azonositas() fggvnnyel tltttnk fel. Ebben tallhatk az adott klubhoz tartoz meznevek s rtkek az adatbzisbl. Ezt a tmbt adjuk rtkl az $urlap tmbnek, gy biztostva, hogy az rlap alapbelltsban az adatbzisban tallhat rvnyes informcikat tartalmazza. A 23.3. bra a klubfrissites.php kimenett mutatja.

23.3. bra
A klubfrissites.php kimenete

Teljes plda (els rsz)

449

tagmenu.php
A tagmenu.php a tagok terletnek kzpontja. Alapveten hivatkozsok listjbl ll, de a tagok szmra fontos hrek s ajnlatok is helyet foglalhatnak az oldalon.

23.13. program tagmenu.php


1: <?php 2: include("adatbazis.inc"); 3: include("kozosfv.inc"); 4: 5: $klub_sor = azonositas(); 6: klubAdatEllenorzes( $klub_sor ); 7: ?> 8: 9: <html> 10: <head> 11: <title>dvzlet!</title> 12: </head> 13: 14: <body> 15: <?php 16: include("kozosnav.inc"); 17: ?> 18: 19: <h1>Tagok honlapja</h1> 20: 21: <a href="klubfrissites.php?<?php print SID ?>"> Klub rszletei</a><br> 22: <a href="esemenylista.php?<?php print SID ?>"> Bejegyzett esemnyek</a><br> 23: <a href="esemenyfrissites.php?<?php print SID ?>"> j esemny</a><br> 24: 25: </body> 26: </html> Az oldalon egyetlen jdonsg tallhat. Miutn meghvjuk az azonositas() fggvnyt, hogy meggyzdjnk rla, hogy a ltogatnk tag, az ltala visszaadott tmbt egy j fggvnynek adjuk t. Ez a fggvny, a klubAdatEllenorzes(), a kozosfv.inc llomnyban tallhat s azt ellenrzi, hogy a tag megadta-e mr a klub adatait. Amg egy tag ki nem tlti legalbb a klub nevt, nem adhat rendezvnyeket a rendszerhez.

23

450

23. ra

23.14. program Rszlet a kozosfv.inc fjlbl


1: function klubAdatEllenorzes( $klubtomb ) 2: { 3: if ( ! isset( $klubtomb["klubnev"] ) ) 4: { 5: header( "Location: klubfrissites.php?".SID ); 6: exit; 7: } 8: }

belepes.php
Mieltt tovbblpnk a rendezvnyeket kezel oldalakra, el kell ksztennk a belepes.php programot. Ez az oldal ad lehetsget a bejegyzett tagoknak, hogy a ksbbiekben belpjenek a rendszerbe.

23.15. program belepes.php


1: <?php 2: include("adatbazis.inc"); 3: include("kozosfv.inc"); 4: 5: $uzenet=""; 6: 7: if ( isset( $mitkelltenni ) && $mitkelltenni == "belepes" ) 8: { 9: if ( empty( $urlap["nev"] ) || empty( $urlap["jelszo"] ) ) 10: $uzenet .= "Ki kell tltenie minden mezt!<br>\n"; 11: 12: if ( ! ( $sor_tomb = 13: jelszoEllenorzes( $urlap["nev"], $urlap["jelszo"] ) ) ) 14: $uzenet .= "Hibs nv vagy jelsz, prblkozzon jra!<br>\n"; 15:

Teljes plda (els rsz)

451

23.15. program (folytats)


16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: if ( $uzenet == "" ) // nem talltunk hibt { munkamenetFeltoltes( $sor_tomb["azonosito"], $sor_tomb["nev"], $sor_tomb["jelszo"] ); header( "Location: tagmenu.php?".SID ); } }

?>

<html> <head> <title>Belps</title> </head> <body> <?php include("kozosnav.inc"); ?> <h1>Belps</h1> <?php if ( $uzenet != "" ) { print "<p><b>$uzenet</b></P>"; } ?> <p> <form action="<?php print $PHP_SELF;?>"> <input type="hidden" name="mitkelltenni" value="belepes"> <input type="hidden" name="<?php print session_name() ?>" value="<?php print session_id() ?>"> </p><p> Tagsgi nv: <br> <input type="text" name="urlap[nev]" value="<?php print $urlap["nev"] ?>">

23

452

23. ra

23.15. program (folytats)


54: 55: 56: 57: 58: 59: 60: 61: 62: </p><p> Jelsz: <br> <input type="password" name="urlap[jelszo]" value=""> </p><p> <input type="submit" value="Rendben"> </form> </body> </html>

Az oldal szerkezete mr ismers kell, hogy legyen. Az adatbazis.inc s kozosfv.inc llomnyokat hasznljuk, hogy adatbziskapcsolatot ltestsnk s aktv munkamenettel rendelkezznk. Ha a $mitkelltenni vltoz be van lltva s a vrt "belepes" rtket tartalmazza, ellenrizzk az rlaprl rkezett adatokat. Az j adatbazis.inc fggvnyt hasznljuk arra, hogy az urlap["nev"] s urlap["jelszo"] rtkeket vizsgljuk.

23.16. program Rszlet az adatbazis.inc fjlbl


1: function jelszoEllenorzes( $nev, $jelszo ) 2: { 3: global $kapcsolat; 4: $eredmeny = mysql_query( "SELECT azonosito, nev, jelszo FROM klubok 5: WHERE nev='$nev' and jelszo='$jelszo'", 6: $kapcsolat ); 7: if ( ! $eredmeny ) 8: die ( "jelszoEllenorzes hiba: " .mysql_error() ); 9: if ( mysql_num_rows( $eredmeny ) ) 10: return mysql_fetch_array( $eredmeny ); 11: return false; 12: }

Teljes plda (els rsz) A jelszoEllenorzes() egy belpsi nevet s egy jelszt vr. Ezek felhasznlsval egy egyszer SELECT lekrdezst kld az adatbzisnak a klubok tbljra vonatkozan. Visszatrve a belepes.php oldalra, ha nem tallunk hibt, meghvjuk a munkamenetFeltoltes() fggvnyt, amely belltja az azonosito, nev, jelszo s belepett elemeket a $munkamenet tmbben. Ezutn a tagot tirnytjuk a tagmenu.php oldalra.

453

esemenyfrissites.php
Most, hogy a tagok mr kpesek csatlakozni s belpni a rendszerbe, valamint mdostani is tudjk az adataikat, lehetsget kell adnunk a rendezvnyek bevitelre s mdostsra. A teljes esemenyfrissites.php oldal a 23.17. programban lthat.

23.17. program esemenyfrissites.php


1: <?php 2: include("adatbazis.inc"); 3: include("kozosfv.inc"); 4: include("datum.inc"); 5: 6: $klub_sor = azonositas(); 7: klubAdatEllenorzes( $klub_sor ); 8: 9: $edatum = time(); 10: $uzenet = ""; 11: 12: if ( ! empty( $eazonosito ) ) 13: $esemeny_sor = sorLekeres( "esemenyek", "eazonosito", $eazonosito ); 14: else 15: $eazonosito = false; 16: 17: if ( isset( $mitkelltenni ) && $mitkelltenni=="esemenyFrissites" ) 18: { 19: if ( empty( $urlap["enev"] ) ) 20: $uzenet .="Az esemnynek nvvel kell rendelkeznie!<br>\n"; 21:

23

454

23. ra

23.17. program (folytats)


22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: if ( ! sorLekeres( "teruletek", "azonosito", $urlap["eterulet"] ) ) $uzenet .= "KRITIKUS HIBA: A terlet kdja nem tallhat!<br>"; if ( ! sorLekeres( "tipusok", "azonosito", $urlap["etipus"] ) ) $uzenet .= "KRITIKUS HIBA: A tpus kdja nem tallhat!<br>"; foreach ( array( "ehonap", "eev", "enap", "eperc" ) as $datum_egyseg ) { if ( ! isset( $urlap[$datum_egyseg] ) ) { $uzenet .= "KRITIKUS HIBA: A dtum nem rtelmezhet!"; break; } } $edatum = mktime( $urlap["eora"], $urlap["eperc"], 0, $urlap["ehonap"], $urlap["enap"], $urlap["eev"] ); if ( $edatum < time() ) $uzenet .= "Mltbeli dtum nem fogadhat el!"; if ( $uzenet == "" ) { esemenyModositas( $urlap["enev"], $urlap["ehelyszin"], $urlap["eterulet"], $urlap["etipus"], $urlap["ecim"], $urlap["eirsz"], $urlap["eismerteto"], $munkamenet["azonosito"], $edatum, $eazonosito ); header( "Location: esemenylista.php?".SID ); }

Teljes plda (els rsz)

455

23.17. program (folytats)


51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: } elseif ( $eazonosito ) { //foreach( $esemeny_sor as $kulcs=>$ertek ) // $urlap[$kulcs] = $ertek; $urlap = $esemeny_sor; $edatum = $esemeny_sor["edatum"]; } else { $urlap["eterulet"] = $klub_sor["terulet"]; $urlap["etipus"] = $klub_sor["tipus"]; } ?> <html> <head> <title>Esemny hozzadsa/frisstse</title> </head> <body> <?php include("kozosnav.inc"); ?> <h1>Esemny hozzadsa/frisstse</h1> <?php if ( $uzenet != "" ) { print "<b>$uzenet</b>"; } ?> <p> <form action="<?php print $PHP_SELF;?>"> <input type="hidden" name="mitkelltenni" value="esemenyFrissites"> <input type="hidden" name="<?php print session_name() ?>" value="<?php print session_id() ?>">

23

456

23. ra

23.17. program (folytats)


89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: <input type="hidden" name="eazonosito" value="<?php print $eazonosito ?>"> Esemny neve: <br> <input type="text" name="urlap[enev]" value="<?php print stripslashes($urlap["enev"]) ?>"> </p> <p> Dtum s id: <br> <select name="urlap[ehonap]"> <?php honapLehetosegek( $edatum ) ?> </select> <select name="urlap[enap]"> <?php napLehetosegek( $edatum ) ?> </select> <select name="urlap[eev]"> <?php evLehetosegek( $edatum ) ?> </select> <select name="urlap[eora]"> <? oraLehetosegek( $edatum ) ?> </select> <select name="urlap[eperc]"> <? percLehetosegek( $edatum ) ?> </select> </p> <p> Esemny helye: <br> <select name="urlap[eterulet]"> <?php optionLista( "teruletek", $urlap["eterulet"] ) ?> </select> </p> <p> Esemny tpusa: <br> <select name="urlap[etipus]"> <?php optionLista( "tipusok", $urlap["etipus"])?> </select>

Teljes plda (els rsz)

457

23.17. program (folytats)


128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: </p> <p> Esemny ismertetje: <br> <textarea name="urlap[eismerteto]" wrap="virtual" rows=5 cols=30> <?php print stripslashes($urlap["eismerteto"]) ?> </textarea> </p> <p> Helyszn: <br> <input type="text" name="urlap[ehelyszin]" value="<?php print stripslashes($urlap["ehelyszin"])?>"> </p> <p> Helyszn cme: <br> <textarea name="urlap[ecim]" wrap="virtual" rows=5 cols=30> <?php print stripslashes($urlap["ecim"]) ?> </textarea> </p> <p> Helyszn irnytszma: <br> <input type="text" name="urlap[eirsz]" value="<?php print stripslashes($urlap["eirsz"]) ?>"> </p> <p> <input type="submit" value="Rendben"> </p> </form> </body> </html>

23

Ezen az oldalon az esemenyek tblnak megfelel elemekkel ksztnk egy rlapot. Szoks szerint ellenriznnk kell a berkez rtkeket s frisstennk kell az adatbzist. Ha azonban az oldal meghvsa alapjn gy tljk, hogy nem esemny hozzadsa a cl, hanem mdosts, akkor le kell krdeznnk az adatbzisbl a mdostand adatokat. Az oldal meghvsa sorn az $eazonosito vltozt kapja,

458

23. ra ha egy meglv esemny mdostst kell elvgezni. Ha a vltoz nem res, a sorLekeres() fggvnyt alkalmazva kapjuk meg az $esemeny_sor tmbben a rendezvny adatait. Ha az $eazonosito nincs megadva vagy res, akkor hamis rtkre lltjuk. Ha az oldal rlapkitlts hatsra hvdott meg, ellenriznnk kell a berkezett adatokat. A dtummal kapcsolatban meg kell vizsglnunk, hogy az nem egy mltbeli rtk-e. Ennek rdekben belltunk egy $edatum nev globlis vltozt a beadott adatok fggvnyben. Ha az adatok megfelelnek az ltalunk tmasztott kvetelmnyeknek, az adatbazis.inc egy j fggvnyt hvjuk meg, melynek neve esemenyModositas(). Ez a fggvny minden olyan rtket vr, amit az esemenyek tblban el kell helyeznnk. Az utols paramter a rendezvny azonostszma. Ezt az esemenyModositas() fggvny arra hasznlja, hogy megllaptsa, j esemnyt kell felvennie vagy mdostania kell egy mr ltezt. Figyeljk meg, hogy a klub azonostszma a $munkamenet["azonosito"] vltozban tallhat, gy ezt helyezzk az esemenyek tbla eklub mezjbe. A dtum adatbzisban trtn trolsra idblyeget hasznlunk.

23.18. program Rszlet az adatbazis.inc fjlbl


1: function esemenyModositas( $enev, $ehelyszin, $eterulet, $etipus, $ecim, $eirsz, $eismerteto, $eklub, $edatum, $eazonosito ) 2: { 3: global $kapcsolat; 4: if ( ! $eazonosito ) 5: { 6: $lekeres = "INSERT INTO esemenyek (enev, ehelyszin, eterulet, etipus, 7: ecim, eirsz, eismerteto, eklub, edatum ) 8: VALUES( '$enev', '$ehelyszin', '$eterulet', '$etipus', '$ecim', 9: '$eirsz', '$eismerteto', '$eklub', '$edatum')"; 10: } 11: else 12: {

Teljes plda (els rsz)

459

23.18. program (folytats)


13: 14: $lekeres = "UPDATE esemenyek SET enev='$enev', ehelyszin='$ehelyszin', eterulet='$eterulet', etipus='$etipus', ecim='$ecim', eirsz='$eirsz',

15: eismerteto='$eismerteto', eklub='$eklub', edatum='$edatum' 16: WHERE eazonosito='$eazonosito'"; 17: } 18: $eredmeny = mysql_query( $lekeres, $kapcsolat ); 19: if ( ! $eredmeny ) 20: die ( "esemenyModositas hiba: " .mysql_error() ); 21: }

Lthat, hogy a fggvny az $eazonosito paramter rtktl fggen mkdik. Ha hamis rtk, egy INSERT SQL parancs hajtdik vgre a megadott adatokkal. Egyb esetben az $eazonosito egy UPDATE krs felttelben szerepel. Miutn az adatbzist frisstettk, a tagot az esemenylista.php oldalra irnytjuk, ahol a teljes rendezvnynaptrt lthatja. Ha a tag mg nem tlttte ki az rlapot, tugorjuk az ellenrz s adatbzis-frisst kdokat. Ha azonban rendelkeznk az $eazonosito vltozval, mr lekrtk az esemny informciit az adatbzisbl s az rlapra rhatjuk azokat. Ezt gy tehetjk meg, hogy az $esemeny_sor vltozt rtkl adjuk az $urlap vltoznak, az $edatum vltozt pedig az $esemeny_sor["edatum"] rtkvel tltjk fel. Ha nem kaptunk rlaprtkeket s $eazonosito vltoznk sincs, az $urlap["terulet"] s $urlap["tipus"] elemeknek a klubnak megfelel adatokat adjuk rtkl a $klub_sor tmbbl. Ezzel a megfelel lenyl menkben a klubokhoz tartoz rtkek lesznek alapbelltsban kivlasztva. A HTML rlapon az egyetlen emltsre mlt kd a dtum s id szmra ksztett lenyl menket lltja el. Ezeket a menket elg egyszeren bepthettk volna a PHP kdba, de szksgnk van arra, hogy alapbelltsban az aktulis idt, a tag ltal korbban vlasztott idt, vagy az esemenyek tblban trolt idt jelezzk. Az alapbelltsban kivlasztand rtket mr elhelyeztk az $edatum vltozban. Ezt a program elejn az aktulis idre lltottuk be. Ha berkez adatokat szlelnk, annak megfelelen lltjuk be ezt az rtket. Egyb esetben, ha mr meglv esemnyt mdostunk, az esemenyek tbla edatum mezjnek rtkt adjuk az $edatum vltoznak.

23

460

23. ra Minden lenyl menhz az $edatum vltozban lv idblyeget adjuk t a megfelel fggvnynek. Ezek az j datum.inc nev kls llomnyban tallhatk.

23.19. program Rszlet a datum.inc fjlbl


1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: function honapLehetosegek( $datum ) { $datum_tomb = getDate( $datum ); $honapok = array( "Jan","Feb","Mr", "pr","Mj","Jn", "Jl","Aug","Szep", "Okt","Nov","Dec" ); foreach ( $honapok as $kulcs=>$ertek ) { print "<OPTION VALUE=\"".($kulcs+1)."\""; print ( ( $datum_tomb["mon"] == ($kulcs+1) )?"SELECTED":"" ); print ">$ertek\n"; } } function napLehetosegek( $datum ) { $datum_tomb = getDate( $datum ); for ( $x = 1; $x<=31; $x++ ) { print "<OPTION VALUE=\"$x\""; print ( ( $datum_tomb["mday"] == $x )?"SELECTED":"" ); print ">$x\n"; } } function evLehetosegek( $datum ) { $datum_tomb = getDate( $datum ); $most_tomb = getDate(time()); for ( $x = $most_tomb["year"]; $x <= ($most_tomb["year"]+5); $x++ ) { print "<OPTION VALUE=\"$x\"";

Teljes plda (els rsz)

461

23.19. program (folytats)


31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: print ( ( $datum_tomb["year"] == $x )?"SELECTED":"" ); print ">$x\n"; }

function oraLehetosegek( $datum ) { $datum_tomb = getDate( $datum ); for ( $x = 0; $x< 24; $x++ ) { print "<OPTION VALUE=\"$x\"; print ( ( $datum_tomb["hours"] == $x)?"SELECTED:"" ); print ">".sprintf("%'02d",$x)."\n"; } } function percLehetosegek( $datum ) { $datum_tomb = getDate( $datum ); for ( $x = 0; $x<= 59; $x++ ) { print "<OPTION VALUE=\"$x\""; print ( ( $datum_tomb["minutes"] == $x )?"SELECTED":"" ); print ">".sprintf("%'02d",$x)."\n"; } }

Minden fggvny egy idblyeget vr s HTML OPTION elemek listjt rja ki. A getDate() PHP fggvnyt hasznljk arra, hogy az idblyeg megfelel elemnek indext megllaptsk (v, hnap, hnap napja, ra, perc). Ezutn a kapott szmot sszehasonltjk az alkalmazott tartomny rtkeivel (a tartomny a hnap napjainl 1-tl 31-ig, a perceknl 0-tl 59-ig terjed). Ha egyezst szlelnek, a SELECTED jelzt adjk az OPTION elemhez, gy vlasztjk ki a megfelel sort. A 23.4. bra az esemenyfrissites.php kimenett mutatja.

23

462

23. ra

23.4. bra
Az esemenyfrissites.php kimenete

esemenylista.php
Vgl biztostanunk kell a tagoknak egy oldalt, ahol minden ltaluk bevitt esemnyt vgigtekinthetnek. Ennek az oldalnak lehetsget kell adnia arra is, hogy a tagok az esemnyeket szerkeszthessk vagy trlhessenek egyet. Az esemenylista.php az eddigiek ismeretben egyszer program.

23.20. program esemenylista.php


1: <?php 2: include("adatbazis.inc"); 3: include("kozosfv.inc"); 4: $klub_sor = azonositas(); 5: klubAdatEllenorzes( $klub_sor ); 6: 7: function esemenyKiiras() 8: { 9: global $klub_sor; 10: $esemenyek = esemenyekLekeres ( $klub_sor["azonosito"] ); 11: if ( ! $esemenyek ) 12: { 13: print "Nincs esemny a listban<P>"; 14: return; 15: }

Teljes plda (els rsz)

463

23.20. program (folytats)


16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: print "<table border=1>\n"; print "<td><b>Dtum</b></td>\n<td> <b>Nv</b></td>\n <td><b>&nbsp;</b></td>\n"; foreach ( $esemenyek as $sor ) { print "<tr>\n"; print "<td>".date("j M Y H.i", $sor["edatum"])."</td>\n"; print "<td><a href= \"esemenyfrissites.php?eazonosito=". $sor["eazonosito"]."&".SID."\">". html($sor["enev"])."</a></td>\n"; print "<td><a href=\"". $GLOBALS["PHP_SELF"]."?eazonosito=". $sor["eazonosito"]; print "&mitkelltenni= esemenyTorles&".SID."\" "; print "onClick=\"return window.confirm('Biztos benne, hogy trli ezt az esemnyt?')\">"; print "trls</a><br></td>\n"; print "</tr>\n"; } print "</table>\n"; } $uzenet=""; if ( isset( $mitkelltenni ) && $mitkelltenni == "esemenyTorles" && isset( $eazonosito ) ) { esemenyTorles( $eazonosito ); $uzenet .= "Az esemny trlse megtrtnt!<br>"; } ?> <html> <head> <title>Esemnyek listja</title> </head>

23

464

23. ra

23.20. program (folytats)


47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: <body> <?php include("kozosnav.inc"); ?> <h1>Esemnyek listja</h1> <?php if ( $uzenet != "" ) { print "<b>$uzenet</b>"; } ?> <?php esemenyKiiras(); ?> </body> </html>

Szoks szerint az adatbazis.inc fjlt hasznljuk, hogy ksz adatbziskapcsolattal kezdjk az oldalt s a kozosfv.inc fjlt, hogy aktv munkamenetnk legyen. gyszintn a megszokott mdon ellenrizzk, hogy rvnyes tag krte-e le az oldalt. Ezutn ltrehozunk egy j esemenyKiiras() nev fggvnyt, amely kzvetlenl a bngszbe rja az esemnyrl elrhet informcikat. Emlkezznk r, hogy az azonositas() fggvny ltal visszaadott $klub_sor tmb tartalmazza a klubadatokat. A $klub_sor["azonosito"] rtket hasznlhatjuk arra, hogy a klubhoz tartoz sszes rendezvnyt listba rjuk. Ehhez az adatbazis.inc esemenyekLekeres() fggvnyt hasznljuk. Ezt a fggvnyt alaposabban a kvetkez rban trgyaljuk, egyelre elegend annyit tudnunk, hogy egy klubazonostt vr els paramterl, gy egy ktdimenzis tmbben adja vissza a klubhoz tartoz sszes esemny minden adatt. A fggvny visszatrsi rtkt az $esemenyek tmbben troljuk. Valjban tbb adatot krnk le, mint amennyire szksgnk van, de az esemenyekLekeres() fggvny olyan rugalmas, hogy nyugodtan hasznlhatjuk, hacsak nem rzkelnk teljestmnybeli problmkat a program futsa sorn. Ha az $esemenyek hamis rtk, figyelmeztet zenetet kldnk a kimenetre s befejezzk a fggvny futst. Egyb esetben egy HTML tblzatot ptnk fel: vgiglpkedve az $esemenyek tmbn kirunk minden esemnyre vonatkozan nhny informcit.

Teljes plda (els rsz) A date() PHP fggvnynek tadva minden tmb edatum elemt, formzott dtumokat runk ki. A dtum mellett minden esemny szmra egy hivatkozst hozunk ltre, felhasznlva az esemny azonostjt s az enev rtket. Az tadand eazonosito vltoz mellett szerepeltetjk a SID llandt, gy biztostva, hogy a munkamenet rvnyes marad az j oldalon is. A hivatkozs az esemenyfrissites.php oldalra mutat, amely gy meg tudja jelenteni az esemny adatait a szerkeszts szmra. Vgl minden rendezvny sorban egy erre az oldalra visszamutat hivatkozst is szerepeltetnk. Ehhez az eazonosito mellett egy esemenyTorles rtk mitkelltenni paramtert is meghatrozunk. Ez az adott esemny trlsre szolgl majd, ezrt egy JavaScript esemnykezelt is adunk a hivatkozshoz, hogy ne lehessen vletlenl trlni egy rendezvnyt sem. Miutn elksztettk az esemenyKiiras() fggvnyt, kezelnnk kell azt az esetet is, amikor a tag trlni kvn egy esemnyt. Ezt a $mitkelltenni s az $eazonosito vltozk ellenrzsvel tehetjk meg. Ha rendben megkaptuk ezeket, egy j adatbazis.inc fggvnyt, az esemenyTorles()-t hvjuk meg, tadva az $eazonosito rtket.

465

23.21. program Rszlet az adatbazis.inc fjlbl


1: function esemenyTorles( $eazonosito ) 2: { 3: global $kapcsolat; 4: $lekeres = "DELETE FROM esemenyek WHERE eazonosito='$eazonosito'"; 5: $eredmeny = mysql_query( $lekeres, $kapcsolat ); 6: if ( ! $eredmeny ) 7: die ( "esemenyTorles hiba: ".mysql_error() ); 8: return ( mysql_affected_rows($kapcsolat) ); 9: }

Az esemenylista.php egy lehetsges kimenett a 23.5. bra mutatja.

23

466

23. ra

23.5. bra
Az esemenylista.php kimenete

sszefoglals
Az ra vgre elkszltnk a teljesen mkd, tagok szmra kszlt krnyezettel a rendezvnyeket nyilvntart rendszerhez. Lehetsget teremtettnk grafikusainknak az oldalak j kialaktsra, azzal, hogy a lehet legtbb kdot kls llomnyokban helyeztk el. Gyakran hasznltuk a header() fggvnyt, hogy j oldalra irnytsuk a tagot, ha adatokat vrunk tle. A belpsi informcik trolshoz munkamenet-kezel fggvnyeket, a tagok azonostshoz adatbzislekrdezseket hasznltunk minden oldalon. A kvetkez rban hasonl megoldsokat fogunk hasznlni a program nyilvnos felletnek kialaktshoz.

Krdsek s vlaszok
A tbb oldalbl ll alkalmazsok megtervezse s karbantartsa bonyolultnak tnik. Van valami titok emgtt? A pldaalkalmazs elksztse sorn majdnem minden oldalon egyszer mintt kvettnk. Ahogy alkalmazsaink nagyobb vlnak, a teljes krnyezetrl egyetlen programknt kell gondolkodnunk. A klnll oldalak csak a ltogat csatlakozsi pontjai az egsz alkalmazshoz. Tartsuk az sszes egynl tbb oldalon ismtld kdot kln llomnyban!

Teljes plda (els rsz) Ha esetleg gy dntnk, hogy egyetlen kzponti programot ksztnk a teljes alkalmazs szmra, egy egyszer, alapvet HTML elemeket tartalmaz oldalt kell ksztennk. Minden ms tartalom dinamikusan ll majd el a program futsa sorn. Szksgnk lesz egy mitkelltenni tpus vltozra, amely mindig a megfelel szolgltatst vlasztja ki a teljes alkalmazsbl. Ez sokkal formsabb teheti a kdot s segt elkerlni a nem tl elegns Location fejlctrkkt. Msrszt ez azzal jr, hogy sokkal tbb HTML-t kell beptennk a PHP kdok kz.

467

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Melyik PHP fggvnyt hasznljuk arra, hogy MySQL adatbzishoz csatlakozzunk? 2. Melyik fggvnyt alkalmazzuk a munkamenet elkezdsre vagy folytatsra? 3. Melyik fggvny alkalmas arra, hogy kls llomnyokat illessznk a PHP kdba? 4. Melyik PHP fggvnnyel kldnk SQL krseket egy MySQL adatbzis szmra? 5. Melyik llandt alkalmazhatjuk arra, hogy a munkafolyamat-azonostt eljuttassuk egyik oldalrl a msikra egy HTML hivatkozsban? 6. Hogyan kldhetjk tovbb a ltogatt egy msik oldalra? 7. Melyik fggvny alkalmas dtumok formzsra?

Feladatok
1. Tekintsnk vgig az rban trgyalt forrskdokon. Tallunk olyan megoldsokat, amelyeket sajt programjainkban is tudunk majd hasznostani?

23

24. RA
Teljes plda (msodik rsz)
Az elz rban felptettk a klubok szmra a bejegyz s karbantart felletet, amivel j klubok s rendezvnyek kerlhetnek a rendszerbe. Most az tlagos felhasznlk szmra elrhet programokat kell elksztennk, melyek lehetv teszik a listk bngszst. Ebben az rban a kvetkezket tanuljuk meg: Hogyan ksztsnk olyan fggvnyeket, amelyek egyetlen lekrdezssel tbb tblbl hvnak le adatokat? Hogyan kszthetnk a paramtereiktl fgg SQL parancsokat vgrehajt fggvnyeket? Hogyan menthetjk a felhasznl rgebbi belltsait munkamenetfggvnyekkel? Hogyan kell talaktanunk az egyszer szveges adatokat, hogy a HTML kdba rhassuk azokat?

470

24. ra

Az esemnynaptr nyilvnos oldalai

Miutn a tagok bejegyeztethetik klubjaikat s az esemnyeket, itt az ideje, hogy az tlagos felhasznl szmra is elrhet oldalak ksztsbe fogjunk. Ezek az oldalak a listk bngszsre s nem a bennk val keressre szolglnak majd, br nem lenne tl bonyolult ez utbbit sem megvalstani. Ebben az rban ngy oldalt ksztnk el, amelyek lehetsget adnak a felhasznlnak, hogy kirassa egy adott terlet vagy tma rendezvnyeit, brmilyen idpont szerinti szrssel prostva.

esemenyekinfo.php
Az esemenyekinfo.php oldal lehetsget ad a rendszerben lv rendezvnyek bngszsre. Bizonyos szempontbl hasonlt az esemenylista.php oldalra, amit az elz rban trgyaltunk, de nagyobb rugalmassgot s tbb informcit nyjt a felhasznlnak.

24.1. program esemenyekinfo.php


1: <?php 2: include("adatbazis.inc"); 3: include("datum.inc"); 4: include("kozosfv.inc"); 5: 6: if ( isset($mitkelltenni) && $mitkelltenni == "esemenyLista" ) 7: $munkamenet["esemenyek"] = $urlap; 8: elseif ( $munkamenet["esemenyek"] ) 9: $urlap = $munkamenet["esemenyek"]; 10: else 11: { 12: $datum_tomb = getDate( time() ); 13: $munkamenet["esemenyek"]["terulet"] = "BRMELY"; 14: $munkamenet["esemenyek"]["tipus"] = "BRMELY"; 15: $munkamenet["esemenyek"]["honap"] = $datum_tomb["mon"]; 16: $munkamenet["esemenyek"]["ev"] = $datum_tomb["year"]; 17: } 18: 19: $idoszak = datumIdoszak( $munkamenet["esemenyek"]["honap"], 20: $munkamenet["esemenyek"]["ev"] );

Teljes plda (msodik rsz)

471

24.1. program (folytats)


21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: function esemenyLista( ) { global $idoszak, $munkamenet; $esemenyek = esemenyekLekeres( 0, $idoszak, $munkamenet["esemenyek"]["terulet"], $munkamenet["esemenyek"]["tipus"] ); if ( ! $esemenyek ) { print "Nincs megjelenthet esemny<p>"; return; } print "<table border=1>\n"; print "<td><b>Dtum</b></td>\n"; print "<td><b>Esemny</b></td>\n"; print "<td><b>Klub</b></td>\n"; print "<td><b>Terlet</b></td>\n"; print "<td><b>Tpus</b></td>\n"; foreach ( $esemenyek as $sor ) { print "<tr>\n"; print "<td>".date("j M Y H.i", $sor["edatum"])."</td>\n"; print "<td><a href=\"esemenyinfo.php?eazonosito=". $sor["eazonosito"]."&".SID."\">". html($sor["enev"])."</a></td>\n"; print "<td><a href=\"klubinfo.php?kazonosito=". $sor["eklub"]."&".SID."\">". html($sor["klubnev"])."</a></td>\n"; print "<td>".$sor["teruletnev"]."</td>\n"; print "<td>".$sor["tipusnev"]."</td>\n"; print "</tr>\n"; } print "</table>\n"; }

?>

<html> <head> <title>Esemny informcik</title>

24

472

24. ra

24.1. program (folytats)


57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: </head> <body> <?php include("kozosnav.inc"); ?> <h1>Esemny informcik</h1> <p> <form action="<?php print $PHP_SELF;?>"> <input type="hidden" name="mitkelltenni" value="esemenyLista"> <input type="hidden" name="<?php print session_name() ?>" value="<?php print session_id() ?>"> <select name=urlap[honap]> <?php honapLehetosegek( $idoszak[0] ); ?> </select> <select name=urlap[ev]> <?php evLehetosegek( $idoszak[0] ); ?> </select> <select name=urlap[terulet]> <option value="BRMELY">Brmely terlet <?php optionLista( "teruletek", $urlap["terulet"]) ?> </select> <select name=urlap[tipus]> <option value="BRMELY">Brmely tpus <?php optionLista( "tipusok", $urlap["tipus"] ) ?> </select> <input type = "submit" value="Listzs"> </form> </p> <?php esemenyLista( ); ?> </body> </html>

Teljes plda (msodik rsz) Szoks szerint az adatbazis.inc s a kozosfv.inc kls llomnyok beillesztsvel kezdjk. Amellett, hogy elrhetjk majd az ezekben trolt fggvnyeket, biztosak lehetnk abban, hogy l adatbziskapcsolattal rendelkeznk s aktv munkamenettel dolgozhatunk. Ezutn ellenrizzk, hogy rkezett-e rlapadat. Ezt a mr ismert mitkelltenni rlapelembl szrmaz $mitkelltenni vltoz vizsglatval tehetjk meg. Ha kitlttt rlap adatai rkeztek, azok elnyt lveznek minden korbban elraktrozott adattal szemben. Az elz rban lthattuk, hogyan rendeltnk egy asszociatv tmbt a munkamenethez, hogy a belpett tag adatait nyilvntartsuk. Ebben az rban j elemeket adunk ehhez, amelyek a felhasznl belltsait tartalmazzk majd. A $munkamenet vltozt a kozosfv.inc llomnyban rendeltk a munkamenethez (mint azt mr az elz rban lttuk): session_start(); session_register( "munkamenet" ); Most ezt a $munkamenet tmbt tbbdimenzis tmbb alaktjuk, mivel a $munkamenet["esemenyek"] tmbelemnek egy asszociatv tmbt adunk rtkl. Ebben a tmbben fogjuk trolni a csak ehhez az oldalhoz tartoz belltsokat. Ezek a terlet, tpus, hnap s v rtkek. Ha rlap adat rkezett, a korbbi belltsokat ezzel rjuk fell. Lehetsges, hogy a program futsakor ppen nem rkezett rlapinformci, de korbban mr troltuk a felhasznl ltal elnyben rszestett belltsokat. Ebben az esetben a $mitkelltenni vltoz nincs belltva, viszont a $munkamenet["esemenyek"] tmb mr tartalmaz elemeket. Ebben az esetben az $urlap tmbt rjuk fell a korbban trolt rtkekkel. Ez biztostja, hogy az rlapban a megfelel belltsok ltsszanak. Ha a felhasznl nem kldtt be rlap adatokat s korbban sem troltuk a belltsait, neknk kell alaprtkekkel feltltennk a $munkamenet["esemenyek"] tmbt. A getDate() beptett PHP fggvnyt hasznljuk arra, hogy elemeire bontsuk a dtumot. A visszaadott tmb alapjn lltjuk be a $munkamenet["esemenyek"]["honap"] s $munkamenet["esemenyek"]["ev"] elemeket az aktulis hnap s v rtkekre. Mr tudjuk, hogy az v s hnap rtkek rvnyes adatot tartalmaznak, akr rlaprtkekbl, akr korbbi belltsbl, akr az aktulis dtumbl szrmaznak. Ezeket az rtkeket a datum.inc egy j fggvnynek, a datumIdoszak() fggvnynek adjuk t. Ez a fggvny hnap s v paramtereket vr s kt idblyeggel tr vissza, megjellve a hnap kezdett s vgt.

473

24

474

24. ra

24.2. program Rszlet a datum.inc fjlbl


1: function datumIdoszak( $honap, $ev ) 2: { 3: $eleje = mktime( 0, 0, 0, $honap, 1, $ev ); 4: $vege = mktime( 0, 0, 0, $honap+1, 1, $ev ); 5: $vege--; 6: return array( $eleje, $vege ); 7: }

A fggvny ltal visszaadott tmbt az $idoszak globlis vltoznak adjuk rtkl. Ltrehozunk egy j esemenyLista() fggvnyt, amely a megfelel esemnyekrl r majd informcikat a bngszbe. Ezt ksbb a HTML trzsrszben hvjuk meg. Ahhoz, hogy az esemnyek listjt megkapjuk, az esemenyekLekeres() fggvnyt hasznljuk, amely az adatbazis.inc llomnyban tallhat. Ezzel a fggvnnyel rintlegesen mr az elz rban is tallkoztunk, de kevs j tulajdonsgt ismerhettk meg.

24.3 program Rszlet az adatbazis.inc fjlbl


1: function esemenyekLekeres( $kazonosito=0, $idoszak=0, $terulet=0, $tipus=0 ) 2: { 3: global $kapcsolat; 4: $lekeres = "SELECT klubok.klubnev, esemenyek.*, teruletek.terulet as teruletnev, tipusok.tipus as tipusnev "; 5: $lekeres .= "FROM klubok, esemenyek, teruletek, tipusok WHERE "; 6: $lekeres .= "klubok.azonosito=esemenyek.eklub 7: AND esemenyek.eterulet=teruletek.azonosito 8: AND esemenyek.etipus=tipusok.azonosito "; 9: if ( ! empty( $kazonosito ) && $kazonosito !="BRMELY" ) 10: $lekeres .= "AND esemenyek.eklub= '$kazonosito' "; 11: if ( ! empty($idoszak) )

Teljes plda (msodik rsz)

475

24.3 program (folytats)


12: $lekeres .= "AND esemenyek.edatum >= '$idoszak[0]' AND esemenyek.edatum <='$idoszak[1]' "; if ( ! empty($terulet) && $terulet != "BRMELY" ) $lekeres .= "AND esemenyek.eterulet='$terulet' "; if ( ! empty($tipus) && $tipus != "BRMELY" ) $lekeres .= "AND esemenyek.etipus='$tipus' "; $lekeres .= "ORDER BY esemenyek.edatum"; $eredmeny = mysql_query( $lekeres, $kapcsolat ); if ( ! $eredmeny ) die ( "esemenyLekeres hiba: ".mysql_error() ); $vissza = array(); while ( $sor = mysql_fetch_array( $eredmeny ) ) array_push( $vissza, $sor ); return $vissza; }

13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:

A fggvny neve nem igazn fejezi ki sokoldalsgt. Ngy paramtert vr: egy klubazonostt, egy kt idblyeget tartalmaz tmbbl ll idszakot, egy terlet- s egy tpuskdot. Minden paramtere elhagyhat vagy hamis, illetve res rtkkel helyettesthet. A fggvny lnyegben egy SQL krst llt ssze a paramterek alapjn. A lekrs alapveten sszekapcsolja az adatbzisban lv tblkat, ezzel biztostva, hogy a klubnv, terletnv s tpusnv mezk is elrhetk legyenek az eredmnytblban. $lekeres = "SELECT klubok.klubnev, esemenyek.*, teruletek.terulet as teruletnev, tipusok.tipus as tipusnev "; $lekeres .= "FROM klubok, esemenyek, teruletek, tipusok WHERE "; $lekeres .= "klubok.azonosito=esemenyek.eklub AND esemenyek.eterulet=teruletek.azonosito AND esemenyek.etipus=tipusok.azonosito ";

Ezutn a fggvny tovbbi feltteleket ad ehhez, attl fggen, hogy a megfelel fggvnyparamter be van-e lltva. A $tipus s $terulet paramterek akkor is figyelmen kvl maradnak, ha a "BRMELY" karakterlncot tartalmazzk.

24

476

24. ra A gyakorlatban ez azt jelenti, hogy minl tbb paramtert kap a fggvny, annl szkebb eredmnytblt fogunk kapni. Ha nem adunk t semmilyen paramtert, az sszes esemny informciit megkapjuk. Ha csupn egy $kazonosito paramtert adunk meg, csak az adott klubhoz tartoz esemnyeket kapjuk vissza. Ha csak a msodik $idoszak paramtert adjuk meg, csak az adott idszakba es rendezvnyeket lthatjuk s gy tovbb. Vgl a fggvny az SQL parancsot vgrehajtja s egy ktdimenzis tmbbel tr vissza, amely a kivlasztott esemnyek rszleteit tartalmazza. Miutn a fggvny ltal visszaadott ktdimenzis tmbt az $esemenyek vltozba helyeztk, vgig kell lpkednnk annak elemein. Az edatum elemeket felhasznlva kirjuk a formzott dtumokat a date() beptett fggvny segtsgvel. Ezutn egy hivatkozst ksztnk az esemenyinfo.php oldalra, ahol tbb informci rhet el egy rendezvnyrl. Ehhez az esemny azonostjt s a SID llandt kell tadnunk. Ebben a ciklusban egy jabb HTML hivatkozst is ksztnk a klubinfo.php oldalra, a klub azonostjval s a SID llandval, vgl kirjuk a terlet- s tpusneveket a bngszbe. Taln feltnt az elz rban, hogy egy html() nev fggvnyt hasznltunk arra, hogy szveges adatokat rjunk ki a bngszbe. Az esemenyLista() fggvnyben, ahogy az esemnyek informciin vgiglpkednk, ismt a html() fggvnyt hvjuk meg. Ez az ltalunk rt fggvny a kozosfv.inc llomnyban tallhat. Egy karakterlncot vr s annak bngszbe rshoz alkalmass tett, talaktott vltozatval tr vissza. A klnleges karakterek HTML elemekk alakulnak, az jsor karakterek pldul <br>-.

24.4. program Rszlet a kozosfv.inc fjlbl


1: function html( $szoveg ) 2: { 3: if ( is_array( $szoveg ) ) 4: { 5: foreach ( $szoveg as $kulcs=>$ertek ) 6: $szoveg[$kulcs] = htmlszoveg( $ertek ); 7: return $szoveg; 8: } 9: return htmlszoveg( $szoveg ); 10: } 11:

Teljes plda (msodik rsz)

477

24.4. program (folytats)


12: function htmlszoveg( $szoveg ) 13: { 14: $szoveg = htmlspecialchars( $szoveg ); 15: $szoveg = nl2br( $szoveg ); 16: return $szoveg; 17: }

Lthat, hogy ez valjban nem egy, hanem kt fggvny. A html() egy karakterlncot vagy egy tmbt vr paramterl. Ha tmbt kap, vgiglpked rajta, talaktva minden elemet, egyb esetben magt a kapott karakterlncot alaktja t. A tnyleges talakts egy msik fggvnyben, a htmlszoveg()-ben valsul meg, amely kt beptett fggvnyt alkalmaz a kapott karakterlncra. A htmlspecialchars() minden karaktert, ami nem jelenne meg helyesen a HTML kdban, a hozz tartoz HTML elemre cserl. Az nl2br() minden jsor karaktert <br> sortrssel helyettest. Visszatrve az esemenyekinfo.php oldalra, miutn belltottuk az alapadatokat s ltrehoztuk az esemnyek kirsra szolgl fggvnyt, mr csak annyi van htra, hogy egy rlapot biztostsunk a felhasznlnak, amely lehetsget ad a lista szktsre, illetve bvtsre. A felhasznlnak vlasztsi lehetsget ad rlap egyszeren elkszthet az elz rban megismert fggvnyekkel, melyek kzvetlenl OPTION HTML elemeket rnak ki a bngszbe. Az esemenyekinfo.php egy lehetsges kimenett a 24.1. bra mutatja.

24.1. bra
Az esemenyekinfo.php kimenete

24

478

24. ra

klubokinfo.php
A felhasznl jogos ignnyel nem csak rendezvnyek, hanem klubok szerint is ki szeretn ratni az adatbzis adatait, tpus vagy terlet szerint szktve azokat. A klubokinfo.php oldal ezt az ignyt elgti ki.

24.5. program klubokinfo.php


1: <?php 2: include("adatbazis.inc"); 3: include("datum.inc"); 4: include("kozosfv.inc"); 5: if ( isset($mitkelltenni) && $mitkelltenni == "klubLista" ) 6: $munkamenet["klubok"] = $urlap; 7: elseif ( $munkamenet["klubok"] ) 8: $urlap = $munkamenet["klubok"]; 9: else 10: { 11: $munkamenet["klubok"]["terulet"] = "BRMELY"; 12: $munkamenet["klubok"]["tipus"] = "BRMELY"; 13: } 14: function klubLista( ) 15: { 16: global $munkamenet; 17: $klubok = klubokLekeres ( $munkamenet["klubok"]["terulet"], 18: $munkamenet["klubok"]["tipus"] ); 19: if ( ! $klubok ) 20: { 21: print "Nincs megjelenthet klub<p>\n"; 22: return; 23: } 24: print "<table border=1>\n"; 25: print "<td><b>Klub</b></td>\n"; 26: print "<td><b>Terlet</b></td>\n"; 27: print "<td><b>Tpus</b></td>\n"; 28: foreach ( $klubok as $sor ) 29: { 30: print "<tr>\n";

Teljes plda (msodik rsz)

479

24.5. program (folytats)


31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: print "<td><a href=\"klubinfo.php?[kazonosito]=". $sor["azonosito"]."&".SID."\">". html($sor["klubnev"])."</a></td>\n"; print "<td>$sor["teruletnev"]</td>\n"; print "<td>$sor["tipusnev"]</td>\n"; print "</tr>\n"; } print "</table>\n"; }

?> <html> <head> <title>Klub informcik</title> </head> <body> <?php include("kozosnav.inc"); ?> <P> <h1>Klub informcik</h1> <p> <form action="<?php print $PHP_SELF;?>"> <input type="hidden" name="mitkelltenni" value="klubLista"> <input type="hidden" name="<?php print session_name() ?>" value="<?php print session_id() ?>"> <select name=urlap["terulet"]> <option value="BRMELY">Brmely terlet <?php optionLista( "teruletek", $urlap[terulet] ) ?> </select> <select name=urlap[tipus]> <option value="BRMELY">Brmely tpus <?php optionLista( "tipusok", $urlap["tipus"] ) ?> </select> <input type = "submit" value="Rendben"> </form>

24

480

24. ra

24.5. program (folytats)


65: 66: 67: 68: 69: 70: </p> <?php klubLista( ); ?> </body> </html>

Lthatjuk, hogy ez a program szerkezetben s logikjban igencsak hasonlt az elz pldban szereplre. Az ehhez az oldalhoz tartoz memria azonban a $munkamenet["klubok"] tmbbe kerl. Ha rlapadatok rkeznek, azokkal rjuk fell a korbbi tartalmt, ha nem rkezett rlap s mr be van lltva, akkor az $urlap tmbt rjuk fell a $munkamenet["klubok"] vltozval. Ha egyik felttel sem teljesl, alaprtkekkel tltjk fel. Egy klubLista() fggvnyt hozunk ltre, amelyben az adatbazis.inc egy j fggvnyt, a klubokLekeres()-t hvjuk meg. Ez a fggvny a klub terletre, illetve tpusra vonatkoz elhagyhat paramtereket vr.

24.6. program Rszlet az adatbazis.inc fjlbl


1: function klubokLekeres( $terulet="", $tipus="" ) 2: { 3: global $kapcsolat; 4: $lekeres = "SELECT klubok.*, teruletek.terulet as teruletnev, tipusok.tipus as tipusnev "; 5: $lekeres .= "FROM klubok, teruletek, tipusok WHERE "; 6: $lekeres .= "klubok.terulet=teruletek.azonosito AND klubok.tipus=tipusok.azonosito "; 7: if ( $terulet != "BRMELY" && ! empty( $terulet ) ) 8: $lekeres .= "AND klubok.terulet=$terulet "; 9: if ( $tipus != "BRMELY" && ! empty( $tipus ) ) 10: $lekeres .= "AND klubok.tipus='$tipus' "; 11: $lekeres .= "ORDER BY klubok.terulet, klubok.tipus, klubok.klubnev"; 12: $eredmeny = mysql_query( $lekeres, $kapcsolat ); 13: if ( ! $eredmeny ) 14: die ( "klubokLekeres hiba: ".mysql_error() );

Teljes plda (msodik rsz)

481

24.6. program (folytats)


15: 16: 17: 18: 19: $vissza = array(); while ( $sor = mysql_fetch_array( $eredmeny ) ) array_push( $vissza, $sor ); return $vissza; }

A klubokLekeres() fggvny paramterei fggvnyben dinamikusan llt el egy SQL utastst. Alapesetben csupn sszekapcsolja a klubok, teruletek s tipusok tblkat. Ha res karakterlncon s a "BRMELY" karaktersorozaton kvl brmi mst kap a $terulet vagy $tipus paramterekben, tovbb szkti az eredmnytblt a WHERE felttelhez adott jabb elemekkel. Vgl egy ktdimenzis tmbbel tr vissza. A klubokinfo.php oldalon vgiglpkednk ezen a tmbn, kirva a teruletnev s tipusnev rtkeket is a bngsz szmra. Mint eddig, a klub neve most is egy hivatkozsban szerepel, amely a klubinfo.php oldalra mutat.

klubinfo.php
A klubinfo.php oldal lehetsget ad egyetlen klub minden adatnak megtekintsre. Hivatkozsok segtsgvel juthat ide a felhasznl, akr az esemenyekinfo.php, az esemenyinfo.php vagy a klubokinfo.php oldalakrl is. Az oldalt az eddig megismert megoldsok s fggvnyek segtsgvel pthetjk fel, amint az albbi kd mutatja.

24.7. program klubinfo.php


1: <?php 2: include("adatbazis.inc"); 3: include("kozosfv.inc"); 4: if ( ! isset($kazonosito) ) 5: header( "Location: klubokinfo.php?".SID ); 6: $klub = klubLekeres( $kazonosito ); 7: 8: $klub = html( $klub ); 9: if ( $klub["email"] != "" ) 10: $klub["email"] = "<A HREF=\"mailto:$klub[email]\ ">".$klub["email"]."</A>";

24

482

24. ra

24.7. program (folytats)


11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: function klubEsemenyei () { global $kazonosito; $esemenyek = esemenyekLekeres( $kazonosito ); if ( ! $esemenyek ) { print "Nincs megjelenthet esemny<P>"; return; } print "<table border=1>\n"; print "<td><b>Dtum</b></td>\n"; print "<td><b>Esemny</b></td>\n"; print "<td><b>Terlet</b></td>\n"; print "<td><b>Tpus</b></td>\n"; foreach ( $esemenyek as $sor ) { print "<tr>\n"; print "<td>".date("j M Y H.i", $sor["edatum"])."</td>\n"; print "<td><a href=\"esemenyinfo.php?eazonosito=". $sor["eazonosito"]."&".SID."\">".htm l($sor["enev"])."</a></td>\n"; print "<td>".$sor["teruletnev"]."</td>\n"; print "<td>".$sor["tipusnev"]."</td>\n"; print "</tr>\n"; } print "</table>\n"; } ?> <html> <head> <title>Klub rszletek</title> </head> <body> <?php include("kozosnav.inc"); ?> <p> <h1>Klub rszletek</h1> <h4><?php print $klub["klubnev"] ?></h4>

30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47:

Teljes plda (msodik rsz)

483

24.7. program (folytats)


48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: <p> Terlet: <b><?php print $klub["teruletnev"] ?></b> <br> Tpus: <b><?php print $klub["tipusnev"] ?></b> <br> Email: <b><?php print $klub["email"] ?></b> </p> Ismertet:<br> <b><?php print $klub["ismerteto"] ?></b> <hr> <?php klubEsemenyei(); ?> </body> </html>

A program egy $azonosito paramtert vr, amely egy klub azonostszmt kell, hogy tartalmazza. Ha az oldal nem kapott ilyen paramtert, a felhasznlt a klubokinfo.php oldalra kldjk. A klub adatainak kidertsre egy j adatbazis.inc fggvnyt, a klubLekeres()-t alkalmazzuk. Ez a fggvny egy klubazonostt vr s egy tmbt ad vissza:

24.8. program Rszlet az adatbazis.inc fjlbl


1: function klubLekeres( $kazonosito ) 2: { 3: global $kapcsolat; 4: $lekeres = "SELECT klubok.*, teruletek.terulet as teruletnev, tipusok.tipus as tipusnev "; 5: $lekeres .= "FROM klubok, esemenyek, teruletek, tipusok WHERE "; 6: $lekeres .= "klubok.terulet=teruletek.azonosito 7: AND klubok.tipus=tipusok.azonosito 8: AND klubok.azonosito='$kazonosito'"; 9: $eredmeny = mysql_query( $lekeres, $kapcsolat ); 10: if ( ! $eredmeny ) 11: die ( "klubLekeres hiba: ".mysql_error() ); 12: return mysql_fetch_array( $eredmeny ); 13: }

24

484

24. ra A klub adatainak megszerzsre a sorLekeres() fggvnyt is hasznlhattuk volna. Azrt ksztettnk mgis egy clfggvnyt erre a feladatra, mivel gy az eredmnytbla a teruletnev s tipusnev elemeket is tartalmazza majd. Ezt a klubok, teruletek s tipusok tblk sszekapcsolsval rhetjk el. A klubLekeres()ltal visszaadott tmbt a $klub vltozban troljuk, tartalmt pedig a HTML trzsrszben rjuk ki a bngsz szmra. Az oldalon ltrehozunk mg egy klubEsemenyei() nev fggvnyt is, amely a klubhoz tartoz esemnyek kirst vgzi, felhasznlva az esemenyekLekeres() nven korbban ltrehozott fggvnynket. A klubinfo.php egy lehetsges kimenett a 24.2. bra mutatja.

24.2. bra
A klubinfo.php kimenete

esemenyinfo.php
Az esemenyinfo.php az utols oldal, amit az alkalmazshoz el kell ksztennk. Erre az oldalra brmely esemnyinformcikat ad laprl el lehet jutni egy hivatkozs segtsgvel. Az oldal minden informcit megad az $eazonosito segtsgvel kivlasztott esemnyrl.

Teljes plda (msodik rsz)

485

24.9. program esemenyinfo.php


1: <?php 2: include("adatbazis.inc"); 3: include("kozosfv.inc"); 4: if ( ! isset($eazonosito) ) 5: header( "Location: esemenyeklista.php?".SID ); 6: $esemeny = esemenyLekeres( $eazonosito ); 7: html( $esemeny ); 8: ?> 9: <html> 10: <head> 11: <title>Esemny rszletei</title> 12: </head> 13: <body> 14: <?php 15: include("kozosnav.inc"); 16: ?> 17: <P> 18: <h1>Esemny rszletei</h1> 19: <h4><?php print $esemeny["enev"] ?></h4> 20: <p> 21: Klub: 22: <b> 23: <?php print "<a href=\"klubinfo.php?kazonosito=". $esemeny["eklub"]."&".SID."\"> 24: $esemeny["klubnev"]</a>" 25: ?> 26: </b> 27: <br> 28: Terlet: <b><?php print $esemeny["teruletnev"]?></b> 29: <br> 30: Tpus: <b><?php print $esemeny["tipusnev"] ?></b> 31: </p> 32: Ismertet:<br> 33: <?php print $esemeny["eismerteto"] ?> 34: </body> 35: </html> Az eddigiek utn ez az oldal mr elg egyszernek ltszik. Egyetlen j fggvnnyel tallkozhatunk, az adatbazis.inc llomny esemenyLekeres() fggvnyvel. Ennek segtsgvel kapjuk meg az adott $eazonosito-hoz tartoz esemny rszleteit. Miutn ezek egy tmbben rendelkezsre llnak, mr csak ki kell rnunk azokat a bngszbe.

24

486

24. ra Az esemenyLekeres() fggvnyt a 24.10. pldban lthatjuk. Tulajdonkppen csupn egy egyszer SQL lekrsbl ll, amely a klubok s az esemenyek tblkat kapcsolja ssze.

24.10. program Rszlet az adatbazis.inc fjlbl


1: function esemenyLekeres( $eazonosito ) 2: { 3: global $kapcsolat; 4: $lekeres = "SELECT klubok.klubnev as klubnev, esemenyek.*, teruletek.terulet as teruletnev, tipusok.tipus as tipusnev "; 5: $lekeres .= "FROM klubok, esemenyek, teruletek, tipusok WHERE "; 6: $lekeres .= "klubok.azonosito=esemenyek.eklub 7: AND esemenyek.eterulet=teruletek.azonosito 8: AND esemenyek.etipus=tipusok.azonosito 9: AND esemenyek.eazonosito='$eazonosito'"; 10: $eredmeny = mysql_query( $lekeres, $kapcsolat ); 11: if ( ! $eredmeny ) 12: die ( "esemenyLekeres hiba: ".mysql_error() ); 13: return mysql_fetch_array( $eredmeny ); 14: }

A jv
Mostanra elkszltnk a teljes rendezvnynaptrral. Remlem sikerlt rzkeltetni ezzel a vals letbeli kisalkalmazsok dinamikus kialaktsnak lehetsgeit s a PHP szertegaz kpessgeit. Klnsen rdemes megfigyelni, mennyire megknnytik munknkat a PHP 4 munkameneteket kezel fggvnyei, mivel ezek hasznlatval igen egyszer az adatok megrzse krsrl krsre .Ha a felhasznlnk a munkamenet sorn ksbb visszatr mondjuk az esemenyekinfo.php oldalra, pontosan azokat a belltsokat fogja tallni, mint amelyeket legutbb otthagyott. A munkamenetfggvnyek nlkl felteheten sokkal tbb informcit kellett volna krsrlkrsre tadnunk oldalainknak az URL-ekben.

Teljes plda (msodik rsz) Br az esemnynaptr bizonyos megkzeltsbl teljesnek tekinthet, mindazonltal csak egy j prototpus, amit meg tudunk mutatni a megrendelnek, ahogy haladunk a munkval. Az alkalmazs hasznra vlna nhny tovbbi szolgltats, klnskppen egy kulcsszavas keress. Kellemes lenne lehetsget adni a ltogatknak, hogy megjegyzseket fzhessenek a rendezvnyekhez. Ez j dimenzit nyitna az alkalmazs szmra, igazn rdekes krnyezett alaktva azt. Lehetsget adhatnnk a tagok szmra, hogy kpekre mutat hivatkozsokat helyezzenek el a klubok ismertetiben. Akr azt is megoldhatnnk, hogy kpeket tlthessenek fel bngszjk segtsgvel. A tagok felteheten rlnnek, ha az esemnyeket lemsolhatnk vagy a rendezvnyek ismtld jellegt is kezelhetnk. Mieltt az alkalmazst tnyjtannk a megbznak, szksgnk lesz egy karbantart felletre, amely alkalmas arra, hogy egy technikailag kpzetlen adminisztrtor is mdosthasson vagy trlhessen tagokat, illetve az esemnyeket, valamint a terlet- s tpuskategrikat megvltoztathassa. Valsznleg feltnt mr, hogy programjaink kimenete elgg sprtai. Vgl t kell adnunk a munkt egy grafikus terveznek, aki gyes vezrlsvot, komoly grafikt s ms elemeket ad az oldalhoz. Szerencsre a legtbb PHP kd kls llomnyokban tallhat, a HTML-tl fggetlenl, de elkpzelhet, hogy szksg lesz rnk is a ciklusok jrarsnl.

487

sszefoglals
Ebben s az elz rban elksztettnk egy teljesen mkd tbboldalas PHP alkalmazst. Gyakoroltuk az llapot mentsnek, a felhasznli azonostsnak, az adatbzis-adatok mdostsnak s megjelentsnek mdjait s sok ms krdst is rintettnk. Egy tbboldalas alkalmazs vgigvitele egy knyvben nem knny dolog, de megri a kitartst. Olyan krdsekre adtunk vlaszokat, olyan problmkat oldottunk meg, amelyekkel munknk sorn idrl idre tallkozni fogunk. Majdnem minden programnak, amit runk, egynl tbb felhasznl krseit kell majd egyidben kiszolglnia, teht gyes megoldsokra van szksg az llapotok mentsre.

24

488

24. ra

Krdsek s vlaszok
Ennyi volt. Hogyan tovbb? Ez mr nem a knyvn mlik. Elg informcit tallhatunk ebben a knyvben ahhoz, hogy sajt kifinomult alkalmazsainkat el tudjuk kszteni. Ezzel s a Vilghln elrhet rengeteg informcival nincs, ami megllthatna brkit is a fejldsben!

Mhely
A mhelyben kvzkrdsek tallhatk, melyek segtenek megszilrdtani az rban szerzett tudst. A vlaszokat az A fggelkben helyeztk el.

Kvz
1. Melyik fggvny hasznlhat j elem tmb vgre val beszrshoz? 2. Lehetsges egy j elem felvtele a tmb vgre fggvny hasznlata nlkl is? 3. Melyik fggvny alkalmazhat a klnleges karakterek talaktsra HTMLkirs cljbl? 4. Melyik fggvny alaktja t az jsor karaktereket <br> elemekk? 5. A SID lland a munkamenet-azonost oldalrl-oldalra kldshez hivatkozsok ksztsnl hasznlhat. Hogyan rhet el ugyanez a hats rlap ksztsekor?

Feladatok
1. Tekintsnk vgig az rban trgyalt forrskdokon. Tallunk olyan megoldsokat, amiket fel tudunk hasznlni sajt programjainkban? 2. Lapozzuk t a knyvet s jegyzeteinket, ha rtunk ilyeneket. Jusson ksbb esznkbe, hogy rdemes kis id elteltvel jra tnzni a jegyzeteket, hogy minl tbb hasznunk legyen a befektetett munkbl.

You might also like