Professional Documents
Culture Documents
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
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
Tartalomjegyzk
Bevezet
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
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
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
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
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
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
(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
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
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
xxi Krdsek s vlaszok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 Mhely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299 Kvz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299 Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
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
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
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
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
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
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
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
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
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.
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.
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.
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.
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
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.
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 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
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
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. 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
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.
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
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.
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.
Az alkotelemek
39
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.
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.
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.
Plda 5
3.234 "hello" true
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
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
44
4. ra
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.
Az alkotelemek
45
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.
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.
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.
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
Nv egyenl
nem egyenl azonos nem azonos nagyobb, mint nagyobb, vagy egyenl
Plda $x == 5
$x != 5 $x === 5 $x !== 5 $x > 4 $x >= 4
Eredmny false
true false true false true
< <=
$x < 4 $x <= 4
false true
Ezeket a mveletjeleket tbbnyire egszekkel vagy lebegpontos szmokkal hasznljuk, br az egyenlsg karakterlncok esetben is vizsglhat.
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.
Nv vagy
vagy kizr vagy
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
Mirt kell ktfle vagy s s mveletjel? A magyarzat a mveletek kirtkelsi sorrendjben rejlik, amelyrl a fejezet ksbbi rszben tanulunk.
Az alkotelemek
51
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;
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.
Az alkotelemek
53
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
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.
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
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".
60
5. ra
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.
62
5. ra
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
<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
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.
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.
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.
Vezrlsi szerkezetek
69
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
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.
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.
72
5. ra
Vezrlsi szerkezetek
73
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
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
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.
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.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 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.
82
6. ra
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
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.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.
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.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.
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
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.
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
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.
Fggvnyek
93
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
rtk Berci
Mariska Aladr Eleonra
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.
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
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.
Tmbk
103
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 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 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.
Tmbk
107
7.2. bra
Asszociatv tmb bejrsa
108
7. ra
Tmbk
109
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.
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.
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.
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
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.
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.
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
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
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:
124
8. ra
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.
Objektumok
125
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.
126
8. ra
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.
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
Objektumok
131
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.
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.
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.
Objektumok
135
$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.
136
8. ra
Objektumok
137
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
140
8. ra
Objektumok
141
142
8. ra
8.2. bra
Egy HTMLTablazat tpus objektum kimenete
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?
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
$REQUEST_URI
$HTTP_REFERER
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.
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
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.
154
9. ra
rlapok
155
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>
156
9. ra
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.
rlapok
157
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.
158
9. ra
rlapok
159
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.
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
162
9. ra
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.
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.
rlapok
165
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.
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.
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.
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
Plda test.gif
6835
A 9.15. pldban lthat program kirja a rendelkezsre ll informcikat a feltlttt fjlrl, s ha az GIF formtum, megjelenti.
168
9. ra
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
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
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
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.
Fjlok hasznlata
175
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.
176
177
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
Fjlok hasznlata
179
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.
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.
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.
182
10. ra
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.
183
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.
184
10. ra
Fjlok hasznlata
185
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.
186
10. ra A 10.13. pldban elszr az fwrite() fggvny hasznlatval egy fjlba runk, majd az fputs() fggvnnyel adatokat fznk hozz.
Fjlok hasznlata
187
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.
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
Fjlok hasznlata
189
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
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 );
195
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.
197
11
198
11. ra
11.1. bra
A DBM adatbzis sszes bejegyzsnek lekrdezse.
199
11
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.
201
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
202
11. ra
11.2. bra
sszetett adatszerkezetek visszaolvassa DBM adatbzisbl
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
204
11. ra
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.
207
11
208
11. ra
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.
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" );
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
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'
217
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
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.
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
222
12. ra
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.
223
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.
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
226
12. ra
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.
12
228
12. ra
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";
231
12
232
12. ra
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.
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?
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.
$PATH_INFO
Kapcsolat a klvilggal
239
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 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.
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
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
Szveg OK
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.
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
246
13. ra
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
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.
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.
Kapcsolat a klvilggal
249
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
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.
252
13. ra
Kapcsolat a klvilggal
253
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
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
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.
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.
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
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. 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.
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
$kek );
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
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
imagefilledpolygon( $kep, $pontok, count ( $pontok )/2, $kek ); 15: imagecolortransparent( $kep, $piros ); 16: imagegif($kep); 17: ?>
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.
14
270
14. ra
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
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.
273
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
275
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.
279
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.
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
Plda 28
7 12 20
Dtumok kezelse
285
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
286
15. ra
15.1. bra
A getdate() fggvny hasznlata
Plda pm
PM 05 Thu January 03 3 5
Dtumok kezelse
287
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
15
288
15. ra
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.
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
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
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.
Dtumok kezelse
291
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.
15
292
15. ra
Dtumok kezelse
293
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
Dtumok kezelse
295
15
296
15. ra
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.
Az adatok kezelse
303
16
304
16. ra } } $pont = new Pont( 5, 7 ); $tomb_pont = (array) $pont; print $tomb_pont["x"]; // azt rja ki, hogy "5"
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.
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 adatok kezelse
307
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
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"
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
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
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.
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
316
16. ra
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.
Az adatok kezelse
317
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.
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
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.
322
17. ra
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
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.
'20' '.4'
Tpusparamter
'd'
Karakterlncok kezelse A 17.2. program a printf() hasznlatval egy termkrlistt hoz ltre.
327
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
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.
330
17. ra
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
332
17. ra
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.
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 "; "
Karakterlncok kezelse
335
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.
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 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
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}
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.
343
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"
346
18. ra
347
18
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.
349
18
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"
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.
351
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.
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.
353
18
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.
356
18. ra
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.
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?
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
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.
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 );
367
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
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
371
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.
373
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
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
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.
377
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?
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
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.
383
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.
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.
385
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.
387
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.
389
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
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.
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
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.
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
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.
397
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
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
21
400
21. ra
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
401
21
402
21. ra
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
404
21. ra
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.
405
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
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.
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.
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.
22
414
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
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.
Nv Mind
Hibk
E_WARNING
Figyelmeztetsek
rtelmez hiba
E_NOTICE
Megjegyzsek
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
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
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.
419
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
422
22. ra
} 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
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.
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.
433
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.
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:
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
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
436
23. ra
?>
<html> <head> <title>Csatlakozs</title> </head> <body> <?php include("kozosnav.inc"); ?> <p> <h1>Csatlakozs</h1>
437
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.
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
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:
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
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.
443
?>
<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
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.
445
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
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.
447
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
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
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
450
23. ra
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.
451
?>
<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
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.
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
454
23. ra
455
23
456
23. ra
457
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.
459
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.
461
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.
463
23
464
23. ra
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
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
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.
471
?>
24
472
24. ra
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
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.
475
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>-.
477
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.
479
?> <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
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.
481
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
482
24. ra
30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47:
483
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
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.
485
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.
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.