You are on page 1of 149

Tanuljunk PHP-l (Fejleszts alatt) Fbin Zoltn 2001-2004 v0.

Tartalomjegyzk
1 BEVEZETS.............................................................................................................................................................5 MIRE J EZ A JEGYZET?.....................................................................................................................................................5 1. 2 A PHP RVID TRTNETE ..........................................................................................................................................5 MI A PHP? .......................................................................................................................................................................6 2 MILYEN RENDSZEREN HASZNLHAT? ........................................................................................................8 2.1.1 2.1.2 3 Milyen opercis rendszer? ...........................................................................................................................8 Milyen WEB szervert? ...................................................................................................................................8

A PHP4 TELEPTSE (WIN32 VLTOZAT) ........................................................................................................9 3.1 KNYVTRAK ....................................................................................................................................................9 3.2 TELEPTS ........................................................................................................................................................10 3.2.1 Apache WEB szerver 1.3.xx vagy 2.0.xx .......................................................................................................10 3.2.2 Internet Information Server 4 vagy 5............................................................................................................10 3.2.3 Personal Web Server 4 vagy jabb (Win98) .................................................................................................11 3.2.4 Szerver nlkli hasznlat: ............................................................................................................................11

4 5 6 7

ESZKZK A PHP HASZNLATHOZ............................................................................................................12 EGY HTML S EGY PHP OLDAL SZERKEZETE ............................................................................................13 A PHP SZINTAKTIKJA......................................................................................................................................14 VLTOZK, ADATTPUSOK..............................................................................................................................15 7.1 7.2 7.3 7.4 7.4.1 7.4.2 7.4.3 7.5 A VLTOZ NEVE .............................................................................................................................................15 A VLTOZ RTKE ..........................................................................................................................................15 A VLTOZK S KIFEJEZSEK TPUSAI ...............................................................................................................15 ELRE DEFINILT VLTOZK ............................................................................................................................17 PHP Core A PHP rendszer alapvet vltozinak a listja..........................................................................17 Environment ................................................................................................................................................17 PHP Variables - A PHP vltozk listja.......................................................................................................17 KONSTANSOK ...................................................................................................................................................18

ALAPVET UTASTSOK ..................................................................................................................................19 8.1 8.2 8.3 ECHO ...............................................................................................................................................................19 FORMZOTT KIRS ..........................................................................................................................................20 A KIIRATS GYAKORLSA .................................................................................................................................21

OPERTOROK (MVELETEK)..........................................................................................................................22 9.1 9.2 9.3 9.4 9.5 9.6 9.7 9.8 9.9 9.10 STRINGEK KZTTI MVELETEK........................................................................................................................22 ARITMETIKAI MVELETEK ................................................................................................................................22 HOZZRENDELS, RTKADS ..........................................................................................................................22 NVEL/CSKKENT OPERTOROK...................................................................................................................22 LOGIKAI OPERTOROK ......................................................................................................................................23 SSZEHASONLT OPERTOROK ........................................................................................................................23 BITORIENTLT OPERTOROK.............................................................................................................................23 HIBAKEZEL OPERTOROK ...............................................................................................................................24 VGREHAJT OPERTOROK ...............................................................................................................................24 GYAKORL FELADATOK....................................................................................................................................24

10

VEZRLSI SZERKEZETEK ..............................................................................................................................25 10.1 10.2 10.3 10.4 10.5 10.6 ELGAZSOK ...................................................................................................................................................25 CIKLUSOK ........................................................................................................................................................27 ELGAZSOK S CIKLUSOK HASZNLATA HTML KDDAL KEVERVE ..................................................................29 PHP LAPOK BESZRSA, MAKRO-K HASZNLATA. ..........................................................................................30 TVOLI FILE-OK HVSA ...................................................................................................................................31 PLDAPROGRAMOK FELTTELEKKEL, CIKLUSOKKAL ..........................................................................................31

11

SAJT FGGVNYEK, VLTOZK LETTARTAMA S LTHATSGA...............................................32 11.1 11.2 11.3 FGGVNYEK ...................................................................................................................................................32 PARAMTERTADS .........................................................................................................................................32 FGGVNYEK VISSZATRSI RTKE .................................................................................................................34

11.4 VLTOZK LETTARTALMA S LTHATSGA ..................................................................................................34 11.5 VLTOZK TADSA LAPOK KZTT ................................................................................................................36 11.5.1 Header utasts.......................................................................................................................................36 11.5.2 GET metdus ..........................................................................................................................................36 11.5.3 POST metdus ........................................................................................................................................37 11.5.4 $_SESSION vltozk ...............................................................................................................................40 Egy session kezel mkdse - plda..........................................................................................................................45 11.5.5 COOKIE-k (stik) ...................................................................................................................................48 12 13 14 15 KONVERZI ADATTPUSOK KZTT............................................................................................................50 TMBK................................................................................................................................................................51 SZTRINGEK, SZVEGEK MANIPULCIJA..................................................................................................55 FORMOK /RLAPOK INTERAKTV PROGRAMOK RSA .......................................................................59 15.1.1 16 17 18 nmagukat meghv rlapok...................................................................................................................59

FORMOK ADATAINAK FELDOLGOZSA SZERVER- S KLIENS OLDALON.......................................61 LEVLKLDS, PLAIN TEXT, HTML LEVL, ATTACHEMENT.................................................................63 ADATBZISOK .....................................................................................................................................................65 18.1 MYSQL ...........................................................................................................................................................66 18.2 POSTGRES SQL ................................................................................................................................................66 18.3 ADATBZIS-KEZELS NATV MDON ..................................................................................................................68 18.4 TIPIKUS FELADATOK ADATBZIS-KEZELSNL ...................................................................................................70 18.5 HIBAKEZELS ...................................................................................................................................................73 18.6 ADATBZISKEZELS MSKPPEN ABSZTRAKCIS RTEGEK, ADODB, ODBC ..................................................73 18.6.1 Az absztrakcis rteg...............................................................................................................................73 18.6.2 ODBC programcsomag...........................................................................................................................73 18.6.3 Az ADODB rtegezs ..............................................................................................................................74 Example 3: Inserting .................................................................................................................................................79 Example 4: Debugging ..............................................................................................................................................79 Example 5: MySQL and Menus..................................................................................................................................80 Example 6: Connecting to 2 Databases At Once.........................................................................................................80 Example 7: Generating Update and Insert SQL .........................................................................................................80 Example 8: Implementing Scrolling with Next and Previous.......................................................................................82 Example 9: Exporting in CSV or Tab-Delimited Format.............................................................................................83 Example 10: Recordset Filters...................................................................................................................................83 Example 11: Smart Transactions ...............................................................................................................................83 18.7 USING CUSTOM ERROR HANDLERS AND PEAR_ERROR...................................................................................85 18.8 DATA SOURCE NAMES ...................................................................................................................................87 18.9 CACHING OF RECORDSETS ............................................................................................................................87 18.10 PIVOT TABLES .............................................................................................................................................87

19

CLASS REFERENCE...........................................................................................................................................91

19.1 GLOBAL VARIABLES......................................................................................................................................91 $ADODB_COUNTRECS...........................................................................................................................................91 $ADODB_CACHE_DIR............................................................................................................................................91 $ADODB_FETCH_MODE........................................................................................................................................91 19.2 ADOCONNECTION ..........................................................................................................................................93 ADOConnection Fields..............................................................................................................................................93 ADOConnection Main Functions...............................................................................................................................94 ADOConnection Utility Functions ...........................................................................................................................105 19.3 ADORECORDSET .........................................................................................................................................107 ADORecordSet Fields .............................................................................................................................................107 ADORecordSet Functions........................................................................................................................................107 function rs2html($adorecordset,[$tableheader_attributes], [$col_titles]).................................................................112 Differences between this ADOdb library and Microsoft ADO...................................................................................113 20 20.1 20.2 DATABASE DRIVER GUIDE...........................................................................................................................114 ID KEZELSE PHP MYSQL ESETN .............................................................................................................115 SOKIG FUT PROGRAMOK .............................................................................................................................116

21

FILE-OK, KNYVTRAK KEZELSE A SZERVEREN S TVOLI URL-EKEN ......................................117

LTOGATK SZMA:<BR> <?PHP .........................................................................................................................120 22 23 24 GRAFIKA .............................................................................................................................................................122 A KRNYEZET FELDOLGOZSA, AZONOSTS ........................................................................................131 BELPTETS, JELSZAVAK ALKALMAZSA, TITKOSTS......................................................................132 24.1 25 26 TITKOSTOTT TVITELE A KLIENS S A SZERVER KZTT: MD5()......................................................................136

BIZTONSG, TIPPEK S TRKKK ..............................................................................................................143 A PHP.INI FILE PARAMTEREZSE..............................................................................................................145

SABLONOK TEMPLATE-EK, LIB-EK....................................................................................................................148 26.1 26.2 27 TEMPLATE-EK, SMARTY ..................................................................................................................................148 PEAR CSOMAG ..............................................................................................................................................148

PHP CACHE PROGRAMOK ..............................................................................................................................149

1 Bevezets
Mire j ez a jegyzet?
A jegyzetnek az a clja, hogy bevezesse az olvast a ma robbansszeren terjed PHP nyelv vilgba, megtantsa az alapvet eljrsokat, fogalmakat s kpess tegye az olvast sajt PHP scriptek rsra. Hasznljuk tovbb a Szily Klmn Mszaki Kzpiskola tdves szmtstechnikai programoz szakn is. Nem teljes PHP dokumentci! Nem is lehet az, hiszen mialatt a jegyzetet megrtam legalbb kt j verzi jelent meg a PHP-bl s folyamatosan bvl a PHP-ben hasznlhat szolgltatsok kre. Igyekeztem arra koncentrlni, hogy egy kezd viszonylag gyorsan elsajtthassa a nyelv alapjait, gyorsan tudjon hatsos programokat rni, s ha valamilyen gyakran elfordul problma megoldsra keres vlaszt, akkor azt viszonylag hamar meg tudja oldani. Teljes dokumentcit az Internetrl lehet beszerezni, rszben magyar nyelven az albbi cmekrl, http://www.php.net dokumentci angolul vagy a http://hu.php.net/docs.php oldal magyarul. A php 4.2.3 verzijtl prblkozva rom ezt a jegyzetet. A jegyzetben tallhat pldaprogramokat, tleteket, rszben az albbi forrsokbl szemezgettem s ezton ksznetet mondok nekik : http://hu.php.net A PHP site magyar oldalai php-lista@Gimli.externet.hu Magyar PHP lista http://php4.x3.hu, Korss Istvn (KI), kefa@mail.datanet.hu PHP-s cikksorozata a PC-World-bl, resource-ok PHP s egyb tmkban http://phpbuilder.com/columns/ying20000602.php3?page=1 sessionok, Ying Zhang cikke http://phpmailer.sourceforge.net Emailklds http://php.weblogs.com/ADODB ADODB adatbziskezels Molnr Lszl A Postgres SQL teleptse Smarty felhasznli kziknyv http://Smarty.php.net Smarty template rendszer s a dikjaim is.

1. 2 A PHP rvid trtnete


A PHP trtnete 1994 szre nylik vissza, amikor a munkt keres Rasmus Lerdorf egy Perl CGI szkriptet hasznlt a Web odalt felkeresk regisztrlsra. A ltogatkat naplz kdot "PHP-tools for Personal Home Page"-nek nevezte el. Az els nyilvnos vltozat gy 1995 tjn ltott napvilgot. Ez mg csak nhny egyszerbb feladatra volt hasznlhat, tbbek kztt szmllt, vendgknyvet tartalmazott. A PHP fejlesztse a Toronti Egyetemen folytatdott, ahol Rasmus Lerdorf olyan interfszt fejlesztett ki, aminek segtsgvel a HTML kdba gyazott specilis utastsok kzvetlenl rtk el az egyetemi adatbzisokat. A rendszert Rasmus "Form Interpreter"-nek, FI-nek nevezte el. Az FI-ben hasznlt elv mr megegyezett a PHP alapelvvel, miszerint a HTML kdba begyazott utastsokat rtelmezte s 5

hajtotta vgre az FI rtelmezje. Ksbb a PHP s az FI sszehzastsbl szletett meg az els szles krben hasznlt parancsrtelmez a PHP/FI. Ez tartalmazta a PHP s az FI addigi szolgltatsait, st az mSQL adatbzisok elrst is tmogatta. Rasmus eleinte eljtszadozott a gondolattal, hogy a PHP-t kereskedelmi termkk teszi, de olyan komoly mennyisg visszajelzst kapott ms programozktl, klnbz kiegsztseket s hibajavtsokat kldve a PHP-hez, hogy letett ebbli szndkrl. A PHP fejldshez s sokrtsghez nagymrtkben hozzjrult kls programozk szabad s ingyenes rszvtele a rendszer fejlesztsben. A PHP a mai napig is ingyenes termk, s ez valban nagyon j dolog. Az els verzi megjelenstl kezdve a PHP felhasznli tbora tretlenl nvekedett. 1996-ban kzel 15.000 Web oldalon hasznltk a PHP/FI-t, 1997-ben mr tbb mint 50.000 Web oldalon. Ebben az vben kezddtt el a PHP sokkal jobban szervezett tovbbfejlesztse. A PHP/FI-t rtelmezjt szinte az alapoktl kezdve jrartk, temelve a PHP/FI-ben alkalmazott technikkat s kdot, de szmos jat is hozztve. gy alakult ki a PHP 3-as vltozata, ami gyakorlatilag rendelkezett mindazokkal a kpessgekkel, amik a PHP npszersgt megalapoztk. A PHP fejldse azonban nem ll meg. Jelenleg a 4.0.6 vltozatnl tart a fejleszts, de ksznheten a "szabad szoftver" filozfinak nem valszn, hogy itt megreked. A magyar PHP lista az elmlt vben indult, napi 2-3 levllel, egy v alatt napi 30-50 levlre duzzadt a forgalma.

Mi a PHP?
Egy programozsi nyelv. A PHP majdnem ltalnos cl programozsi nyelv, amely mra sokfle terleten alkalmazhat, amit a Weben keresztl meg lehet oldani. Dinamikus oldalak, adatbzis-kezels, akr gyviteli alkalmazsok, levelezs, portlok, grafikai alkalmazsok, file-kezels, tvoli adminisztrci, stb. Mieltt a PHP mkdst rszleteznnk, meg kell ismerkedni egy kicsit a Web-en lv alkalmazsok lelkivilgval. Amikor a bngszben berjuk egy olyan oldal nevt, s letltjk azt, akkor az Interneten lv WEB szerver kldi el a bngsznknek a kvnt oldalt. Ez az oldal egy HTML oldal, egy ASCII szveg llomny, amely megrkezve a bngsznkre azt a bngsz rtelmezi, s a tartalmt megjelenti. Az ilyen oldalakat statikus oldalaknak hvjuk, mivel a kvetkez s az utna kvetkez krsekkor mindig pontosan ugyanazt az oldalt fogjuk jra meg jra megkapni, hiszen a szerveren ez egy file. Abban az esetben, ha azt szeretnnk, hogy az oldal tartalma vltozzon, azaz dinamikus oldalt szeretnnk, valamilyen mdon az oldalt a szerveren ltre kell hozni, mdostani kell. Ennek rdekben ki kell egszteni a WEB-szervert olyan alkalmazsokkal, amelyek az oldal krsekor futskor lltjk el az oldalt, majd odaadjk a szervernek, amely az eredmnyt tovbbtja a bngsz fel. Ezeket a programokat sszefoglal nven CGI programoknak hvjuk, ami a Common Gateway Interface kifejezs rvidtse. Ezek a programok teht j funkcionalitssal bvtik ki a WEB szervereket. A legfontosabb ebben az, hogy ez ltal a bngszk interaktv mdon tudnak kapcsolatot teremteni a WEB szerverrel, adatokat tudnak bevinni neki, a bevitt informci alapjn vltozik a visszaadott rtk. Az ilyen rendszer mkdse olyan, hogy a bngszben bert informcit megkapja a WEB szerver, tadja a CGI programnak, ami az informci birtokban feldolgozza s visszakldi a WEB szervernek, amely tovbbtja a bngsz fel HTML kd formjban. A CGI programok vagy a szerver opercis rendszern futni kpes programok, amelyeket valamilyen nyelven, pl. C-ben rtak meg s fordtottak le, vagy gynevezett scriptek, amelyek egy rtelmez program kzremkdsvel futnak. A PHP programokat egy ilyen rtelmez futtatja a szerveren akkor, ha a bngsz PHP, PHP3, PHP4, vagy hasonl kiterjeszts file-okra hivatkozik. Ekkor a WEB szerver meghvja a PHP rtelmez programot (interpretert), amely rtelmezi a krdses oldalt, majd az eredmnyt Web oldal formjban visszaadja a WEB szervernek, amely tovbbtja a bngsznek.

Teht a PHP program egy WEB szerveren fut script, amelynek az eredmnye egy WEB bngszn keresztl jelenik meg. Ha valaki mr tallkozott HTML oldalakon Javascriptekkel, vagy Vbscriptekkel, akkor lehet fogalma arrl, hogy mirl is van sz, ugyanakkor lnyeges klnbsg van a ktfle megolds kztt. Mg a Javascriptek s a Vbscriptek a bngszn hajtdnak vgre, addig a PHP scriptek a szerveren. Ennek tbb elnye van, pldul sokkal bonyolultabbak lehetnek, el lehet rejteni a tartalmukat a kvncsi tekintetek ell, nincsenek a bngsz kpessgeihez ktve. A PHP script a bngszn soha nem jelenik meg (ha megjelenik, akkor baj J), csak az a HTML vagy egyb kd, amelyet elllt. A bngsz krse nyomn a PHP rtelmez megkapja az oldal helyt, nevt s az esetleges bemen paramtereket valami.php Bngsz WEB szerver valami.php PHP rtelmez

A kvnt oldalt betlti az rtelmez, feldolgozza, s az eredmnyt visszakldi HTML kd Bngsz WEB szerver HTML kd PHP rtelmez valami.php

A PHP rtelmez a fejldse sorn egyszer script futtat programocskbl komoly fejleszteszkz lett.

2 Milyen rendszeren hasznlhat?


2.1.1 Milyen opercis rendszer?
Gyakorlatilag ltezik az sszes elterjedt opercis rendszeren, Win32, Linux, Solaris, BSD, hogy csak a legismertebbeket rjk le. Ezeken a rendszereken fut sok-sok WEB szerver segtsgvel lehet futtatni. Gondolva a tanulsra s az ltalban meglv szmtstechnikai krnyezetre a Windows 98, ME, NT, W2000 opercis rendszert ajnljuk. Magyarzat: Mirt nem LINUX? Azok rszre, akik most tanuljk a nyelvet nem clszer olyan rendszert hasznlni, amelynek nem ismerik elgg a tulajdonsgait. Az oktatsban elssorban Windowsos rendszereket hasznlnak.

2.1.2

Milyen WEB szervert?

A PHP teleptse eltt mindenkppen szksgnk lesz egy mkd WEB szerverre. Nyilvn most nem az a feladatunk, hogy egy WEB szerver teleptst bemutassuk, de ha a Windows NT-t hasznljuk s a Service Pack 5-t felteleptettk, akkor lesz IIS4-nk. A Windows 2000 alatt eleve a rendszer rsze, Win9x alatt pedig a Personal WEB Servert hasznlhatjuk alaprtelmezetten. Ennek ellenre mi az Apache WEB szervert ajnljuk, annak egyszer teleptse, egyszer belltsa miatt. Megjegyezzk, hogy az Apache belltsa majdnem ugyanaz LINUX alatt s Win32 alatt is, teht ennek a rendszernek a hasznlatakor nagyon kis klnbsgek kellenek a LINUX-os verzira val tllshoz. A ksbbiek sorn bemutatunk egy olyan sszelltst is, amellyel egyszerbb PHP programokat tudunk futtatni WEB szerver nlkl is, Win9x, ME, NT, W2000, XP rendszeren! n Windows 2000 s Apache 1.3.xx valamint Windows XP s Apache 2.0.xx rendszerrel is hasznlom. Hol tallok szolgltatt, aki futtat PHP scripteket, esetleg adatbzist? Az utbbi idben tbben is vllalkoznak erre a szolgltatsra. Jelenleg tudomsom szerint a kvetkez szolgltatk hajlandk futtatni ingyen php-t: http://www.f2s.com ingyen PHP, MySQL, PostGres SQL http://www.swi.hu pnzes szolgltat

3 A PHP4 teleptse (Win32 vltozat)


A PHP teleptse opercis rendszerenknt s WEB szerverenknt ms s ms. A teleptsrl tovbbi informci a http://hu.php.net s a http://www.php4win.de oldalakon tallhat. A PHP csomagot letltve kapunk egy tmrtett llomnyt, amelyet kibontva az albbi knyvtrstruktrt kapjuk.

3.1

Knyvtrak

browscap: A browscap.ini file-t tartalmazza. Ez a file az egyes bngsztpusok adatait, tulajdonsgait tartalmazza. dlls: Itt olyan dll-ek vannak, amelyekre a php-nek s nhny kiterjesztsnek van szksge. Ezeket msold be a windows/system (Win9.x) vagy a winnt/system32 (Windows NT, Win2000) knyvtrba. Ha ezek lteznek mr az adott helyen, csak akkor rd fell a rgieket, ha a rendszer nem mkdik. extensions: A php kiterjesztseit tartalmaz knyvtr. keys: Az mcrypt-hez kulcsok. Az mcrypt mg nem mkdik. licenses: Tbb licence-et tartalmaz. mibs: Az SNMP hasznlata esetn szksges. pdf-related:Az itt lv fontok a PDF kiterjeszts hasznlathoz kellenek. Olvasd el az ezzel kapcsolatos licence-t. pear: readme: sapi: The pear archive captured at the build date. Readme file-ok klnbz tmkban Natv server api-kat tartalmaz. Az ajnlott a CGI verzi. Ezen kvl vlaszthatod mg ezeket: - php4-module a win32 Apache szerver sapi-ja, - ISAPI - az IIS4/5 sapi-ja, - NAPI - a netscape enterprise server s a php4 servlet verzija A PHP mkdsnek tesztelshez hasznlhat program van itt.

tests:

A PHP rtelmez ltalban a C:\PHP\PHP.EXE program, amelynek manapsg Windows NT/W2000/XP krnyezetben a \WINNT\SYSTEM32\PHP\PHP.EXE helyet ajnljk, de n nem ide teszem. Szerintem az utlagos frisstsek miatt clszer valamelyik meghajt gykerbl nyl knyvtrba tenni, pldul C:\PHP. A PHP konfigurlshoz szksg van egy PHP.INI nev file-ra, amelynek a Windows knyvtrba kell kerlnie. Ennek a file-nak a mintja php.ini-dist nven a PHP knyvtrban tallhat teleptskor. A megfelel sorokat trva van egy mkd konfigurcink. A ksbbiek sorn megnzzk, hogy milyen vltoztatsok szksgesek a PHP.INI-ben, a gyorsabb mkds rdekben.

3.2

Telepts

Mindenekeltt csomagold ki a PHP-t a C:\PHP knyvtrba, majd msold a php4ts.dll-t a C:\WINDOWS\SYSTEM vagy a C:\WINNT\SYSTEM32 knyvtrba! Msold a php.ini-dist file-t a rendszer gykrknyvtrba, ahol a Windows van, majd nevezd t PHP.INIre. Szerkeszd t a PHP.INI-t, szksg szerint (a ksbbiekben bemutatjuk, hogy mit rdemes tszerkeszteni).

3.2.1

Apache WEB szerver 1.3.xx vagy 2.0.xx

1. Teleptsd az Apache szervert. Ez a teleptt tartalmaz MSI file vagy az .EXE kiterjeszts file esetn az nkicsomagol file futtatst jelenti. 2. lltsd le az Apache Webszervert. 3. Az Apache szerver konfigurcis llomnya pldul az C:\Apache\conf\httpd.conf file. Szerkeszd meg ezt a file-t, az albbi mdon: Apache modul esetn:
# Apache modul esetn LoadModule php4_module c:/php/sapi/php4apache.dll AddType application/x-httpd-php .php4

Msold be a \Winnt\system32 vagy a \windows\system knyvtrba a php4ts.dll file-t CGI modul esetn:
#for the cgi binris esetben ScriptAlias /php4/ "C:/php/" Action application/x-httpd-php4 "/php4/php.exe" AddType application/x-httpd-php4 .php

Sajnos jelenleg az Apache modul nem fut a 2.0.xx-es verziban. 4. Keresd meg a DirectoryIndex parancsot a konfigurcis llomnyban s egsztsd ki az albbi mdon
DirectoryIndex index.html index.php index.php3 index.php4

5. Indtsd jra az Apache szervert, 6. rd meg a kedvenc ASCII editorod segtsgvel az albbi tartalm scriptet, mentsd el a szervered gykrknyvtrba, majd hvd meg a bngszben az albbi mdon:
<?php echo phpinfo(); ?>

7. Prbld ki az albbi programocskt a Bngszddel a szervered root knyvtrbl:


http://localhost/proba.php

Ennek hatsra lefut a script s kirja a bngszdbe az ppen hasznlt php rendszer rengeteg paramtert.

3.2.2

Internet Information Server 4 vagy 5

Indtsd el a Microsoft Management Console-t vagy az Internet Services Manager-t, a Control Panelrl. Kattints a Webszerverre s vlaszd a properties-t. Ha nem akarsz HTTP Authentication-t hasznlni a PHP-vel, akkor tlpheted ezt a lpst. Az ISAPI Filters (ISAPI szrk) alatt add hozz az j ISAPI szrt. Hasznld a PHP nevet a szr nevnek, majd keresd meg az php4isapi.dll-t, a C:\PHP\sapi\php4isapi.dll tvonalon. 10

A Home Directory alatt, kattints a Configuration (Konfigurci) gombra. j bejegyzst kell felvenni, az Application Mapping-be (Alkalmazsok Hozzrendelse). Hasznld a C:\php\sapi\php4isapi.dll-t s lltsd Executable-re (Futtathat), .php legyen a kiterjeszts, Method exclusions-nl lltsd be az engine checkbox-ot. lltsd le az IIS-t. Indtsd jra. az IIS-t rd meg a kedvenc ASCII editorod segtsgvel az albbi tartalm scriptet, mentsd el a szervered gykrknyvtrba, majd hvd meg a bngszben az albbi mdon:
<?php phpinfo(); ?>

localhost/s prbld ki az albbi programocskt a Bngszddel a szervered root knyvtrbl:


http://localhost/proba.php

Ennek hatsra lefut a script s kirja a bngszdbe az ppen hasznlt php rendszer rengeteg paramtert.

3.2.3

Personal Web Server 4 vagy jabb (Win98)

Szerkeszd meg a csomagban lv PWS-php4isapi.reg (ISAPI interface) file-t vagy a PWSphp4cgi.reg (CGI interface) file-t, hogy arra knyvtrra mutasson, ahol a php4isapi.dll / php.exe tallhat. Pl.
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w3svc\parameters\ScriptMap]".php"="C:\\PHP\ \php4isapi.dll"

A PWS Manager-ben jobb egrrel kattintva, a megfelel knyvtrhoz add hozz a PHP support-ot (tmogats), vlaszd a Properties-t (Tulajdonsgok). lltsd be az 'Execute' vgrehajthat tulajdonsgot.

3.2.4

Szerver nlkli hasznlat:

Bontsd ki a C:\PHP knyvtrba a csomagot. Az albbi batch file-t ksztsd el, a megfelel tvonalakkal
C:\php\php.exe %1 >%Temp%\phptemp.htm C:\Progra~1\Intern~1\iexplore %Temp%\phptemp.htm

A batch file-t paramtere a php file legyen. A msodik sorba az ltalad hasznlt bngsz elrst kell berni rd meg a kedvenc ASCII editorod segtsgvel az albbi tartalm scriptet, mentsd el a szervered gykrknyvtrba, majd hvd meg a bngszben az albbi mdon:
<?php phpinfo(); ?>

Hvd meg a megrt batch file-t az albbi mdon:


Test.bat proba.php

Ennek hatsra lefut a script s kirja a bngszdbe az ppen hasznlt php rendszer rengeteg paramtert. A CGI verzi stabilabb a Windows rendszerekben, az ISAPI verzik alkalmanknt sszednthetik a rendszert. 11

4 Eszkzk a PHP hasznlathoz


Felmerl a krds, hogy mi kellhet a PHP hasznlathoz a fentieken kvl. A vrakozssal ellenttben nem sok, de azrt itt sszefoglalom a lehetsgeket: Kell egy ASCII szvegszerkeszt, kezdetben j a NOTEPAD.EXE a Windowsbl is. Ha ennl komolyabbra vgysz, akkor vlaszd mondjuk az EditPlus nev editort, amely a http://www.editplus.com cmrl tlthet le. Szmozza az oldalakat, s mg a szintaktikt is sznezi. Ezen kvl sok ms hasonl editor van forgalomban. A nagyok kzl tudnm ajnlani a Macromedia Dreamweaver Ultradev 4 vagy a Dreamweaver MX csomagot is. Nem rt, ha van egy j HTML editorod, mert a php oldalak jelents rszben azrt HTML kdbl is llnak. A freeware vagy shareware programok kztt jelents vlasztk van, pl. CoffeCup. Kell egy bngsz, ami adott az jabb Windows-okban Internet Explorer 4/5/6. Hasznlhatod a Netscape Navigator-t (www.netscape.com), illetve az Opera legjabb vltozatt is. Taln ez utols a legkisebb s leggyorsabb. Az opera letlthet a www.opera.com -rl. Szksged lesz egy j Help-re. n a http://hu.php.net/docs.php oldalrl a CHM (Windows-os Help file) vltozatot javaslom, de hasznlhatod a HTML verzikat is, s ha gyors Internet kapcsolatod van, akkor a Internetrl is lehet online mdon hasznlni ket. Nem rt, ha a HTTP-rl is van egy j Help-ed. A http://www.htmlhelp.com/ -rl letlthet tbbfle formban, kztk Windows-os Help formjban a HTML nyelv szintaktikja. Nem ide tartozik, de gyakori, hogy a php scripteket vegytjk Javascriptekkel is. Erre a clra tbb forrs ltezik, de sajnos magyar nyelven s Windows-os Help formjban nem tudok rla: Taln clszer a kvetkezt Web oldalt hasznlni http://weblabor.hu/leiras/javascr/ vagy megnzni az albbi oldalt: http://www.szily.sulinet.hu/jegyzetek Letlthet llapot vltozat az ftp://ftp.szily.sulinet.hu/jegyzetek/Javascript/ knyvtrban tallhat. Szksg lehet egy j HTML/ Javascript knyvre, pldul Bcz Pter Szsz Pter: A vilghl lehetsgei

12

5 Egy HTML s egy PHP oldal szerkezete


Mieltt tovbbmennnk nzzk, mit akarunk programozni? Hogyan is nz ki egy HTML oldal:
<HTML> <head> <TITLE>Proba web oldal</TITLE> </head> <BODY> <P> Hello World!!! </P> </BODY> </HTML>

Na ez nagy durrans volt. A bekezdses rsmdot az ttekinthetsgrt hasznlok, de mint ltjuk ksbb, ez rendkvl fontos! A bngszk a sor vge jelet, a szkzket s a tabultor jeleket kihagyjk, ezrt akr az egszet egy sorba is rhatnnk. A fenti HTML oldalt az albbi php scripttel tudjuk elllttatni:
<HTML> <head> <TITLE>Proba web oldal</TITLE> </head> <BODY> <P> <?php echo Hello World!!!; ?> </P> </BODY> </HTML>

Tisztn ltszik, hogy a program szerkezete nagy vonalakban ugyanaz, de azrt vannak klnbsgek. A PHP rtelmez a kd els sorait vltozatlanul tovbbtja a Web szervernek, de amikor a <?php taghez r, rtelmezi az ott lv sorokat, s az echo paranccsal kirja a Web szerver fel az echo utni szveget. A kvetkez sorban lv ?> tag jelzi az rtelmeznek a PHP script vgt. Egy oldalon tbbszr is megnyithatjuk a scriptet s bezrhatjuk, azaz keverhetjk a php s a HTML kdot, st ha van mersznk, akkor beiktathatunk javascriptes rszeket is. Az albbi lehetsgeink vannak arra, hogy php scriptet helyezznk el egy oldalon:
<?php ..............php kd .............?> <script language=PHP> ..... php kd ...</script>

Ha berjuk a PHP.INI-ben, a short_open_tag= on sort, akkor ez a megolds is lehetsges:


<?..... php kd ....?>

Ha berjuk a PHP.INI-be az asp_tags = on sort, akkor hasznlhat az albbi szintaktika is:


<% ..... php kd ........%>

Specilis lehetsg. Ha egy vltoz rtkt szeretnnk csak kiiratni s a short_open_tag = on sor be van rva, akkor egy vltoz rtkt gy adhatjuk t a web oldalnak legegyszerbben:
<?=$valtozo ?>

13

6 A PHP szintaktikja
A PHP nyelv szintaktikja nagyon hasonlt a C nyelvre, ezrt sokak szmra nem lesz tlsgosan idegen. A php scriptben lv utastsok mindegyike utn ktelezen ki kell tenni a ; elvlasztjelet. Megjegyzs: Br a dokumentci azt mondja, hogy egy zr tag eltt nem kell kitenni, azrt azt tancsolom, hogy megszoks cljbl mindenhol alkalmazzuk A Megjegyzseinket szintn C jelleg szintaktikval ktflekppen tehetjk ki: // # Az egysoros kommentek, a sor vgig tarthatnak, mint a C-ben jellel, mint a Unixos shell programoknl A tbb soros kommentek

/*...................................*/

<?php echo "Ez egy teszt"; // Ez egy egysoros c++ szer komment /* Ez egy tbbsoros komment Mg egy sor komment */ echo "Ez egy msik teszt"; echo "Ez az utols teszt"; # Ez egy shell-szer komment ?>

Amint ltjuk a fentiek alapjn a kirand szveget jelek kz tehetjk, de a jelpros lehet ... is. A tovbbiakban nzzk meg, hogy milyen tpus rtkekkel dolgozhatunk.

14

7 Vltozk, adattpusok
A PHP-ben hasznlhatunk vltozkat is. A vltoz neve eltt mindig $ jel tallhat.

7.1

A vltoz neve

A vltoz neve betvel vagy alhzs jellel kezddik s brmilyen alfanumerikus karakterrel, illetve 127...255 ASCII kd karakterrel folytatdhat. A kis s nagybetk klnbznek!

7.2

A vltoz rtke

Amikor elszr adunk rtket egy vltoznak, akkor jn ltre a vltoz.


$a = 5; $todo = szveg;

Ha egy vltoz rtkt azeltt vizsgljuk meg, mieltt rtket adunk neki, az rtke NULL lesz. Egy vltoz tpust tbbflekppen lehet meghatrozni. rtket adunk neki, az rtk alapjn ltrejtt vltoznak a tpusa is egyrtelmv vlik. Belltjuk a tpust a settype (vltoznv, tpus) paranccsal, ahol a tpus az albbiak kzl vlaszthat: "integer", "double", "string", "array", "object" Tpuskonverzit alkalmazunk. Az alkalmazhat tpusok ugyanazok, mint a fenti pldban, hozzvve, hogy az integer lehet int is, a double lehet float s real is.
$a = (int) $b $c = (string) $d

A vltozk rtkadsakor hasznlhatunk hasonl trkkket, mint a C-ben:


$a = $b = 5

A fenti kifejezst gy kell rtelmezni, mintha az albbiakat rtuk volna le:


$b = 5; $a = b;

A ksbbiekben foglalkozunk rszletesen az opertorokkal, amelyek egy vltoz rtkt meghatrozzk. A vltoznak brmilyen mdon rtket adtunk, akkor a tpust is meghatroztuk.

7.3

A vltozk s kifejezsek tpusai

A klnbz programozsi nyelveken megszokott tpusok a PHP-ban is megtallhatk: Numerikus tpusok: int, integer - egsz tpus rtke 32768-32767-ig tart Float, double, real Lebegpontos String A C-ben hasznlt string fogalomhoz hasonl, ... vagy .... jelek kz rt ASCII karaktersorozat. Array Tmb tpus. A tmb elemi tetszlegesen vegyesek lehetnek Egy tmb lehet egy, kt s tbb dimenzis tmb is. A tmb indexelse trtnhet hagyomnyosan 0-tl kezdd indexelssel, vagy lehet gynevezett asszociatv tmbt is ltrehozni, amikor a tmbindex valamifle string, vagy egyb rtk. Ebben a pldban egy dimenzis tmbt hozunk ltre.
$array = array (1, "hello", 1, "world", "hello");

15

Az albbi pldban ktdimenzis asszociatv hozunk ltre.


$fruits = array ( "fruits" => array ("a"=>"orange", "b"=>"banana", "c"=>"apple"), "numbers" => array (1, 2, 3, 4, 5, 6), "holes" => array ("first", 5 => "second", "third") );

Object - Objektum. A tpus hasonlt a C++ objektumaira, de vannak lnyeges klnbsgek is. Egy objektum tpus vltoz ltrehozshoz elszr definilni kell magt az osztlyt a class kulcsszval, hasonlkppen, mint C++ -ban, majd a definci utn a new() opertorral ltre lehet hozni a megfelel vltozt. A class rszt kpezik vltozk s a classhoz tartoz fggvnyek is. A ksbbiekben rszletesen is szlunk az objektumokrl. Az albbiakban egy pldt ltunk.
<?php class Kosar { var $dolgok;

// A kosrban lev dolgok

function berak ($sorsz, $db) { // berak a kosrba $db darabot az $sorsz index dologbl $this->dolgok[$sorsz] += $db; } function kivesz ($sorsz, $db) { // kivesz a kosrbl $db darabot az $sorsz index dologbl if ($this->items[$sorsz] > $db) { $this->items[$sorsz] -= $db; return true; } else { return false; } } } $a = new Kosar; ?>

boolean Logikai rtkek. Kt rtk elre definilt, a TRUE s a FALSE null - Olyan vltozk, amelyeknek nincsen belltott rtkk Resource Erforrsok, mint pldul file vagy adatbziskezel mutatja. Valjban ezek a memria egyes helyre mutat pointerek! Unknown type - Ismeretlen tpusok Vltozk s kifejezsek visszatrsi rtknek tpust le lehet krdezni az albbi fggvnyekkel:
int empty ($a) string gettype ($a)

Megadja, hogy a vltoz res volt-e vagy nem. Visszaadja a vltoz tpust. A lehetsges tpusok az albbiak: "integer", "double", "string", "array", "object", "unknown type" Belltja egy vltoz tpust. A lehetsges tpusok ($type) lehet: "integer", "double", "string", "array", "object" Visszaadja a vltoz rtkt egssz konvertlva a megadott alap szmrendszerben. Az alap default rtke 10. Megadja, hogy a vltoz tmb vagy sem Megadja, hogy a vltoz logikai tpus vagy sem Megadja, hogy a vltoz lebegpontos-e, vagy sem.

void settype($var,$type)

int intval($a,[$alap])

int is_array($a) int is_bool($a) int is_float ($a) int is_double ($a)

16

int is_real ($a) int is_long ($a) int is_integer ($a) int is_int ($a)

Megadja, hogy a vltoz egsz vagy sem. Megadja, hogy a vltoz numerikus, numerikus szveg vagy sem. Megadja, hogy a vltoz objektum vagy sem Megadja, hogy a vltoz erforrs azonost vagy sem (pl. file handler) Megadja, hogy a vltoz string vagy sem. Megadja, hogy be van-e lltva a vltoz. A visszatrsi rtke hamis, ha nem s Igaz, ha van rtke a vltoznak Ember szmra olvashat informcit ad egy vltozrl.
<?php $a = array (1, 2, array ("a", "b", "c")); print_r ($a); ?>

int is_numeric ($a) int is_object ($a) int is_resource ($a) int is_string ($a) int isset (vltoz)

void print_r(kifejezs)

7.4

Elre definilt vltozk

A vltozk kztt vannak olyanok, amelyek a rendszerben elre definiltak. Ezeknek a vltozknak a nevt s pillanatnyi rtkt a phpinfo() fggvny segtsgvel lehet kiratni. A vltozkra hivatkozva termszetesen az rtkeket fel tudjuk hasznlni, s azt tudjuk manipullni. Ezen vltozknak az rtkt a PHP.INI file-ban lehet belltani, nhny rtk a hasznlt WEB szervertl fgg, tovbbi rtkek pedig a futtat opercis rendszertl fggnek. A vltozk msik nagy csoportjai a rendszerben alkalmazott modulok rtkei. Nhny fontosabb vltoz csoport

7.4.1 7.4.2

PHP Core A PHP rendszer alapvet vltozinak a listja Environment

A rendszer belltsait, s alaprtelmezett paramtereit tartalmaz vltozlista. Az opercis rendszerrl, a krnyezeti belltsokrl, a WEB szerverrl, a bngszrl, az aktulisan meghvott laprl s a kliensrl minden lnyeges adatot felsorol, belertve az IP cmeket is.

7.4.3

PHP Variables - A PHP vltozk listja

Tovbbi gyakran hasznlt vltozk tmbjei a szerver ltal szolgltatott tmb s a


$_SERVER[PATH]

A krnyezeti vltozk
$HTTP_ENV_VARS vagy $_ENV[valtnev]

Formok kezelsnl hasznlhat vltozk listja a GET metdussal elkldtt vltozk listja s rtkei
$_GET[valtnev]

Post metdussal elkldtt vltozk listja s rtkei


$_POST[valtnev]

17

Sessionokben hasznlt vltozk listja s rtkei


$_SESSION[valtnev] $GLOBALS[valtnev ]

a szupergloblis vltozk. Brhol elrhetk az rtkei


$_COOKIE[valtnev]

A PHP 4.1.0-tl ez a szupergloblis tmb is ltezik A HTTP protokollban definilt tovbbi vltozk. Ezek kzl a vltozk kzl nhny megtallhat a krnyezeti vltozk kztt is. A szerver IP cme
Echo $REMOTE_ADDR

a szerver neve
$REMOTE_HOST

a lekrt oldal azonostja


$HTTP_REFERER

a szerverhez kapcsold bngsz fajtja, az opercis rendszer fajtja


$HTTP_USER_AGENT

a WEB oldalnak tadott paramtersztring (a.php?A=proba)


$QUERY_STRING

Az aktulisan futtatott PHP oldal azonostja:


$_SERVER["PATH_TRANSLATED"]

A szerveren lv WEB szerver gykrknyvtra


$_SERVER["DOCUMENT_ROOT"]

Az albbiakban egy pldt mutatok be a fenti vltozk hasznlatbl: A pr sort beszrva egy script elejre ellltja konstans formban az aktulisan fut script elrsi tvonalt, tovbb a WEB szerver dokumentumainak elrsi tvonalt.
$path=dirname($_SERVER["PATH_TRANSLATED"]); DEFINE("PATH",$path); DEFINE("DOCROOT", $_SERVER["DOCUMENT_ROOT"]);

7.5

Konstansok

A PHP-ben vannak elre definilt konstansok, tovbb mi is definilhatunk a


define(nev, rtk) parancs segtsgvel.

Az elre definilt konstansok kzl nhny:


_FILE_ _LINE_ PHP_VERSION PHP_OS TRUE, FALSE

az ppen futtatott file neve az ppen fut programsor a futtatott rendszer verziszma a futtat opercis rendszer logikai rtkek

18

8 Alapvet utastsok
Aki a Pascal nyelven nevelkedett megszokta, hogy a definicis s a vgrehajthat utastsoknak kttt sorrendje van. A C nyelv s tbbek kztt a PHP tartalmaz elrsokat az utastsok sorrendjre, de azok nem annyira ktttek, ezrt aztn nagyon knny ttekinthetetlen s rosszul mkd programot rni bennk. Ahhoz, hogy gyorsan tudjunk egy programot rni, ismertetnk nhny utastst.

8.1

Echo

A PHP egyik leggyakrabban hasznlt utastsa az echo. Segtsgvel a bngszbe ki lehet rni a program futsnak eredmnyt. A kirats sorn gondolnunk kell arra, hogy az eredmny egy HTML kd mindig, amit majd a bngsz tovbb rtelmez. Az egyms utn r echo parancsok az eredmnyt egyms utn rjk ki a kimenetre, pozicionls, visszalps a szvegben nem lehetsges. Ha a kirs utn j sorban szeretnnk kezdeni a kirst, akkor a HTML szerint egy <BR> tag-et (soremels) vagy kell kirni. Az albbiakban tbb soros kirst alkalmazunk:
<?PHP echo Szevasz tavasz<BR>; echo Mit stsz kis szcs?<BR>; ?>

A numerikus eredmnyek kirsra is hasznlhatjuk ezt az utastst, azonban formtumozni nem tudjuk a kimenetet gy.
<?PHP $a = $b = echo echo ?> 5; 6; $a + $b; Mit stsz kis szcs?<BR>;

Tovbbi problma, hogy mi van akkor, ha numerikus informcit s string-et akarunk egy szvegben kirni. A feladat megoldshoz ugyanazt kell hasznlnunk, mint amikor kt string-et akarunk sszefzve kirni.
<?PHP $a = 5; $b = 6; echo Az eredmny: .$a + $b; $sz = Tn ss hst stsz kis szcs?; echo Mit stsz kis szcs?.$sz.<BR>; ?>

A fenti pldban az echo parancs az sszeads mvelett string-g konvertlta s gy ratta ki. A konverzi teljesen automatikus. Tovbbi rdekes lehetsg, amikor egy string-ben szeretnnk kiratni egy vltoz rtkt:
<?php $o = 5 + 6; Echo Az eredmny: $o<BR>; ?>

Amint ltjuk, a korbbi megfontolsok alapjn a soremelst a HTML szerint kell hasznlnunk. Az albbiakban nhny gyakran hasznlt tag-et runk le. A hasznlhat tag-ek trt egy HTML kdolssal foglalkoz knyvbl, jegyzetbl vagy Internet helyrl meg lehet tudni. A kpernyn val soremelsre a <BR> tag szolgl. Vzszintes vonal rsra <HR> Paragrafus eleje, vge: <P> ....</P> Vastag bet <B> ....</B> 19

Dlt bet <I> ....</I> Tblzat ltrehozsraLaz albbi plda egy soros, kt oszlopos tblzatot hoz ltre)
<table> <tr> <td> <td> </tr> </table>

<P> els oszlop</p> </td> <P> masodik oszlop</p> </td>

Stb.... Mivel a fenti TAG-ek sztringek, ezrt clszeren az echo paranccsal kell kiiratnunk ket. Az echo egy nyelvi elem s nem fggvny, azaz valami olyasmi, mintha C-ben egy fggvnymakrt hoznnk ltre. ppen ezrt bonyolultabb kifejezsek kiiratshoz alkalmatlan! Ha az adatokat formzottan szeretnnk kirni, akkor a printf parancsot kell hasznlni

8.2
print()

Formzott kirs
Ugyanaz, mint az Echo, csak a szintaktika kiss ms. kiirats formzottan formzott sztringet ad vissza az albbi szintaktika szerint:

printf()

sprintf()

string sprintf (string formtum [, mixed paramterek...]) A fromtum szerint megadott karaktersorozattal tr vissza. A formtumkarakterek lnyegben a C-ben megszokott formtumkarakterek. A formtumstring tbb direktvt tartalmazhat. A % string vezeti be a direktvkat, majd utna kvetkeznek a formz karakterek. Ezeken kvl minden karakter megjelenik a kimeneten. A kimenet konverzis parancsait a printf() s az sprintf() parancsban ugyangy lehet hasznlni. A konverzis parancssorozat az albbi parancsokat tartalmazza: Opcionlis kitlt karakter. Ezzel lehet a stringet megfelel mretre kitlteni. Default rtke a szkz. Ezen kvl lehet a 0, vagy egyb karakter. Igazts karakter. Az eredmny balra vagy jobbra igaztott lesz. A default a jobbraigazts; a karakter igaztja balra. Szlessg meghatroz. Megmondja, hogy minimum hny karakter legyen az eredmnyben. A tizedes jegyek szma. Csak a double formtum esetn hatsos. (A szmformtumokat number_format() fggvnnyel tudjuk mg jl kezelni.) A tpusmeghatroz megmondja, hogy milyen tpus adatokat kell kezelnie. Lehetsgek:
% - a % jel. b az argmentum integer, s binris szmknt jelentjk meg c az argumentum integer, ASCII kdknt jelentjk meg. d az argumentum integer, decimlis szmknt jelentjk meg. f - the argumentum double s lebegpontos szmknt jelentjk meg. o - az argumentum integer, s oktlis szmknt jelentjk meg. s az argumentum string s gy is jelentjk meg.

20

x - az argumentum integer s hexadecimlis szmknt jelentjk meg (kisbetvel) X - az argumentum integer s hexadecimlis szmknt jelentjk meg (nagybetvel)

$isodate = sprintf ("%04d-%02d-%02d", $ev, $ho, $nap); $money1 = 68.75; $money2 = 54.35; $money = $money1 + $money2; // Az echo $money kimenete "123.1" lesz $formatted = sprintf ("%01.2f", $money); // Az echo $formatted kimenete "123.10" echo $money; echo $formatted;

8.3

A kiirats gyakorlsa

1. rasd ki PHP programmal egy ltalad ismert tetszleges vers els ngy sort, soronknt! 2. rasd ki egy tetszleges dalszveget egy tblzatba, versszakonknt egy- egy oszlopba! 3. rasd ki egyms utn a 1-tl 20-ig a ngyzetszmokat jobbra igaztval!

21

9 Opertorok (mveletek)
A kvetkezkben megismerjk, hogy milyen mveleteket vgezhetnk a klnbz adattpusokkal.

9.1

Stringek kztti mveletek

Stringek sszefzse: .
$a = alma.krte ; echo $a; //eredmnye almakrte lesz

Stringek hozzadsa meglv sztringhez: .=


$a = meleg; $a .= vz; $echo $a; // eredmny: melegvz

9.2
echo echo echo echo echo

Aritmetikai mveletek
$a $a $a $a $a + * / % $b; $b; $b; $b; $b; //$a s $b sszege //$a s $b klnbsge //$a s $b szorzata //$a s $b hnyadosa (egsz, ha $a s $b egszek s a hnyados egsz) //Modulus $a / $b maradka

A numerikus rtkek sszeadsra ugyanolyan opertorokat hasznlunk, mint ms nyelvekben.

9.3

Hozzrendels, rtkads

Az opertor az "=". Ez ugyanazt jelenti, mint Pascalban a := vagy C-ben az =. A bal oldal rtke legyen az, ami a jobb oldal. A hozzrendel kifejezsnek az rtke a bal oldalhoz rendelt rtk.
$a = ($b = 4) + 5; // $a most 9, s $b 4

9.4

Nvel/cskkent opertorok

A PHP tmogatja a C-ben megismert inkrementl s dekrementl opertorokat. Az albbiakban megismerjk azokat, majd pldt ltunk rjuk: Amikor az opertor a vltoz eltt van, akkor a kirtkels sorn elszr nvekszik a vltoz rtke, majd rtkeli ki a rendszer, mg a vltoz mgtti opertor esetn elszr kirtkeli a vltozt a rendszer, majd nveli vagy cskkenti az rtkt!
<?php $a = 33; echo ++$a; echo $a++; echo --$a; echo $a--; ?>

// // // //

Nveli $a-t eggyel, majd visszaadja $a rtkt Visszaadja $a rtkt, majd nveli $a-t eggyel Cskkenti $a-t eggyel, majd visszaadja $a rtkt Visszaadja $a rtkt, majd cskkenti $a-t eggyel

Itt egy msik pldaprogram:


<?php echo "<h3>Postinkrementls</h3>"; $a = 5; echo "5-nek kell lennie: " . $a++ . "<br>\n"; echo "6-nak kell lennie: " . $a . "<br>\n"; echo $a = echo echo echo $a = echo echo "<h3>Preinkrementls</h3>"; 5; "6-nak kell lennie: " . ++$a . "<br>\n"; "6-nak kell lennie: " . $a . "<br>\n"; "<h3>Postdekrementls</h3>"; 5; "5-nek kell lennie: " . $a-- . "<br>\n"; "4-nek kell lennie: " . $a . "<br>\n";

22

echo $a = echo echo ?>

"<h3>Predekrementls</h3>"; 5; "4-nek kell lennie: " . --$a . "<br>\n"; "4-nek kell lennie: " . $a . "<br>\n";

9.5

Logikai opertorok

A logikai mveletek minden programozsi nyelvben hasonlan nznek ki. Az albbi lehetsgek vannak. A PHP-ben az igaz rtket mindig az 1 s a hamis rtket a 0 hordozza. Ennek a tudsnak a birtokban ugyanakkor nem clszer a 0 s 1 rtkeket numerikusan hasznlni.
<?php $a = TRUE; $b = FALSE; echo $a and $b; echo $a or $b; echo $a xor $b; echo ! $a; echo $a && $b; echo $a || $b; ?>

//s //Vagy //Kizr vagy //Tagads //s //Vagy

Csak akkor igaz, ha mind $a mind $b igazak Akkor igaz, ha $a s $b kztt van igaz Akkor igaz, ha $a s $b kzl pontosan egy igaz Igaz, ha $a nem igaz Csak akkor igaz, ha mind $a mind $b igazak Akkor igaz, ha $a s $b kztt van igaz

9.6

sszehasonlt opertorok

Az sszehasonlt opertorok, mint nevk is sugallja, kt rtk sszehasonltsra szolglnak. Az eredmny igaz, vagy hamis lehet!
Echo $a == $b; //Egyenl Igaz, ha $a s $b rtke egyenl <?php $a = alma; $b = krte; echo $a === $b; //Azonos Igaz, ha $a s $b rtke egyenl, s azonos tpusak // (csak PHP 4) echo $a != $b; //Nem egyenl Igaz, ha $a s $b rtkei klnbzk echo $a !== $b; //Nem azonos Igaz, ha $a s $b rtkei vagy tpusai klnbzk // (csak PHP 4) echo $a < $b; //Kisebb mint Igaz, ha $a szigoran kisebb, mint $b echo $a > $b; //Nagyobb mint Igaz, ha $a szigoran nagyobb, mint $b echo $a <= $b; //Kisebb, vagy egyenl Igaz, ha $a kisebb, vagy egyenl, mint $b echo $a >= $b; //Nagyobb, vagy egyenl Igaz, ha $a nagyobb, vagy egyenl, mint $b ?>

Van egy feltteles opertor is, a "?:" (ternlis) opertor, ami gy mukdik, mint a C-ben s sok ms nyelvben.
(kif1) ? (kif2) : (kif3);

A kifejezs kif2-t rtkeli ki, ha kif1 igaznak bizonyul, s kif3-at, ha kif1 hamis.

9.7

Bitorientlt opertorok

A bitorientlt opertorok teszik lehetv, hogy egy egsz rtk bizonyos bitjeit belltsuk, vagy kimaszkoljuk.
<?php $a = 126; $b = 3 ; echo $a & $b; // echo $a | $b; echo $a ^ $b; // echo ~ $a; echo $a << $b; // // echo $a >> $b

//s Azon helyeken, ahol mind $a-ban, mind $b-ben '1' volt, az eredmnyben '1' lesz, egybknt '0'. //Vagy Ott lesz '1' az eredmny, ahol vagy $a-ban, vagy $b-ben '1' llt. //Kizr vagy Ott lesz '1', ahol vagy $a-ban, vagy $b-ben '1' ll, de csak az egyikben. //Nem $a sszes bitjt invertlja //Eltols balra $a bitjeit $b-vel balra tolja (minden tols 2-vel val szorzst jelent [amg el nem fogynak a bitek. A legfels helyirtk az eljelbit.) //Eltols jobbra $a bitjeit $b-vel jobbra tolja (minden tols 2-vel val

23

// // ?>

[egsz!]osztst jelent. Mivel a legfels bit az eljelbit, negatv szm jobbra tolsa fura eredmnyre vezet!)

9.8

Hibakezel opertorok

A PHP egy hibakezel opertort tmogat, az at (kukac) jelet (@). Ha egy PHP kifejezs el rod, a kifejezs ltal esetlegesen generlt hibazenete(ke)t figyelmen kvl hagyja a rendszer. Ha a track_errors szolgltats be van kapcsolva, brmilyen a kifejezs ltal generlt hibazenet a $php_errormsg globlis vltozba kerl trolsra. Ez a vltoz minden hiba esetn fellrdik, ezrt ellenrizd minl hamarabb a kifejezst kveten ha hasznlhat informcit szeretnl kapni.
<?php /* Szndkos SQL hiba (plusz idzjel a tblanvnl): */ $res = @mysql_query ("select nev, kod from 'nevlista") or die ("A lekrs sikertelen volt. A hiba: $php_errormsg"); ?>

Lsd mg: error_reporting().

9.9

Vgrehajt opertorok

A PHP-segtsgvel utastsokat hajthatok vgre az opercis rendszeren. A jel a visszaidzjel ``. Ha kzjk rok egy parancsot az opercis rendszer rszre, akkor az megprblja vgrehajtani s egy vltoznak tadni az eredmnyt. [Az albbi kis plda az aktulis knyvtr tartalmt (hossz lista, rejtett fjlok is) formzva rja ki (illetve fix szlessg betket hasznlva, entereket tiszteletben tartva)]
<?php $output = `dir C:\`; echo "<pre>$output</pre>"; ?>

Ebben a tmban az albbi fggvnyeket rdemes mg megtekinteni a doksibl: system(), passthru(), exec(), popen(), s escapeshellcmd().

9.10 Gyakorl feladatok


1. Irasd ki kt vltoznak az sszegt klnbsgt, szorzatt s hnyadosukat, tovbb a maradkot gy, hogy minden sorba egy rtk kerl, tovbb kiiratjuk az operandusokat is! 2. Irasd ki ttekinthet formban egy ember klnbz cmen megkapott jvedelmeit, a befizetend adjt s sszesatst! 3. rd ki az albbi logikai kifejezs igazsgtblzatt: (A and B ) or not C! 4. Mutasd meg, hogy mi trtnik akkor, ha negatv szmnak a kt, hrom, ngy bittel eltolod az rtkeit jobbra s balra is! 5. Hvd meg a futtat opercis rendszeren a knyvtr listz parancsot s irasd ki az eredmnyt!

24

10 Vezrlsi szerkezetek
A PHP-ben ugyangy, mint ms programozsi nyelvekben az utastsok vgrehajtsnak sorrendje alapveten fentrl lefel. Ily mdon csak szekvencilis programokat lehet rni, azonban rvid tanuks utn szksgess vlik elgazsokat s ciklusokat tartalmaz programok rsa is. A vezrlsi szerkezetek, mint mindig itt is a C-hez hasonlak. A program a klnbz irnyokba val tovbbhaladst ltalban egy kifejezs hatrozza meg. Ennek a kifejezsnek az rtke logikai alapveten, azonban a PHP hasonlkppen, mint a C nem klnbztet meg kln logikai rtkeket, hanem a 0 s a nem 0 rtkek jelentik azt. Ily mdon, ha egy numerikus kifejezs 0, akkor hamis, s ha nem 0, akkor igaznak tekinthet. Ha egy string kifejezs res, akkor hamis, ha van rtke, akkor igaz. Az olyan vltozk, amelyeket mg azeltt rtkelnk ki, hogy rtket kaptak volna (ez nem helyes), a NULL rtkkel brnak.

10.1 Elgazsok
Az els fontos lehetsg a felttelhez kttt vgrehajts. Ha brmelyik gon tbb utastst akarunk vgrehajtatni, akkor szintn a C szintaktika szerint { ...} jelprost kell hasznlnunk If( utasts) ...
if(kifejezs) utasts;

if(kifejezs) { utasts1; utasitas2; ..... }

If .... else.... Ha a kifejezs igaz, akkor az utasts1 klnben az utsts2 hajtdik vgre.
if( kifejezs ) else utasts1; utasts2;

Ha a kifejezs igaz, akkor az utasts1 g hajtdik vgre, klnben a msik


if( kifejezs ) { utasts1; utasitas2; ..... }else{ utasts3; utasitas4; ..... }

If ... elseif ... else ... Ha kettnl tbb elgazst szeretnnk, akkor az albbi szintaktikval tudjuk a krdst megoldani:
if( kifejezs1 ) elseif(kifejezs2) else utasts1; utasts2; utasts3;

vagy
if( kifejezs1 ) { utasts1; utasitas2; .....

25

}elseif( kifejezs2 ){ utasts3; utasitas4; ..... }else { utasts5; utasts6; ...... }

Switch(kifejezs) A fenti esetben az if s az elseif utastsnl lv kifejezsek tetszlegesek lehetnek, s az gy felrt vezrlsi szerkezettel meglehetsen bonyolult elgazsokat lehet ltrehozni. Ezzel szemben ltalnosabb eset, amikor egy vltoz rtktl fggen akarunk tbb fle mveletet is vgrehajtani. Erre a clra alkalmas a C-bl jl ismert switch() fggvny, amely tbb irny elgazst hajt vgre. Az gak meghatrozsakor csak konstansokat hasznlhatunk, s az gra akkor addik t a vezrls, ha a switch fggvnyben lv vltoz rtke pontosan a konstans rtkvel egyezik meg. Amennyiben egy gra radtuk vezrlst, majd vgrehajtottuk az ott definilt utastsokat, a switch szerkezet vgre kell ugranunk a break utasts segtsgvel, mivel klnben rcsorognnk a kvetkez case felttelvizsglatokra. Nzzk a szintaktikjt:
switch ($i) { case 0: print "i break; case 1: print "i break; case 2: print "i break; default: print "i }

most 0";

most 1";

most 2";

se nem 0, se nem 1, se nem 2";

A fenti pldban az $i vltoz rtktl fggen lptnk valamelyik irnyba. Ha a vltoz rtke nem vette fel sem a 0, 1 vagy 2 rtkeket, akkor a default utni parancs hajtdik vgre. Gyakori eset, hogy amikor tbb klnbz esemnyt egyetlen vltoz klnbz rtkei alapjn akarsz vgrehajtatni, akkor hasznlod a switch utastst. Elfordulhat, hogy ugyanazt az esemnyt tbb rtk is jellheti, illetve tbb klnbz esemny van. Az albbi pldban a $jelz vltoz 0, 1, 2 rtke esetn az fv1() fggvny fut le, a 3-as rtkre az fv2() fggvny, egyb esetekben az fv3().
switch ($i) { case 0: case 1: case 2: fv1($jelzo); break; case 3: fv2($jelzo); break; default: fv3($jelzo); }

A fenti pldban az fv1, fv2, fv3 fggvnyek lehetnek akrmik!

26

10.2 Ciklusok
Mint a C-ben, itt is hasonl ciklusszerkezetek lteznek. While (kifejezs) Itt a kifejezs a ciklus eltt rtkeldik ki, azaz a ciklus magja nem biztos, hogy vgrehajtdik.
While (kifejezs) utasts; While (kifejezs) { Utasts1; Utasts2; ... }

Plda:
<?php $i = 1; while ($i <= 10) { print $i++; } $i = 1; while ($i <= 10) { print $i; $i++; } ?>

// a kirt rtk $i, a kirs utn n $i rtke // Az elz ciklus mskppen, de ugyanazzal az eremdnnyel // a kirt rtk $i, a kirs utn n $i rtke

Do ..... While(kifejezs) A kifejezs a ciklus vgn rtkeldik ki, azaz a ciklus magja egyszer mindenkppen lefut.
Do utasts while(kifejezs); Do{ Utasts1; Utasts2; ... }while(kifejezs);

Plda:
<?php $i = 0; do { print $i; } while ($i>0); ?>

For(inicializl kifejezs; Benntmarads kifejezse; iterl kifejezs) A ciklus elejn egyszer fut le az inicializl kifejezs. ltalban ez egy vltoznak ad egy kezdrtket. Az ilyen vltozt ciklusvltoznak hvjuk. A Benntmarads kifejezse mindannyiszor a ciklus magjnak lefutsa eltt rtkeli ki a rendszer. Ha a kifejezs igaz rtket ad vissza, akkor lefut a ciklus magja, ha hamis rtket, akkor a ciklus utni els utastson folytatdik a futs. Ha a kifejezs helyre res rtket runk, akkor vgtelen ciklusba kerlhetnk, hacsak a ciklus belsejbl nem ugrunk ki a break utastssal. Az Iterl kifejezs felels azrt, hogy a ciklus valamikor befejezdjn. ltalban a ciklusvltoz rtkt nveljk vagy cskkentjk eggyel.
For (init;bentmarads;itercio) utasts; For (init;bentmarads;itercio){ Utasts1; Utasts2 ...... }

Plda:

27

<?php // rassuk ki az egsz szmokat visszafel 100-tl 1-ig for ($i = 100; $i >0; $i--) { print $i; } //rassuk ki egy kt dimenzis tmb elemit soronknt $a= array( array(3,5,4,6),array(12,234,12,12),array(3,6,5,77)); for ($i =1; $i<= 0; $i--) { for (j=1;j<=4;j++){ print $a[$i][$j]. ; } print <BR>; } ?>

Foreach ( tmb_kifejezs as $rtk) vagy Foreach ( tmb_kifejezs as $kulcs => $rtk) Ez a fajta ciklus a Perl nyelvbl kerlt t a PHP-be. Ezt a ciklust arra hasznlhatjuk, hogy egy ciklussal vgigmenjnk egy tmb minden egyes elemn. Rendkvl jl hasznlhat adatbzis lekrdezsek vagy egyb tmbben visszaadott adatok feldolgozsa sorn. Ktfle
Foreach ($tmbvltoz as $ertek) utasts; Foreach ($tmbvltoz as $ertek){ Utasts1; Utasts2 ... }

Plda:
$tomb = array (1, 2, 3, 17); foreach ($tomb as $ertek) { print "Az aktulis rtke \$tomb-nek: $ertek.\n"; }

A msodik formban a $kulcs vltoz megkapja a tmb ppen aktulis indext, ezltal egyes esetekben knnyebb a feldolgozsa
Foreach($tmbvltoz as $kulcs => $ertek) utasts; Foreach ($tmbvltoz as $kulcs => $ertek){ Utasts1; Utasts2 ... }

Plda:
* harmadik foreach plda: kulcs s rtk */ $tomb = array ( "egy" => 1, "kett" => 2, "hrom" => 3, "tizenht" => 17 ); foreach ($tomb as $kulcs => $ertek) { print "\$tomb[$kulcs] => $ertek.\n"; }

break vagy break n A break utasts arra szolgl, hogy segtsgvel egy struktrbl az adott helyen ki tudjunk ugrani. Ha utna runk egy szmot, akkor annak alapjn tbb egymsba gyazott struktrbl is ki tud ugrani: Pldnak okrt korbban a switch utastsnl mutattunk egy pldt a break hasznlatra, az opcionlis mdra pedig itt van egy plda:
$i = 0; while ($i++) { switch ($i) { case 5: echo "5 esetn<br>\n";

28

break 1; /* csak a switch-bl lp ki */ case 10: echo "10 esetn kilps<br>\n"; break 2; /* a switch s a while befejezse */ default: break; } }

continue vagy continue n Br programozsi mdszertanok kerlik a ciklusokbl val kiugrlst s a ciklusmagon belli itercit, azrt minden ltalnos nyelvben benne van a lehetsg, belertve a Pascalt s a C-t is. Ez az utasts akkor hasznlhat, ha a ciklus belsejben mr eldlnek a tovbbi itercira vonatkoz felttelek s nem akarjuk, hogy a ciklus magjnak tbbi rszt feleslegesen futtassuk. Ha a continue n formt hasznljuk, akkor tbb egymsba gyazott struktrt tudunk folytatni. Az albbi pldban 100 db vletlenszmot hozunk ltre a 0..4 egsz tartomnybl s az eloszlsukat vizsgljuk. A continue utastsok hatsra ha megvan az rtk, tovbbi feltteleket nem rtkel ki a program, hanem rgtn iterlja a for ciklust.
<?php $n = 100; srand (double) microtime() * 1000000); $a1=$a2=$a3=$a4=$a5=0; for($i=1;$i < $n;$i++){ $veletlen= rand(0,4); switch($veletlen){ case 0: $a1++; continue; case 1: $a2++; continue; case 2: $a3++; continue; case 3: $a4++; continue; default: $a5++; } } ?>

10.3 Elgazsok s ciklusok hasznlata HTML kddal keverve


Gyakori, hogy a HTML oldalon kt klnbz kdot szeretnnk megjelenteni, attl fggen, hogy ppen melyik felttel igaz, ugyanakkor a kirand HTML rszt tl bonyolultan llthatjuk csak el PHPben. Ebben az esetben alkalmazni lehet az albbi pldhoz hasonlt:
<?php if ( kifejezs) { echo elso g; ?> <table> <tr> <td> <P> Szevasz tavasz, a kifejezs igaz</p> </td> <td> <P> valamit visz a vz</p> </td> </tr> ....... </table> <?php } else { echo Msik oldal; ?> <p> Ez a rsz itt egyszerbb lett!</p> <?php } ?>

Az igaz kifejezs esetn az igaz gban ltrejv egy soros tblnak kt oszlopa lesz, mg a hamis rtk esetn csak a msodik szakaszban lv kirs jelenik meg, mivel a PHP amikor megszakad a PHP kd itt tbbszr is megszakad -, akkor a szervernek vltozatlanul adja vissza a HTML kdot. Sajnos az gy megrt program kiss ttekinthetetlen.

29

10.4 PHP lapok beszrsa, makro-k hasznlata.


Gyakran megfogalmazott feladat, hogy egy tbb lapbl ll PHP programban minden PHP oldal elejn fussanak le ugyanazok a belltsok, ugyanazok az inicializl paramterek, illetve ugyanazokat a fggvnyeket s lehetsgeket hasznljuk minden PHP scriptben. Valami olyasmire gondolok itt, mint Pascal-ban a unit fogalma vagy C-ben a header file-ok fogalma. Erre a clra kt parancs ll rendelkezsre, amelyeknek a mkdse nem pontosan ugyanaz, de nagyon hasonl. Mind a kt esetben arrl van sz, hogy a PHP script egy adott pontjn behvunk egy file-t, amelynek a kdja futsidben bekerl a PHP scriptbe, a szerver kirtkeli, s annak megfelelen jr el. A file tartalma teht a futs idejre gy vlik a PHP script rszv, mintha eleve abba bertuk volna. Mivel a Webszerver kezdi a krdses include file-t feldolgozni, ezrt ilyenkor HTML mdba kerl a szerver, gy a PHP kd feldolgozshoz az include file elejn PHP nyit tag-et kell elhelyezni s a vgn zrtag-et. (<?php .............?>) Include () Az include hasznlata esetn a megadott file mindannyiszor kirtkeldik, ahnyszor a vezrls az include-ra kerl. Ennek eredmnyeknt, ha egy ciklus belsejben megfelelen helyezzk el a file-t, akkor a ciklus rtktl fggen mindig ms s ms file-t szerkesztnk be, mint az albbi pldban lthatjuk:
$fileok = array ('elso.php', 'masodik.php', 'harmadik.php'); for ($i = 0; $i < count($fileok); $i++) { include $files[$i]; }

require() A require parancs akkor is beolvassa a clfile-t, ha soha nem hajtdik vgre a krdses sor a f file-ban, s ha ciklusban helyezzk el a krdses sort, akkor is csak egyszer kerl be. A fentiek miatt require parancsot csak konstans file-nevekkel szabad hasznlni.
<?php require ("file.php"); ?>

include_once() Az utasts hasonlt az include() utastsra, azzal a klnbsggel, hogy csak egyszer kerl bele a futskor a krdses file. Ez azrt fontos, mert ha az include() utastssal tbbszr is meghvjuk futs kzben ugyanazt a file-t, akkor a benne lv globlis vltozk s fggvnyek tbbszr kerlnek a kdba, ami miatt a futs hibazenettel lell, hiszen ugyanaz az azonost ms s mst jell. Az include_once() segtsgvel ezt a hibaforrst kikszblhetjk. require_once() Az utasts hasonlan az include_once() utastshoz csak egyszer hvja be a krdses file-t futs kzben, gy a fggvnyek s globlisvltozk jradefinilsa krli problmk kikszblhetk. Egybknt a require() utastssal megegyez a szerepe s mkdse.

30

10.5 Tvoli file-ok hvsa


A fenti kt utasts include s require alkalmas arra, hogy a PHP megfelel konfigurlsa esetn tvoli file-okat is elrjnk, akr msik Web szerveren is. Ehhez az "URL fopen wrapper"-eket kell bekapcsolni, a PHP4.0.3-tl kezdden az allow_url_fopen php.ini belltsval. Ez a lehetsg Windows rendszereken nem mkdik. Ennek a tulajdonsgnak persze vannak veszlyei is. Ha egy ilyen tvoli hvs sorn olyan lapot hvunk meg, aminek a tartalmra nincsen hatsunk, akkor az include-olt file tartalma lehet olyan, hogy a mi rendszernkre veszlyeket hordoz. A tvoli helyen megfelelen elksztett lap email-ben elkldheti az azonostkat s egyb olyan adatokat, amelyeket nem szeretnnk nyilvnossgra hozni, ezrt ezzel a lehetsggel vatosan kell bnni.

10.6 Pldaprogramok felttelekkel, ciklusokkal


1. rj programot, amely kirja az ttel s a httel oszthat szmokat s ezen szmok sszegt! 2. rj egy programot, amely az eraszthotenszi szita vagy ms mdszer segtsgvel kirja a prmszmokat 1-tl n-ig! 3. Kszts programot, amely sszefsli $a, $b rendezett tmbk tartalmt, majd az tetszets formban kirja a kpernyre! 4. rj programokat, az include s require parancsok segtsgvel, amely teszteli egy rendezsi algoritmus sebessgt, mivel ugyanazokat az include-olt tmbket rendezi sorba.
Az albbi feladatok a Programozsi ttelek s Adatszerkezetek cm jegyzetembl szrmaznak Feladatok:

Egy repl indul az egyik kontinensrl a msikra, s repls kzben rendszeresen mri az alatta lv felszn tengerszint feletti magassgt. A mrt rtk nulla ekkor tenger felett repl vagy pozitv ekkor szrazfld felett repl. Ksztsnk olyan programot, amelyik a kvetkezkre kpes: Szimullja a mrseket vletlenszeren, figyelve arra, hogy az els s az utols mrs szrazfld felett trtnt. Az eredmnyeket fjlba menti. Kirja a kpernyre az albbi krdsekre a vlaszokat:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Milyen tvol van egymstl a kt kontinens? Hol vannak a szigetek partjai (eltte tenger, utna szrazfld vagy fordtva)? Hny sziget van a kt kontinens kztt? Hny hegycscsot tallt (A hegycscs az a hely, ami eltt s mgtt kisebb a tengerszint feletti magassg)? t tud-e menni a kt kontinens kztt egy kajakos, ha egyszerre csak egy adott tvolsgot tud evezni, mert ha tbbet evez, akkor elpusztul? Mekkora a szigetek tlagos tvolsga? Van-e leszllplya valamelyik szigeten (olyan rsz, amely vzszintes legalbb kt mrs tvolsgig) Hny darab apr sziget van (maximum 3 mrshosszsg)? Szeretnk alfldn lni. Van-e olyan rsz, amely sk vidk, elg nagy s alfld? Keressk meg ezt a helyet! Hol tallhat a leghosszabb sziget kezdpontja? - A fenti krdsekre vlaszt ad gyis, hogy vletlen-szl gtolja, vagy segti a replgp tjt - Tltsnk fel adatokkal egy kt-dimenzis tmbt! rjunk programot, amely kirja a legnagyobb elemet tartalmaz sor szmt!

31

11 Sajt fggvnyek, vltozk lettartama s lthatsga


Eddig sok sz esett a vltozkrl s esetenknt a fggvnyekrl is, azonban az eddigiek alapjn azt gondoln az ember, hogy csak ilyen egyszer programok rhatk PHP-ben. Az igazsg az, hogy PHPben csak a futsi id s a futtat rendszer memrija szab hatrt az alkalmazott program bonyolultsgnak.

11.1 Fggvnyek
A PHP-ban is hasznlhatunk programstruktrkat, programszegmenseket. Mr Pascal-bl vagy C-bl is jl ismerhetjk az alapvet kt eljrstpust, amit Pascalban Procedure illetve Function nvvel illetnk, C-ben pedig tpus nlkli illetve tpusos function-nak mondunk. Mind a kt nyelven a klnbsg az, hogy ad-e vissza a krdses eljrstpus rtket, vagy nem. A PHP-ben csakgy, mint a C-ben ktfle eljrstpust hasznlhatunk. A szintaktika a kvetkez: Ez az eljrstpus nem ad vissza rtket.
function fggvny_nv(paramterlista) { A fggvny trzse; }

Ez az eljrstpus a definiltnak megfelel tpus rtket ad vissza:


function fggvny_nv(paramterlista) { A fggvny trzse; return rtk; }

Lthat, hogy a visszatrsi rtk lte vagy nem lte a programoztl fgg, ezrt egyes esetekben clszer a visszatrsi rtk tpust megllaptani ahhoz, hogy van-e egyltaln visszatrsi rtk. PHP3-ban a definilt fggvnynek mindig a fggvny hvsa eltti ponton kell lennie, vagyis azokat a fggvnyeket, amelyeket hasznlni akarunk a PHP program elejre kell tennnk. A PHP4ben ez a megszorts megsznt, ugyanakkor clszer magadat ehhez a szokshoz tartani. A PHP nem tmogatja a fggvnyek polimorfizmust, a fggvnyeket nem tudod undefinilni vagy jradefinilni a mr definilt fggvnyeket. Az objektum orientltsg ennek megfelelen nem teljes a PHP-ben. A fggvny meghvsa esetn paramtereket adhatunk t a hvott fggvnynek. Ennek rszleteit a kvetkez szakaszban fogjuk trgyalni. Rekurzi lehetsges a fggvnyhvsoknl, de termszetesen arra kell vigyzni, hogy a rekurzi vget rjen. Az albbi kis plda az N faktorilis kiszmtst vgzi rekurzv mdon.
<?php function nfakt($n){ if ($n>1) $nf = $n*nfakt($n-1); else $nf = 1; echo $n." => ".$nf."<BR>"; return $nf; } nfakt(200); ?>

11.2 Paramtertads
Egy fggvny definilsakor meg kell hatrozni, hogy milyen paramtereket vegyen t. Ezt a paramterlistval tudjuk megtenni, amelyben az tvev vltozk neveit vesszvel elvlasztva fel kell sorolni.

32

A hvskor nem kell minden paramtert tadni. Ebben az esetben a krdses paramtereknek a fggvnyen bell nem lesz rtke. Az empty() fggvnnyel lehet megvizsglni, hogy egy paramter kapott-e rtket vagy sem. A PHP-ben ktfle paramtertads, ltezik rtk szerinti A hv kifejezs rtke behelyettestdik a meghvott fggvny paramterlistjban szerepl vltozba s a fggvnyen bell a paramter hasznlhat. Ez az alaprtelmezs. Cm szerinti Ez azt jelenti, hogy a vltoz memriacmt adjuk t a fggvnynek, amely a cm ismeretben tudja azt mdostani s a fggvnybl val visszatrskor a vltozsok megmaradnak. Ez utbbi esetben, ha cm szerint akarunk tvenni rtket egy fggvnnyel, akkor hasznlnunk kell a & opertort.
<?php function fgv(&$n) { $n *= 2; } $n=100; echo $n<BR>; fgv($n); echo $n<BR>; ?>

Mg akkor is tadhatjuk cm szerint a vltozt, ha a fogad fggvnyt nem ksztettk fel a cm szerinti paramtertvtelre, az tadsnl hasznljuk a & opertort. Ez utbbi nem tlsgosan szp md, mivel egy fggvnyt valsznleg nem azrt hasznlunk rtk szerinti paramter tvtelre, hogy majd mshol mdostsunk a dolgon.
<?php function fgv($n) { $n *= 2; } $n=100; echo $n<BR>; fgv(&$n); echo $n<BR>; ?>

A fggvnyek paramtereinek tvtele mg egy mdon megtrtnhet. A PHP tmogatja a paramterek kezdrtkadst. Ennek akkor van rtelme, ha a fggvny hvsakor nem adtunk t rtket a fggvnynek. Ilyenkor alaprtelmezett rtket kap az a paramter, amelyet a hv nem adott t. Termszetesen az t nem adott paramtereknek a helye az tadottak utn helyezkedjen el!
<?php function joghurtot_keszit ($flavour, $type = "acidophilus") { return "Ksztek egy kcsg $flavour z $type-ot.\n"; } echo joghurtot_keszit ("eper"); ?>

Ha azt szeretnnk, hogy egy fggvny vltoz szm paramtert vegyen t s a fggvnyben meg akarjuk llaptani, hogy ppen most hny paramter van, akkor a kvetkez fggvnyeket hasznlni: func_get_args() Egy tmbben visszaadja az tadott paramterek listjt. Func_num_arg() Megadja a kapott fggvnyek szmt 33

func_get_arg(sorszm) Visszaadja a sorszm paramterrel megadott paramtert. Ha a sorszm nagyobb, mint a paramterlista utols elemnek indexe, akkor hibazenet jn (warning). A paramterlista indexe 0-val kezddik. Az albbi plda ezeket pldzza.
<?php function foo() { $numargs = func_num_args(); echo "paramterek szma: $numargs<br>\n"; if ($numargs >= 2) { echo "A msodik paramter: " . func_get_arg (1) . "<br>\n"; } $arg_list = func_get_args(); for ($i = 0; $i < $numargs; $i++) { echo "$i-ik paramter: " . $arg_list[$i] . "<br>\n"; } } foo (1, 2, 3); ?>

11.3 Fggvnyek visszatrsi rtke


Egy fggvny tetszleges tpust, mg tmbt, vagy vltozreferencit is vissza tud adni. Tbb rtk visszaadsra a tmbt hasznlhatjuk. Ha nem hasznljuk a return utastst, akkor az utols vgrehajtott kifejezs lesz a visszatrsi rtk.

11.4 Vltozk lettartalma s lthatsga


A PHP-ban nagyon egyszer szablyok vannak a vltozk lthatsgra s lettartamra vonatkozlag. lettartam A vltoz akkor jn ltre, amikor ltrehozzuk, rtket adunk neki. Egy vltoz megsemmisl, ha az unset(vltoznv) paranccsal felszabadtjuk a vltoz nevt (memriaterlett is), vagy vget r az adott PHP script oldal. Ez all kivtel, ha a vltozkat tadjuk egy msik PHP oldalnak a POST, GET metdussal, a cookie-k vagy sessionok hasznlatval. Egy PHP oldal elejn hasznlhatk a HTTP_ s az Environment vltozk, amikrl korbban esett sz. Hasznlhatk azok a vltozk, amelyeket egy msik php oldal, vagy ms HTML oldal kldtt, POST vagy GET metdussal. Hasznlhatk a Cookie-k s a Sessionok segtsgvel tvitt vltozk is. Ltezik az gynevezett a $GLOBALS tmb, amelynek tartalma a PHP oldal minden helyrl lthat.

34

Ltezik-e a vltoz Azt, hogy egy vltoz ltezik-e az isset() fggvnnyel krdezhetjk le. Igazat ad vissza, ha a vltoz ltezik, az empty() fggvny pedig igazat ad vissza, ha a vltoz rtke 0, res, vagy nem ltezik!
<?PHP if (!isset($_SESSION[logged_in])) print(Belptl!); ?> die(Jelentkezz be!);

Lthatsg A PHP oldalon ltrejtt s a klnbz mdokon tvett vltozk globlisak, azaz attl a helytl kezdve lthatk mindenhonnan, azonban ha meghvunk egy fggvnyt, akkor abban a fggvnyben csak azok a vltozk lthatk, amelyeket a fggvnyben hoztunk ltre, vagy paramterknt adtunk t. Ha a fggvnybl kilpnk, akkor ezek a vltozk megsemmislnek kivve, ha nem cm szerinti paramtertads sorn jttek ltre. Azaz ezek a vltozk loklisak lesznek a fggvnyre nzve. Ha egy fggvnybl j fggvnyt hvunk, akkor abban nem lehet ltni a hv fggvny vltozit. A fentiek all az egyetlen kivtel, ha a fggvnyben hasznljuk a global parancsot, aminek segtsgvel importlhatjuk a script globlis vltozit a fggvnybe.
<?php $a = 1; $b = 2; Function Osszead () { global $a, $b; $b = $a + $b; } Ossszead (); echo $b; ?>

A msik lehetsg az, hogy hasznljuk a $GLOBALS[] asszociatv tmb rtkeit, amelyben minden bejegyzett globlis vltoz megtallhat.
<?php $b = 1; $a = 10; $GLOBALS["b"] = $GLOBALS["a"] + $GLOBALS["b"]; echo $b; ?>

Ltrehozhatunk statikus vltozkat is, amelyek a Clipperben s ms hasonl nyelveken lteznek. Statikus vltoz egy fggvnyben jhet ltre. Amikor kilpnk a fggvnybl mr nem hasznlhatjuk ennek a vltoznak az rtkt, de ha jra meghvjuk a fggvnyt, nini mg megvan az elz rtke. J ott folytathatjuk, ahol abbahagytuk. Ennek nha van rtelme. Mindenesetre a hasznlathoz a fggvnyben a static kulcsszt kell hasznlni. Az albbi kis szsszenet egy ciklusbl meghvja jra meg jra a Test() fggvnyt s ennek sorn az $a vltoz tartalma folyamatosan n, noha mindig kilpnk a fggvnybl. Na ja, statikusnak deklarltuk! A statikus vltoznak kezdrtket adva, az csak egyszer fut le, amikor elszr meghvjuk a fggvnyt.
Function Test () { static $a = 0; echo $a; $a++; } for ($i =0; $i< 10;$i++) {

35

Test(); Echo blablabla }

11.5 Vltozk tadsa lapok kztt


Gyakori krds a PHP-ben programozk kztt, hogyan tudnak rtkeket tadni a PHP lapok kztt, hiszen ha egy lap lefut, akkor eddig gy tudtuk, hogy a lapon keletkezet vltozk is megsznnek. Amikor elszr szembekerltem a problmval, akkor azt hittem, hogy a globlis vltozk oldjk meg a problmt. Sajnos a dolog nem ennyire egyszer, de nem is tlsgosan bonyolult. tadhatunk egyedi vltozkat s egy dimenzis tmbket is. Ngy lehetsgnk van erre.

11.5.1 Header utasts


A Header utastst csak akkor hasznlhatjuk, ha az adott oldalon mg semmifle kpernyre rs nem volt, azaz a keletkez HTML oldalnak mg nem kezdtk rni a BODY rszt. A header segtsgvel brmilyen header TAG-et kirathatunk a HTML oldalra. Az albbi pldban egy teljes header sorozatot runk ki a HTML oldalra
header header header header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // always modified ("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 ("Pragma: no-cache"); // HTTP/1.0

header ("HTTP/1.0 404 Not Found");

Itt egy hibakezelst runk ki, az URL nem tallhat. Akkor lehet ilyet tenni, ha pldul az Apache szervernk hibazeneteit tirnytjuk a sajt oldalainkra.
header ("HTTP/1.0 404 Not Found");

Bngsz tirnytsa. Itt adhatjuk meg az j oldalt. Ez a parancs nem csak a bngszt vgja t az j oldalra, hanem a szervernek is visszakld egy tirnyts sttusz zenetet is.
header ("Location: http://www.php.net"); /* tirnytja a bngszt a PHP web oldalra */ exit; /* Ha nem megy az tirnyts, akkor az exit parancs biztosan kilp */

11.5.2 GET metdus


A GET metdust gy hasznlhatjuk, hogy meghvunk egy lapot az oldalunkrl egy msik lapot s az URL vgre paramterknt tadjuk a vltozkat, valahogy gy, ahogy a kvetkez pldkban ltjuk: Az els pldban igazbl nem is PHP a megolds, egyszeren a <BODY> TAG-ben megadjuk, hogy melyik oldalt s menyi id mlva hvja meg az oldal. Ennek a megoldsnak hibja, hogy tulajdonkppen itt egy Javascriptet hasznlunk. A pldban 3 msodpercig vr a betltds utn a bngsz, majd a szerver tdobja az j oldallal s meghvja a lapot a user, pwd s a level vltozkkal.
<BODY OnLoad=timerID=setTimeout('location="index.php?user=anonym&pwd=anonymous&level=1"',30000)>

A kvetkez pldban hasonlt tesznk, de itt a HTML oldal fejlcben dolgozunk. Felhasznljuk a HTML meta tag-jt. Itt is 3 msodperc mlve hvja be a kvetkez oldalt s az elz oldalrl tadjuk az elz pldban ltott 3 vltoz pillanatnyi rtkt.
<meta http-equiv="refresh" content="3; URL=<index.php?<?php echo user=$user&pwd=$pwd&level=$level ?>">

A harmadik pldban a PHP header utastst hasznljuk. A pldban egy POST metdussal egy rlapon bevitt adatokat vizsglunk meg, s amennyiben hinyzik az adat, akkor egy hibakezel

36

fggvnybe irnytom t, ahol a header segtsgvel tirnytom egy msik oldalra, tadva neki a megfelel vltozkat.

function sorry($msg,$from=1,$glob="") { header("Location: sorryuser.php?from=$from&msg=$msg&glob=$glob"); } if(empty($name)) sorry("Hinyzik a nv adat! Ktelez kitlteni",1); if(empty($loginname)) sorry("Hinyz login nv! Ktelez kitlteni",1); if(empty($email)) sorry("Hiny E-mail cm! Ktelez kitlteni. Itt kapod meg a jelszt!",1);

A fenti hrom lehetsg kzs hibja az, hogy az tirnytott lapok URL-je megjelenik a bngszben, azaz titkos informcit nem tudunk tadni, tovbb azok a bngszk, amelyek nem trik az tirnytst, nem fognak tovbbmenni.

11.5.3 POST metdus


A POST adattviteli metdust az rlapokkal kapcsolatban hasznlhatjuk legtermszetesebben. Itt egyelre csak annyit mondunk, hogy az rlapok olyan HTML kdok, amelyen keresztl a bngsz eltt l felhasznl berhat adatokat a HTML oldalon, az rlap SUBMIT gombjnak megnyomsra pedig az rlapon definilt mezk tartalmt, mint vltozneveket s vltoz tartalmakat elkldi a cl oldalnak a bngsz. Az rlap fejlcben meg kell adni a cl oldalt (kinek kldjk) s a megfdelel oldal, ha az olyan oldal, amit a szerver meg tud jelenteni betltdik a bngszbe. A PHP esetn a mdszer az, hogy az rlap kitltse utn a submit gomb megnyomsval elkldjk az eredmnyeket egy PHP oldalnak, amely betltdskor megkapja az elkldtt vltozkat, esetleg elvgzi azokat a ferladatokat, amelyekre rendeltetett, majd megjelent valami vlaszt. Ennl a mdszernl, az elkldtt rtkek nem lthat mdon kerlnek el a meghvott oldalhoz, teht ezzel a mdszerrel viszonylag knny vltozrtkeket tadni. Vigyzni kell azonban arra, hogy az adatbevitel alapveten string s ha nem gy hasznljuk fel azokat a bevitt stringeket, hogy eltte kiszrjk a ../../etc/ ... stb jelleg adatrokats nem figyelnk arra, hogy az eredmnyeket a lehet legtbb szempont szerint ellenrizzk, akkor a web site-unk feltrhet lehet. Az albbi pldban egy olyan HTML oldalt mutatok be, amely egy rlapot tartalmaz, a submit gomb megnyomsnak hatsra az oldal nmagnak (!) kldi el a vltozkat, majd a submit vltoz rtke alapjn egy elgazsra kerl a vgrehajts s az eredmnyt elkldi e-mailben egy megadott cmre. A lapon van egy kis Javascript bett is, amely az aktulis idpont beszrsra szolgl. Az rlapon tallhat olyan mez is, amelynek a tartalma hidden, azaz az rlapon nem jelenik meg.
<html> <head> <meta http-equiv="Content-Language" content="hu"> <meta http-equiv="Content-Type" content="text/html; charset=windows-1250"> <title>Munkalap</title> <script language="JavaScript"> function Kitolt() { var x=0; for (x=0;x<document.munkalap.lista.length;x++) if (document.munkalap.lista.options[x].selected) document.munkalap.ceg.value = document.munkalap.lista.options[x].value; Alert (document.munkalap.lista.options[x].value); } </script> </head> <body bgcolor="#efefef" text="#00000000" link="#6666CC" vlink="#FF9900"> <script language="php"> $datum = date('Y.M.d H:i');

//aktulis dtum

37

$mikor= date ('Y.M.d'); if (!empty($pswd)) $jls = "_".$pswd."_"; else $jls = "__";

// // egyszer (primitiv) password ellenrzs // Lehetne biztonsgosabban is, de itt most ez nem szempont

// A munkalap elkldshez ki kell tlteni a partnercg nevt is. if(!empty($ceg)) { $jel= (strpos($jls, "xxxx") == 0) | empty($munkavegzo); if(!$jel) { // Itt lltjuk ssze az Email-t az tkldtt vltozk rtkbl. $uze =""; $uze= $uze ."Cg $ceg\n"; $uze= $uze ."Bejelent $bejelento\n"; $uze= $uze ."Bejelents idpontja $mikor\n"; $uze= $uze ."Hibajelensg $hibajelensg\n"; $uze= $uze ."A hiba oka $hibaok\n"; $uze= $uze ."Az elvgzett munka $elvegzett_munka\n"; $uze= $uze ."A munkavgzs alapja\n"; $uze= $uze ."- Garancilis $grancilis\n"; $uze= $uze ."- Rendszergazdai $rendszergazda\n"; $uze= $uze ."- Fizets $fizetos\n"; $uze= $uze ."- Kiszlls $kiszallas\n"; $uze= $uze ."- Mhelyben $muhely\n"; $uze= $uze ."- Rendszergazdai $rendszergazda\n\n"; $uze= $uze ."A szksges munkaid $munkaido\n"; if (!empty($munkadij)) { $uze= $uze ."Szmlzott munkadj $munkadij Ft + 25% FA\n\n"; } if (!empty($alkatreszek)) { $uze= $uze ."Beptett alkatrszek $alkatreszek\n"; $uze= $uze ."Alkatrszek ra $alkatreszar Ft + 25% FA\n\n"; } $uze= $uze ."\n"; $uze= $uze ."Munkavgz $munkavegzo\n"; $uze= $uze ."Dtum $datum\n"; $uze= $uze ."Igazols $igazolas\n\n"; $uze= $uze ."A munkalapot kld gp adatai\n"; $uze= $uze ."A gp IP cme ".$HTTP_ENV_VARS['HTTP_HOST']."\n"; $uze= $uze ."A gp neve ".$HTTP_ENV_VARS['REMOTE_HOST']."\n"; $uze= $uze ."A gpen fut bngsz ".$HTTP_USER_AGENT."\n"; mail("europr@matavnet.hu","munkalap",$uze); if( Die("Az munkalapot elkldtk!")); } if ($jel) </script> <script language="javascript"> Alert ("Hinyosan tlttte ki a munkalapot"); </script> <script language="php"> } </script> <table width="77%" border="0"> <tr> <td><font size="6" color="#6666CC"><b><img src="../jozsi_logo.png" width="100" height="93"></b></font></td> <td><font size="6" color="#6666CC"><b>Jzsi Cgnek munkalapja</b></font></td> </tr> </table> <form name="munkalap" method="post" enctype="multipart/form-data" action="index.php"> <table width="76%" border="0"> <tr> <td width="21%" valign="top">A partnercg:</td> <td width="79%" valign="top"> <input type="text" name="ceg" size="60"> <select name="lista" onclick="Kitolt()"> <option value="Nincs a listban"> </option> <option value="Emultor KFT ">EKFT</option> <option value="Gza KFT">GKFT</option> <option value="Magyar-Urnusz Ujsgrk Barti Trsasga">MUBNT</option> <option value="Magyar Tudomnyos Akadmia rdgz Intzete">MTAI</option> <option value="Alladin BT">ABT</option> <option value="Balogh Aladr SZKI">BA..KI</option>

38

<option value="Kiss Piroska Irodalmi Mzeum">KPIM</option> </select> </td> </tr> <tr> <td width="21%" valign="top">A bejelent neve:</td> <td width="79%" valign="top"> <table border="0"> <tr> <td width="131"> <input type="text" name="bejelento" cols ="60% "> </td> <td width="310"> A bejelents idpontja: <input type="text" name="mikor" value="<?php echo $mikor; ?>" > </td> </tr> </table> </td> </tr> <tr> <td width="21%" valign="top">A hibajelensg:</td> <td width="79%" valign="top"> <textarea name="hibajelenseg" rows=4 cols =60 ></textarea> </td> </tr> <tr> <td width="21%" valign="top">A megllaptott hiba</td> <td width="79%" valign="top"> <textarea name="hibaok" rows=5 cols =60 ></textarea> </td> </tr> <tr> <td width="21%" valign="top">Az elvgzett munka lersa</td> <td width="79%" valign="top"> <textarea name="elvegzett_munka" rows="6" cols =60 > </textarea> </td> </tr> <tr> <td width="21%" valign="top"> <table width="75%" border="0"> <tr> <td>Garancilis?</td> <td> <input type="checkbox" name="garancialis" > </td> </tr> <tr> <td>Rendszergazdai?</td> <td> <input type="checkbox" name="rendszergazda" > </td> </tr> <tr> <td>Fizets?</td> <td> <input type="checkbox" name="fizetos" > </td> </tr> <tr> <td>Kiszlls</td> <td> <b> <input type="checkbox" name="kiszallas" > </b></td> </tr> <tr> <td>Mhely</td> <td> <input type="checkbox" name="muhely" > </td> </tr> </table>

39

</td> <td width="79%"> <p align="left">Beptett alkatrszek<br> <textarea name="alkatreszek" rows=2 cols =60 ></textarea> </p> <p align="left">Alkatrszek ra (nett) <input type="text" name="alkatreszar" size="40"> +25% FA</p> </td> </tr> <tr> <td width="21%" valign="top"><br> A munkt vgz(k): <input type="text" name="munkavegzo" size="30"> </td> <td width="79%">Munkark <input type="text" name="munkaido" > <br>Munkadj (netto) <input type="text" name="munkadij">+25% FA </td> </tr> <tr> <td width="21%" valign="top"> <p>Dtum: <?php echo "$datum"; ?> </p> </td> <td width="79%"> Digitlis alrs: <input type="password" name="pswd" value="titok" size=20> </td> </tr> <tr> <td width="21%"> <p> <input type="submit" name="Submit" value="Elklds"> <input type="submit" name="Reset" value="Mgsem"> </p> </td> <td width="79%"> <font face="Times New Roman, Times, serif">Igazols:<br> <textarea name="Igazolas" rows=2 cols =60 ></textarea> </font></td> </tr> </table> </form> <p><A HREF="index.html" onMouseOver="document.vissza.src='../visszaanim.gif';" onMouseOut="document.vissza.src='../vissza.gif'"> <IMG SRC="../vissza.gif" NAME="vissza" ALT="Vissza a foldalra" BORDER=0 height="25"> </A> </p> <p>Utols mdosts: 2011. mrcius 12.</p> </body> </html>

11.5.4 $_SESSION vltozk


A session vltozk olyan vltozk, amelyek megtartjk rtkeiket mikzben a felhasznl egyik oldalrl tlp a msikra anlkl, hogy a korbban ismertetett mdszerek valamelyikvel direkt t kellene adnunk az rtkeket a lapok kztt. Ez a lehetsg igazi globlis vltozkat enged meg s sokkal sszetettebb WEB-es programok ksztst teszi lehetv. Tbb lapbl ll site fejlesztse gyakorlatilag session vltozk nlkl nem megy. Amikor egy felhasznl belp egy WEB oldalra, akkor egy egyedi azonost keletkezik, az gynevezett session id (SID), amelyet vagy a bngszben trolunk gynevezett cookie (sti) formjban, vagy a szerver oldalon tartunk nyilvn. A sessionok tmogatjk korltlan mennyisg vltoz regisztrlst s a tartalmuk megtartst. Amikor a felhasznl elri a web oldalt, akkor a PHP automatikusan leellenrzi, hogy a megfelel session id vajon mr ltezik-e a szerveren. Ha ltezik a session id, akkor a session-hz tartoz elmentett rtkeket hozzrendeli a lekrt oldalhoz. A session id-t kt mdon lehet aktivizlni. 1. Vagy a PHP.INI-ben belltjuk a session.auto_start =1 rtket

40

2. Minden oldal elejn hasznljuk a session_start() fggvnyt, vagy implicit mdon a session_register() fggvnyt. Amikor a ltogat elindt egy PHP-s lekrst, a PHP motor megnzi, hogy a fenti esetekben van-e a krshez hozzrendelve egy session id. Ha van, akkor a korbban elmentett krnyezetet hozzrendeli ehhez a krshez, azaz visszalltja a megfelel vltozkat. Minden regisztrlt vltozt elment a rendszer a krs befejezdsekor. Azok a regisztrlt vltozk, amelyek nem kaptak rtket, azaz nem definiltuk ket, a nem definiltak kz kerlnek. Ezek a vltozk csak akkor kerlnek a definiltak kz ksbb is, ha a user rtket ad neki. A track_vars s a register_globals konfigurcis paramterek (PHP.INI-ben) befolysoljk a session vltozk trolsnak s visszalltsnak mdjt. Ha a track_vars engedlyezve van s a register_globals tiltva, akkor csak a $HTTP_SESSION_VARS globlis asszociatv tmbt lehet session vltozknak belltani. A visszalltott vltozk is csak ebben a tmbben lesznek elrhetk. (Ebben az esetben egy visszaltott vltoz rtkt az albbi mdon tudjuk elrni:
<?php session_register("valtozonev"); $HTTP_SESSION_VARS["valtozonev"]++; ?>

Ha a register_globals engedlyezett, akkor minden globlis vltozt session vltoznak tudunk elmenteni, s a session vltozk a kvetkez krs sorn automatikusan globlis vltozkk vlnak.
<?php session_register("valtozonev"); $valtozonev++; ?>

Ha a track_vars s a register_globals is engedlyezettek a PHP.INI-ben, akkor mind a kt fenti mdszert hasznlhatjuk, azaz a $HTTP_SESSION_VARS elemei s a globlis vltozk ugyanazokat az rtkeket tartalmazzk majd. Hogyan kezelhetjk a session id-ket? Cookie - stikkel URL parameterekkel A session modul mind a kt vltozatot tmogatja. A cooki-k az optimlisak, viszont vannak olyan kliensek, akik nem tmogatjk a cooki-k elhelyezst a gpkn biztonsgi okokbl, radsul ilyenkor a bngsz s a szerver kztt vndorolnak adatok is. Ez biztonsgi problmkat vet fel. A msodik mdszer esetn a session id az URL rsze. A PHP kpes hajlkonyan kezelni a krdst, ha megfelelen fordtottuk (--enable-trans-sid kapcsolval) Ebben az esetben a relatv URI-k megvltoznak automatikusan s tartalmazni fogjk a session ID-t (=SID). Ms esetben hasznlhatjuk a SID konstanst, amely a session_name=session_ID vagy egy res stringet tartalmaz
(pl. PHPSESSID=8e1f5ff69434aea7ecab51da33314b53&PHPSESSID=8e1f5ff69434aea7ecab51da33314b53 )

Az albbi pldban bemutatjuk, hogyan lehet regisztrlni egy vltozt s egy URI-hoz hozzrendelni a session ID-t, felhasznlva a SID-et. Plda 3. Egy user bejelentkezseit szmolja le ez a plda
<?php session_register ("count"); $count++; ?> Hello visitor, you have seen this page <? echo $count; ?> times.<p> <php?

41

# the <?=SID?> is necessary to preserve the session id # in the case that the user has disabled cookies ?> To continue, <A HREF="nextpage.php?<?=SID?>">click here</A>

Ha a fenti kdot lefuttatjuk s megnzzk a PHP.INI-ben megadott knyvtrban lv file-okat, akkor ltni fogjuk, hogy a session indulsa utn ltrejn egy file (pl. C:\temp-ben) valami hasonl nvvel, sess_8e1f5ff69434aea7ecab51da33314b53. Ez tartalmazza a session vltozk nevt s rtkt. Ez felveti azt a problmt, hogy az ilyen tpus file-ok a szerveren lv temp knyvtrban csak gylnek s korrekt lekezelsk idvel nagyon nehzz vlik. Azt is figyelembe kell venni, hogy egyes sessionok elvlnek, msokat nem lehet mg trlni, mert ppen fut alkalmazs hasznlja. A PHP.INI session rszben vannak azok a belltsok, amelyek a session file-ok elvlst, a szemtszedst s egyebeket szablyoznak. A szerver automatikusan gondoskodik egy id mlva a session file-ok trlsrl. Msfell a fejlesztket gondoltak arra is, hogy a programozk a sajt kezkbe akarjk venni a session kezelsnek lehetsgt. Erre a clra a fejlesztk megadtk a session_set_save_handler() fggvnyt, aminek paramtereivel megadhatjuk a teljes session kezel fggvnycsomagunkat. A paramterek teht azoknak a fggvnyeknek a nevei, amelyek az egyes mveleteket vgzik. session_set_save_handler ("ss_open", "ss_close", "ss_read", "ss_write", "ss_destroy", "ss_gc"); Az egyes fggvnyek feladatai a kvetkezk: ss_open ($save_path, $session_name) a kt megadott paramter tartalmazza a PHP.INI-ben megadott helyet session.save_path, s vltoznevet, session.session_name, ami a keletkezett file-t is megjelli sess_session_name alakban (lsd fenti plda) ss_close() Ezzel bezrjuk a session kezelt, nem leljk, mintha a sess_destroy()-t alkalmaznnk! ss_read($id) Ez a fggvny olvassa be a megfelel vltozkba a kulcs ltal meghatrozott sessionokhoz tartoz rtkeket. ss_write($id, $vltozonv_rtk) Ez rja bele a megfelel kulccal azonostott sessionba a vltoznv rtk prokat. ss_destroy($id) Ezt hvjuk meg, amikor trlni akarjuk egy session adatait s be akarjuk zrni a boltot. ss_gc($maxlifetime) Garbage collection algoritmus. Ha egy session lejrt, akkor az idnknt elindtott fggvnnyel letrljk a feleslegess vlt sessionok adatait. Ez pldul azrt is szksges, mert az egyes userek nem biztos, hogy megvrjk egy php oldal lefutst, hanem idnknt csak egyszeren kilpnek, megszakad a kapcsolat, vagy egyb okok is lehetnek. Ha tllpi egy session a neki sznt idt, illetve sokig nem nyltak hozz a session adataihoz, akkor azt knyrtelenl ki kell takartani. Az albbiakban kt vltozatot mutatunk be. Egyet a manualbl, amely a temp knyvtrban lv sessionokat kezeli file-okknt.
Plda a session_set_save_handler() hasznlatrl <?php // Ezzel a fggvnnyel kell berni a megfelel globlis vltozkba a session eltrolsnak // helyt s nevt function ss_open ($save_path, $session_name) { global $sess_save_path, $sess_session_name; $sess_save_path = $save_path; $sess_session_name = $session_name; return(true); }

42

// Ez nem csinl semmit function ss_close() { return(true); } //Beolvassa a session file adatait egy vltozba, amit fel lehet dolgozni, function ss_read ($id) { global $sess_save_path, $sess_session_name; $sess_file = "$sess_save_path/sess_$id"; if ($fp = @fopen($sess_file, "r")) { $sess_data = fread($fp, filesize($sess_file)); return($sess_data); } else { return(""); } } // Kirja a session adatokat egy file-ba. function ss_write ($id, $sess_data) { global $sess_save_path, $sess_session_name; $sess_file = "$sess_save_path/sess_$id"; if ($fp = @fopen($sess_file, "w")) { return(fwrite($fp, $sess_data)); } else { return(false); } } // A session file-t trljk a sessionok trolsra szolgl knyvtrbl function ss_destroy ($id) { global $sess_save_path, $sess_session_name; $sess_file = "$sess_save_path/sess_$id"; return(@unlink($sess_file)); } /******************************************************** * Figyelem! Garbage collection rutint kell ide rni! * ********************************************************/ // Itt azt vizsgljuk meg, hogy az utols hozzfrs mikor zajlott le a file-on. function expirity($filename, $now, $maxlifetime) { $last = fileatime ($filename); return ($now - $last >= $maxlifetime); } function ss_gc ($maxlifetime) { global $sess_save_path, $sess_session_name; $aktdir = dirname($PATH_TRANSLATED); $now = time(); chdir($sess_save_path); $d=opendir($sess_save_path); while($filename=readdir($d)){ if ((substr($filename,0,4) == sess_) && (expirity($filename,$now,$maxlifetime) )) unlink($filename); } closedir($d); chdir($aktdir); return true; } session_set_save_handler ("ss_open", "ss_close", "ss_read", "ss_write", "ss_destroy", "ss_gc"); session_start(); ?>

A korbbiak alapjn rthet lehet a plda. Taln az ss_gc() fggvny kicsit bonyolult. Az aktulis knyvtrt elmentjk, majd belpnk a session adatait trol helyre, ott megnyitva a knyvtrat 43

vgignzzk a file-ok neveit. A sess_ kezdet filenevek session file-okat takarnak, azoknak megnzzk s a jelenlegi idt s az utols hozzfrsnek idejt kivonva egymsbl megnzzk, hogy lejrt-e az lete.

44

Egy session kezel mkdse - plda


A tovbbiakban megnzzk egy MySQL-es sessionkezel mkdst. A mkdshez szksg van az albbi adatbzis szerkezetre:
CREATE TABLE sessions ( sesskey char(32) not null, exp int(11) unsigned not null, value text not null, PRIMARY KEY (sesskey) );

<? //Ezt a file-telbb kell lefuttatni. Mint a session_start fggvnyt! $SESS_DBHOST $SESS_DBNAME $SESS_DBUSER $SESS_DBPASS = = = = "localhost"; "sessions"; "phpsession"; "phpsession"; /* /* /* /* adatbzis adatbzis adatbzis adatbzis szerver hostneve */ neve */ user */ jelsz */

$SESS_DBH = ""; $SESS_LIFE = get_cfg_var("session.gc_maxlifetime"); function sess_open($save_path, $session_name) { global $SESS_DBHOST, $SESS_DBNAME, $SESS_DBUSER, $SESS_DBPASS, $SESS_DBH; if (! $SESS_DBH = mysql_pconnect($SESS_DBHOST, $SESS_DBUSER, $SESS_DBPASS)) { echo "<li>Nem tudok kapcsoldnia stzerverhez: $SESS_DBHOST, mint $SESS_DBUSER user"; echo "<li>MySQL hiba: ", mysql_error(); die; } if (! mysql_select_db($SESS_DBNAME, $SESS_DBH)) { echo "<li>Nem tudom kivlasztani az adatbzist: $SESS_DBNAME"; die; } return true; } function sess_close() { return true; } function global $qry = $qid = sess_read($key) { $SESS_DBH, $SESS_LIFE; "SELECT value FROM sessions WHERE sesskey = '$key' AND exp > " . time(); mysql_query($qry, $SESS_DBH);

if (list($value) = mysql_fetch_row($qid)) { return $value; } return false; } function sess_write($key, $val) { global $SESS_DBH, $SESS_LIFE; $exp = time() + $SESS_LIFE; $value = addslashes($val); $qry = "INSERT INTO sessions VALUES ('$key', $exp, '$value')"; $qid = mysql_query($qry, $SESS_DBH); if (! $qid) { $qry = "UPDATE sessions SET exp=$exp, value='$value' WHERE sesskey='$key' AND exp> " .time(); $qid = mysql_query($qry, $SESS_DBH); } return $qid; } function sess_destroy($key) { global $SESS_DBH;

45

$qry = "DELETE FROM sessions WHERE sesskey = '$key'"; $qid = mysql_query($qry, $SESS_DBH); return $qid; } function sess_gc($maxlifetime) { global $SESS_DBH; $qry = "DELETE FROM sessions WHERE exp < " . time(); $qid = mysql_query($qry, $SESS_DBH); return mysql_affected_rows($SESS_DBH); } session_set_save_handler( "ss_open", "ss_close", "ss_read","ss_write","ss_destroy","ss_gc"); ?>

A fenti kt esetben mindannyiszor hasonl paramterekkel kell meghvni a fggvnyeket: Ss_open(C:\TEMP,PHPSESSID) ezeket adja t a vltozknak The <?=SID?> is not necessary, if --enable-trans-sid was used to compile PHP. A sessionkezelsi rendszer tbb olyan belltst figyelembe vesz, amelyek a PHP.INI-jben tallhatk.
session.save_handler a session kezeljt lltja be. Default files. session.save_path meghatrozza a session file-ok trolsnak helyt. Ha a default filekezelt hasznlod, akkor a /tmp. Knyvtr lesz az. Windowsos rendszeren clszer a TEMP krnyezeti vltozt

megadni, pldul c:\TEMP.


session.name a session ltal hasznlt cookie nevet hatrozza meg. Default PHPSESSID. session.auto_start meghatrozza, hogy a session automatikusan induljon-e el, ha a PHP krs lefutott. Default 0 (nem indul el). session.cookie_lifetime meghatrozza, hogy a cookie hny msodpercig ljen a bngsz indulsa utn. A 0 azt jelenti, hogy, amg a bngsz fut. Default 0. session.serialize_handler defines the name of the handler which is used to serialize/deserialize data. Currently, a PHP internal format (name php) and WDDX is supported (name wddx). WDDX is only available, if PHP is compiled with WDDX support. Defaults to php. session.gc_probability meghatrozza, hogy a gc (garbage collection) szemtgyjt rutin milyen

szzalkkal induljon el. Az elmlt sessionok file-jai a temp knyvtrban ott maradnak s ha egy j PHP krst kap a rendszer, akkor ennek a vltoznak az rtktl fggen statisztikai valsznsggel elindul a rgi session file-ok kitrlse. Ha az rtk kicsi, akkor sok session fle is felgylhet, hiszen ritkn fut le a szemtszeds, ha nagy, akkor gyakran fut az algoritmus, teht lassab lesz a kiszolgls. Default rtk 1, tesz krnyezetben 5 10.
session.gc_maxlifetime specifies the number of seconds after which data will be seen as 'garbage'

and cleaned up.


session.referer_check determines whether session ids referred to by external sites will be

eliminated. If session ids are propagated using the URL method, users not knowing about the impact might publish session ids. This can lead to security problems which this check tries to defeat. Defaults to 0.
session.entropy_file gives a path to an external resource (file) which will be used as an additional entropy source in the session id creation process. Examples are /dev/random or /dev/urandom which

are available on many Unix systems.

46

session.entropy_length specifies the number of bytes which will be read from the file specified above. Defaults to 0 (disabled). session.use_cookies specifies whether the module will use cookies to store the session id on the client side. Defaults to 1 (enabled). session.cookie_path specifies path to set in session_cookie. Defaults to /. session.cookie_domain specifies domain to set in session_cookie. Default is none at all.

specifies cache (nocache/private/public). Defaults to nocache.


session.cache_limiter

control

method

to

use

for

session

pages

session.cache_expire specifies time-to-live for cached session pages in minutes, this has no effect for nocache limiter. Defaults to 180.

A PHP4 sessionkezelje session_start Session adatok inicializlsa session_destroy Session adatok megszntetse session_name Session nv lekrdezse, belltsa session_module_name Session kezel modul nevnek lekrdezse/belltsa session_save_path Session mentsi knyvtr lekrdezse belltsa session_id Sessin ID (SID) lekrdezse/belltsa session_register Register one or more variables with the current session session_unregister Unregister a variable from the current session session_unset Session vltozk felszabadtsa session_is_registered Megmondja, hogy egy vltoz regisztrlva van-e a sessionben session_get_cookie_params Beolvassa a session cookie parametereket session_set_cookie_params Belltja a session cookie parametereket session_decode Dekdolja a session adatokat egy stringbl session_encode Stringbe trolja le a session adatokat

47

11.5.5 COOKIE-k (stik)


A cookiek hasznlata a PHP krnyezetben lehetsges, de nem igazn ajnlott. A PHP alkalmazsok a szerveren futnak s ltalban valamifle user azonostshoz ktttek. A cookike-k hasznlata esetn a cookie-ban trolt adatok tkerlnek a bngszt futtast szmtgpre s ott egy textfile-ban troldnak, aminek a visszafejtse csak id krdse, ppen ezrt fontos vagy titkolni val adatot a cookie-kba sohas ne troljunk, inkbb hasznljunk sessionket. bool setcookie ( string nev, string ertek, int lejarat, string utvonal, sting domain, int titkos) A fenti fggvny minden paramtere az elst kivve elhagyhat. A fggvnyt a html oldal headerben kell elkldeni, mieltt az oldalra brmit kirnnk! Az albbi pldban elkldnk egy egyszer rtket: Param
Nev Ertek

Lers A sti neve

Plda 'teszt nev vltozt hozzuk ltre $_COOKIE['teszt']

Ez az rtk troldik a kliens Ezt az rtket troljuk a 'teszt' nev vltozban. $ertek oldalon =$_COOKIE['teszt'] A sti lejrati ideje msodtime()+60*60*24*2 kt napot lltunk be lejratnak. Ha percekben megadva. Belltsa nincs belltva, akkor abngsz bezrsig rvnyes a sti. time() + lejrati id. Minden bngdsz rendelkezik egy alaprtelmezett sti trhellyel. Bellthatjuk, hogy ehhez kpest hol trolja a stiket. Pldul a /fz/ az fz alknyvtrba teszi a stiket.

Lejarat

Utvonal Hol troljuk a stiket.

Domain

Az a domain, amire rvnyes a Itt adhatjuk meg, hogy melyik aldomainre legyen rvnyes a sti sti. A www.fz.ini.hu esetn csak erre a domainre rvnyes. Ha az rtk 1, akkor csak 0 vagy 1 , alaprterlmezs 0 HTTPS esetn kldi stit.

Titkos

<?php $ertek = 'Ez itt a pldaszveg'; setcookie ("teszt", $ertek); setcookie ("teszt", $ertek,time()+3600); /* egy ra mlva jr le a sti */ setcookie ("teszt", $ertek,time()+3600, "/fz/", ".fz.ini.hu", 1); /* Az /fz alknyvtrban, a www.fz.ini.hu domain s https protokoll esetn */ ?>

Tmbket is trolhatunk stikben.


<?php // A stik belltsa setcookie ("cookie[three]", "cookiethree"); setcookie ("cookie[two]", "cookietwo"); setcookie ("cookie[one]", "cookieone"); // A kvetkez oldalon betltve az albbi kddal irathatjuk ki az adatokat: if (isset($_COOKIE['cookie'])) { foreach ($_COOKIE['cookie'] as $name => $value) {

echo "$name : $value <br />\n";


} } /* Ez three two : one : */ ?> lesz az eredmny : cookiethree cookietwo cookieone

A PHP 3 esetn fordtott sorrendben kellett elkldeni a stiket, mint ahogy trolni szeretnnk, a PHP4 esetn mr a sorrend a trolsi sorrendnek megfelel. 48

A kvetkez oldalt betltve a bngszbe a stik automatikusan megjelennek a $_COOKIE tmbben, s azokat az rtkeket lehet hasznlni. Ha a register_globals paramtert bekapcsoljuk a php.ini-ben, akkor automatikusan ltrejnnek a megfelel vltozk, de korbban emltettk, hogy ennek a paramternek a bekapcsolsa nem javallott. Ha a $_COOKIE tmb rtkeit debuggols cljbl ki akarjuk iratni, akkor hasznljuk a kvetkez utastst:
<?php Print_r($_COOKIE) ?>

49

12 Konverzi Adattpusok kztt


A PHP automatikusan, s meglehetsen szabadon kezeli a tpusokat. Nha szksg lehet egy bizonyos adattpus alkalmazsra. Ekkor hasznlhatjuk az albbi mdszereket: Elrjuk a tpust, mint a C-ben:
$a = (float) $b; $c = (int) $c;

Hasznlhatjuk a bool settype ( $valtozo, tipus) fggvnyt. Ekkor a tetszleges tpus $vltoz-t tkonvertljuk az adott tpusra. A konverzi sikeressgrl bool eredmnyt ad vissza a fggvny. Lehetsges tipus rtkek:

"boolean" (vagy a PHP 4.2.0 ta "bool") "integer" (vagy a PHP 4.2.0 ta "int") "float" (csak a PHP 4.2.0 ta, korbban "double") "string" "array" "object" "null" (a PHP 4.0.8 ta)

TRUE rtket ad siker esetn, FALSE rtket egybknt.


$ize = "5valami"; // string $valami = true; // boolean settype($ize, "integer"); // $ize most 5 (integer) settype($valami, "string"); // $valami most "1" (string)

50

13 Tmbk
A tmbk, azok klnbz lehetsgei, s az azok kr felsorakoztatott fggvnyek a PHP programozs egyik legerteljesebb eszkzrendszert alkotjk, ugyanakkor rendkvl egyszeren s knnyedn hasznlhatk. A tmb vltozk halmaza, melyeket a tmbn bell sorban trolhatunk s a teljes adathalmazt egyszerre is kezelhetjk, ugyanakkor a tmb elemeihez kln-kln is hozzfrhetnk. Fontos tulajdonsga a tmbknek, hogy egy tmbn bell az elemek tpusa klnbz lehet. Egy tmb elemeit legegyszerbben explicit mdon, elemenknt tlthetjk fel:
$tomb[1] $tomb[2] $tomb[4] $tomb[5] = = = = "dBase"; "FoxPro"; "Clipper"; 42;

Lthat, hogy a tmb elemeinek megadsakor nem szksges a sorrendisget szigoran betartani. Egy tmb elemeihez a fentieknl egyszerbben is, a tmbindex hasznlata nlkl is lehet elemeket adni:
$tomb[] = "Basic"; $tomb[] = "FoxPro";

Ily mdon a tmb vghez kapcsoldnak az j elemek, az index rtke pedig az legutols indexelemnl eggyel magasabb lesz. Hasonlan mkdik az array_push() fggvny, azzal a klnbsggel, hogy egy utastson bell tbb rtket is hozzfzhetnk a tmbhz:
array_push($tomb, "Cobol", "Fortran");

Szp lassan dagad tmbnk a fenti utastsokat kveten mr gy nz ki:


Array ( [1] [2] [4] [5] [6] [7] [8] [9] )

=> => => => => => => =>

dBase FoxPro Clipper 42 Basic FoxPro Cobol Fortran

Termszetesen a tmbk rtkeinek megadshoz hasonlan frhetnk hozz a tmbelemekhez, azonban a fent emltett array_push() fggvny prja, az array_pop() fggvny is rendelkezsnkre ll, mely azonban nemcsak egyszeren a tmb utols elemt adja vissza rtkl, hanem a tmb elemeinek szmt is cskkenti az utols elemmel:
$nyelv1 = $tomb[1]; // $nyelv1 rtke "dBase" $nyelv2 = $tomb[4]; // $nyelv2 rtke "FoxPro" $nyelv9 = array_pop($tomb);// $nyelv9 rtke "Fortran" s a tmb nyolc elem lesz

Bonyoltsuk egy kicsit a dolgokat. Ezidig a tmbnk egy dimenzis volt, azonban a PHP nyelvben a tmbk kett vagy akr tbb dimenzisak is lehetnek. Az rtkads legegyszerbb mdja ilyen esetben is az explicit rtkads:
$auto[1][1] $auto[1][2] $auto[2][1] $auto[2][2] $auto[3][1] $auto[3][2] = = = = = = "Maserati"; "olasz"; "Renault"; "francia"; "Mercedes"; "nmet";

a tmb valahogyan gy fog kinzni:


Array ( [1] => Array ( [1] => Maserati [2] => olasz

51

) [2] => Array ( [1] => [2] => ) [3] => Array ( [1] => [2] => ) )

Renault francia

Mercedes nmet

Ilyen s ehhez hasonl tmbk ltrehozsra, azonban sokkal tmrebb s olvashatbb mdszer az array() fggvny hasznlata. Ez a fggvny a paramterknt megadott rtkeket tmb formban adja vissza. gy a fenti rtkadssal pontosan megegyez eredmnyt ad a kvetkez:
$auto[1] = array( "Maserati" , "olasz" ); $auto[2] = array( "Renault" , "francia" ); $auto[3] = array( "Mercedes" , "nmet" );

Ahogyan azonban a tmbelemek tpusaira vonatkozan nincsenek tl szigor megktsei a PHP nyelvnek, ugyangy nem kezeli szigoran a tbbdimenzis tmbk elemszmait sem a PHP. Az albbi rtkads teljesen helyes eredmnyt ad:
$auto[1] = array( "Maserati" , "olasz" ); $auto[2] = array( "Renault" , "francia" , "406", "206" ); $auto[3] = array( "Mercedes" , "nmet" , "E320", "Vito" , "Sprinter kisteheraut" );

Termszetesen az array_pop() s az array_push() fggvnyek az array() fggvnnyel tvzve tbb dimenzis tmbk esetn is hasznlhatk.
array_push( $auto, array("Citroen" , "francia" , "ZX" , "Xsara");

A fenti esetekben a tmb elemei azok sorszmaival voltak azonostva. A PHP ismeri az asszociatv tmbk fogalmt is. Az asszociatv tmbk rendkvl hasznos s sokoldal elemei a PHP nyelvnek. A PERL nyelvben hasznlt hash tpus tmbkhz hasonlan mkdnek. A tmbelemekre val hivatkozs ilyen esetben nem sorszmmal, hanem egy indexelem (kulcs) segtsgvel trtnik, egyszeren gy, hogy a sorszm helyre, az indexelemet helyezzk.
$tomb["els"] = "Kis Gedeon"; $tomb["msodik"] = "Nagy Elemr";

Fggetlenl attl, hogy a tmb elemeinek milyen sorrendben adtunk rtket, az elemeket az indexkulcs segtsgvel rhetjk el, s ez nem fgg attl, ha a tmbhz hozzfznk, vagy attl elvesznk egy elemet. j elem brmikor hozzfzhet a tmbhz:
$tomb["harmadik"] = "Kukonya Berk";

Az asszociatv tmbk lehetnek egydimenzisak, mint a fenti pldban, de lehetnek tbb dimenzisak is. A fenti pldt kibvthetjk tbb dimenziss:
$tomb["els"]["neve"] = "Kis Gedeon"; $tomb["els"]["kora"] = 27; $tomb["msodik"]["neve"] = "Nagy Elemr"; $tomb["msodik"]["kora"] = 22;

Ha a "Nagy Elemr" rtk elemet a $tomb["msodik"]["neve"] hivatkozssal tudjuk elrni, de ha $sorszam rtke "msodik" akkor akr $tomb[$sorszam]["neve"] hivatkozssal is elrhetjk a keresett elemet. 52

A norml s az asszociatv tmbk ltrehozsra egyarnt hasznlhat az array() fggvny, amit leginkbb tmbk kezd rtkfeltltse sorn hasznlhatunk, egy rtkadssal kikszblve tbbet. A fenti pldkkal megegyezek az albbi rtkadsok:
$tomb = array ( "els" => "Kis Gedeon", "msodik" => "Nagy Elemr"); $tomb = array ("els" => array ("neve" "kora" "msodik" => array ("neve" "kora" => => => => "Kis Gedeon", 27), "Nagy Elemr", 22) );

Mint az albbi plda is mutatja, az rtkads esetn az index rtkt nemcsak konkrtan, hanem vltozval is megadhatjuk, gy mr meglehetsen rugalmasan tthetjk fel tmbjeinket adatainkkal. A kvetkez plda megmutatja a print_r() fggvny hasznlatt is, amit tetszleges vltoz rtknek kiratshoz hasznlhatunk, de mivel tmbvltoz esetben a komplett tmbstruktrt is megjelenti leginkbb tesztelsi clokra hasznlhat nagyon jl.
<?php $nick1 = "Tabbi"; $nick2 = "Chris"; $tomb = array ( $nick1 => array("nev" => "Tabi Imre", "email" => "tabbi@freemail.hu"), $nick2 => array("nev" => "Nagy Krisztin", "email" => "chris@nomail.hu") ); echo("<PRE><b>"); print_r($tomb); echo("<HR>"); print_r($tomb["Tabbi"]["nev"]); echo("</b></PRE>"); ?> A program kimenete a kvetkez lesz: Array ( [Tabbi] => Array ( [nev] => Tabi Imre [email] => tabbi@freemail.hu ) [Chris] => Array ( [nev] => Nagy Krisztin [email] => chris@nomail.hu ) )

Asszociatv tmbk esetben azonban figyelemmel kell lenni arra, hogy ilyen tmb elemeit kizrlag a meghatrozott indexrtkkel rhetjk el, a tmb sorszmval nem. Ennek rendkvl egyszer az oka. Az egyszer sorszmozott tmb is asszociatv tmb, ahol a tmbindex maga a sorszm. St egy tmbn bell keverhetjk is a sorszmozott s az indexelt elemeket, de azrt ezt kerljk, csak gondot okozunk magunknak. A norml s az asszociatv tpus tmbk a PHP programozs sorn rendkvl vltozatosan s hatkonyan hasznlhatk, fleg akkor, ha tudjuk azt, hogy a PHP a tmbk elemeire, az elemszmokra s a tmbelemek tpusaira vonatkozan rendkvl szabad kezet ad neknk: tbbdimenzis tmbn bell az egyik index lehet asszociatv, a msik norml tbbdimenzis tmb esetben a tmbelem tmbknek nem kell felttlenl azonos elemszmaknak lenni, vagyis $tomb[1] lehet t elem, mg $tomb[2] lehet akr 8 elem is. egydimenzis tmbk esetben a tmbelemek lehetnek klnbz tpus adatok, de mg tbbdimenzis tmbk esetben sem kell a tmbelem tmbk adatszerkezetnek megegyeznie. 53

Vagyis elg nagy szabadsggal hasznlhatjuk a tmbvltozkat, mgis rdemes szem eltt tartani, hogy ha lehet, jrjunk el kvetkezetesen a vltozk rtkadsval s azok hasznlatval. A PHP nyelvben a tmbvltozkhoz is egy egsz sor fggvny s utasts kapcsoldik. Ezek a http://weblabor.hu/php/ref.array.php cmen tallhatk meg. Ezek a fggvnyek egy egsz sor feladatot lthatnak el kezdve a tmbk defincijtl az rtkfeltltsen s a tmbben val mozgson keresztl a tmbelemek legvltozatosabb md sorbarendezsig. Mivel a tmbk a PHP programozs sorn igen kiterjedten hasznlatosak, s a tmbkhz kapcsold fggvnyek fontossga kiemelked, gy ezen fggvnyekbl a fontosabbakat a kvetkez rszekben rszletesebben is trgyaljuk majd.

54

14 Sztringek, szvegek manipulcija


A tovbbiakban nhny gyakran elfordul szvegmanipulcis feladat megoldst tekintjk meg PHPban. Termszetesen sok olyan feladat van, amit mshol, mshogy mr vagy mg rintnk, illetve sok egyb, itt nem megemltett fggvny tallhat a stringkezelsnl. A pldk a php manualbl valk! Gyakori, hogy egy string hosszt meg szeretnnk tudni: strlen() Ha egy string valahny karaktert ki akarjuk venni a szvegbl, akkor a hasznland fggvny: substr() A 2. s harmadik paramter lehet negatv is. Ekkor a jelentsk a szveg vgrl rtend.
<?php $l=strlen(szevasz tavasz!);

$rest = substr("abcdef", $rest = substr("abcdef", $rest = substr("abcdef", $rest = substr("abcdef", $string = 'abcdef'; echo $string{0};
echo $string{3}; $rest = substr("abcdef", $rest = substr("abcdef", $rest = substr("abcdef", $rest = substr("abcdef", $rest = substr("abcdef", $rest = substr("abcdef", $rest = substr("abcdef", ?>

1); 1, 3); 0, 4); 0, 8);

// // // //

returns returns returns returns

"bcdef" "bcd" "abcd" "abcdef

// returns a

// returns d -1); // returns "f" -2); // returns "ef" -3, 1); // returns "d" 0, -1); // returns "abcde" 2, -1); // returns "cde" 4, -4); // returns "" -3, -1); // returns "de"

Ha ki akarom cserlni a szveg egy rszt ms rszre, akkor: substr_replace() .


<?php $var = 'ABCDEFGH:/MNRPQR/'; echo "Eredeti: $var<hr>\n"; // Beszrjuk a 'bob' szt a $var elejre echo substr_replace($var, 'bob', 0, 0) . "<br>\n"; // Ha a msodik paramter negatv, akkor a szveg vgrl indul a csere. echo substr_replace($var, 'bob', 10, -1) . "<br>\n"; echo substr_replace($var, 'bob', -7, -1) . "<br>\n"; // Trljk a szveg elejrl echo substr_replace($var, '', 10, -1) . "<br>\n"; ?>

A szvegben egyes karakterek, stringek elfordulsait kicserljk msik stringekre. Str_replace()


<?php // Eredmny: <body text='black'> $bodytag = str_replace("%body%", "black", "<body text='%body%'>"); // Eredmny: Hll Wrld f PHP $vowels = array("a", "e", "i", "o", "u", "A", "E", "I", "O", "U"); $onlyconstants = str_replace($vowels, "", "Hello World of PHP"); // Provides: You should eat pizza, beer, and ice cream every day $phrase = "You should eat fruits, vegetables, and fiber every day."; $healthy = array("fruits", "vegetables", "fiber"); $yummy = array("pizza", "beer", "ice cream"); $newphrase = str_replace($healthy, $yummy, $phrase); ?>

Ha egy string helyt akarom megtudni egy msik stringben, akkor: strpos(); Ugyanez a vgrl: strrpos() 55

Ugyanezek kis/nagybet rzketlen mdon: stripos(), strripos()


<?php $findme = 'a'; $mystring1 = 'xyz'; $mystring2 = 'ABC'; $pos0 = strpos ($mystring1, x); $pos1 = stripos($mystring1, $findme); $pos2 = stripos($mystring2, $findme); if ($pos0 === false) { echo "A '$findme' stringet nem talltam a '$mystring1' stringben"; }else{ echo "Az 'x' karakter helye: $pos0"; } // 'a' nincsen 'xyz'-ben if ($pos1 === false) { echo "A '$findme' stringet nem talltam a '$mystring1' stringben"; } if ($pos2 !== false) { echo "Megtalltuk a '$findme' stringet '$mystring2' stringben ezen a helyen: $pos2"; } ?>

Egy string kiegsztse karakterekkel: str_pad()


<?php $input = "Alien"; print str_pad($input, print str_pad($input, print str_pad($input, print str_pad($input, ?>

10); 10, "-=", STR_PAD_LEFT); 10, "_", STR_PAD_BOTH); 6 , "___");

// // // //

produces produces produces produces

"Alien " "-=-=-Alien" "__Alien___" "Alien_"

Ha egy szveg elejrl s vgrl le akarom vgni a bevezet s a zr szkzt, tab-ot, soremels karaktert, akkor a trim() fggvnyt hasznlhatom. Ha csak a szveg elejrl akarom levgni a fent emltett karaktereket, akkor ltrim(), ha a vgrl, akkor rtrim(). Az alapesetben levgand karakterekhez tovbbi kiegsztseket is rendelhetek.
<?php $text = "\t\tThese are a few words :) ... "; $trimmed = trim($text); // $trimmed = "These are a few words :) ..." $trimmed = trim($text," \t."); // $trimmed = "These are a few words :)" $clean = trim($binary,"\0x00..\0x1F"); // trim the ASCII control characters at the beginning and end of $binary ?>

rdekes lehetsg bizonyos specilis karakterek, tag-ek kihagysa a stringekbl, illetve bizonyos specilis karakterek beszrsa: Strip_tags(), htmlentities(), htmlspecialchars(),stripslashes(),
<?php $str = "Is your name O\'reilly?"; // Kivettk az idzjel karaktert. Eredmny: Is your name O'reilly? echo stripslashes($str); echo strip_tags($string, '<a><b><i><u><span><body>'); $str = "A 'quote' is <b>bold</b>"; // Kimenet: A 'quote' is &lt;b&gt;bold&lt;/b&gt; echo htmlentities($str);

//Kivettk

56

$new = htmlspecialchars("<a href='test'>Test</a>", ENT_QUOTES); echo $new; // &lt;a href=&#039;test&#039;&gt;Test&lt;/a&gt; ?>

Gyakori feladat, hogy st kell vgni egy stringet valailyen karakter mentn darabokra, pldul szavakra, ahol a szavakat hatrol karakter tbbfle is lehet. Az eredmny egy stringekbl ll tmb lesz: Explode()
<?php // Example 1 $pizza = "piece1 piece2 piece3 piece4 piece5 piece6"; $pieces = explode(" ", $pizza); print $pieces[0]; // piece1 print $pieces[1]; // piece2 // Example 2 $data = "foo:*:1023:1000::/home/foo:/bin/sh"; list($user,$pass,$uid,$gid,$gecos,$home,$shell) = explode(":",$data); print $user; // foo print $pass; // * ?>

Az albbi plda egy PHP oldalrl keresztreferencit kszt s kirja a beinclude-olt file-okat.
<?php /***************************************** * Crossreference v1.0 * It makes a crossreference list about the * variables of current script * with command line PHP interpreter. * * Copyright by Fabian Zoltan 2004 * *****************************************/ $lines = array(); $vars = array(); $terminal = array(" ","<",">","=",";",")","(",")","\"","\'","!","+","","\t","*","/","?","&",":",".","#","@","{","}","[","]","|","%",","); $ar=str_replace("\\","/",$argv); //Az sszes \\ jelet /-re cserlem $text=file($ar[1]); //Megnyitom a file-t function includes($f) { $terminal = array(" ",";","!","+","-","*","/","=","\n"); //A szveghatrol jelek listja $fileterm = array("\"","'"); $inc =array(); //includes calling $lines = array(); $out = ""; $v = ""; $token = array("include","include_once","require"," require_once"); $text=file($f); while (list ($key, $val) = each ($text)) { $lin = str_replace($terminal," ",$val); if( (strpos($lin,$token[0])>0) or (strpos($lin,$token[1])>0) or (strpos($lin,$token[2])>0) or (strpos($lin,$token[3])>0) ) { $lines[]=str_replace($terminal," ",$val); } } $i=0; /*while ($i<$sizeof($lines)){ if( ) { $out .= includes($f); }

57

$i++; } */ print_r($lines); Return $out; } // Variables crossreference function variables($text) { global $terminal,$lines,$vars; //change Terminator characters while (list ($key, $val) = each ($text)) { $lines[]=str_replace($terminal," ",$val); } $splitted =array(); $line=0; while(list($key,$row)= each($lines)) { $splitted = explode(" ",$row); //Sztvgom szavakra a sort. Az eredmny egy tmb for($i=0; $i<sizeof($splitted); $i++) { $st = $splitted[$i]; if(substr($st,0,1)== "$"){ if(!isset($vars[$st])) $vars[$st] = "->".sprintf("%4d",$line).", "; else $vars[$st].= sprintf("%6d",$line).", "; } } $line++; } ksort($vars); $out = "--------- Variables ---------\n"; while (list ($key, $val) = each ($vars)) { $out .=str_pad($key,10).$val."\n"; } Return $out; } printf(variables($text)); printf(includes($ar[1])); ?>

58

15 Formok /rlapok Interaktv programok rsa


A PHP s ltalban a WEB-es programozs egyik sarokkve volt az interaktivits megjelense. Ehhez arra volt szksg, hogy a bngsznkn bert adatokat vissza tudjuk kldeni a szervernek, amely azt feldolgozza. A HTML-ben lehet rlapokat ltrehozni az albbi szintaktikval:
<form name='Urlap' action='index.php' method='xxxx'> <INPUT ......> </form>

A fenti xxxx= vagy GET vagy POST metdus lehet. Az rlapok belsejben minden html elemet hasznlhatunk, s itt hasznlhatunk olyan beviteli mezket, amelyek vltozknak adnak rtket. A POST s a GET metdus segtsgvel a vltozk neve s rtke eljut az action-nal megjellt laphoz, amely azt fel tudja dolgozni. Az rlapon bell az albbi adatbeviteli lheetsgek vannak:
<INPUT TYPE=TEXT Name=text VALUE=Kezdszveg WIDTH=60>

Egy soros szveg bevitelre szolgl


<INPUT TYPE=PASSWORD Name=text VALUE=Kezdszveg WIDTH=60>

- Egy soros password, bevitelhez kell.

15.1.1 nmagukat meghv rlapok


Gyakori feladat, hogy egy rlapot meghvunk, leellenrizzk s a kvetkez oldalon csak akkor kldjk tovbb a bngszt, ha az oldal hibtlanul ki van tltve. Ehhez az albbi dolgoknak kell teljeslnie: Az rlapot sajt magnak kldi el a PHP oldal Amikor berkezik a krs a szerver oldalon ellenrizzk a megfelel rtkek megltt. Ha az rtkek megvannak, akkor feldolgozzuk ket Ha nincsenek meg az rtkek, akkor jra meghvjuk a feldolgozand adatot: Az albbi pldban kt rrtket kldnk el egy feldolgozand oldalnak. Ha nincs kitltve mind a kt rtk, akkor jrahvjuk a feldolgozand oldalt. A feldolgozs rszen a feldolgozott rtkek valamifle lekrdezsbe torkollnak vagy akrmilyen egyb mveletet vgezhetnk vele. Javasolt egyb mveletek: Az tadott adatok tpus szerinti ellenrzse. Erre hasznlhatk az albbi fggvnyek: is_bool() logikai-? is_int(), is_integer() egsz-e? is_float(), is_real(), lebegpontos-e? is_object() Objektum-e? is_array(). Tmb-e? Is_string() string-e? Az tadott adatokbl clszer kivenni a HTML kdokat, mivel biztonsgi problmk merlhetnek fel
<?php $string = strip_tags($string); ?>

Az tadott rtkekbl clszer kiszedni a [{()}] jeleket.

59

Ha az gy bevitt rtkek kzvetlenl SQL lekrdezsek sszelltsra hasznlatosak, akkor clszer mg egyb specilis jelek kivtele is, pldul = <> OR, AND ! stb...
$a =array([,{,(,),},],or,and,!); $str = str_ireplace($a, " ", $str);

<?php $OK=; $nev =; $pwd=; $uz =; if (isset($_POST[OK]) $OK =$_POST[OK]; if (isset($_POST[nev]) $nev =$_POST[nev]; if (isset($_POST[pwd]) $pwd =$_POST[pwd]; if ($OK =OK) { $nev =$_POST[nev]; $pwd =$_POST[pwd]; //HTML tag-ek kiszedse $nev = strip_tags($nev); $pwd = strip_tags($pwd); //specilis jelek kivtele $a =array([,{,(,),},],or,and,!); $str = str_ireplace($a, " ", $str); if (!isset($nev) or empty($nev)) if (!isset($pwd) or empty($pwd)) } if (!empty($uz)){ //Form kiiratsa print(<P>.$uz.</P>); print(<FORM METHOD=POST>); print(<Table>); print(<TR><TD>Nv:</TD><TD> print(<input type=textname=nev value=.$nev.>); print(</TD></TR>); print(<TR><TD>Jelsz:</TD><TD>); print(<input type=passwordname=pwd value=.$pwd.></TD></TR>); print(<TR><TD> </TD><TD>); print(<input type=submit name=OK value=OK>); print(</TD></TR></TABLE>); print(</FORM>); }else{ /* Feldolgozs*/ } ?> $uz =Tltsd ki a nv beviteli mezt; $uz .=Tltsd ki a jelsz beviteli mezt;

60

16 Formok adatainak feldolgozsa szerver- s kliens oldalon


A PHP-ben a HTML rlapok (FORM-ok) felhasznlsval trtnik meg az interakci a felhasznl s programja kztt. Az rlapok hasznlatnak gyakori formja, hogy az rlap a sajt magt tartalmaz oldalt hvja meg s az rlap kitltttsgt olyan kddal ellenrizzk, amely ugyanazon az oldalon van. Ez clszeren azrt lehet gy, mert a beviteli formtum s az ellenrzs is egy helyen tallhat. A pldban egy egysz tpus, 1000-nl nagyobb adatot s egy folyszmla nevet vr a beviteli oldalon a program.
Urlap.php <?php $message = ; $adat =; $ok = True; if (isset($_POST(OK) && $_POST[OK] ==Elkld){ // Ellenrizzk az adat lteznik-e s megfelel formtumak? $adat = -1; if (isset($_POST[adat])){ $adat= $_POST[adat]; if (is_int($adat)){ if (!($adat>1000)){ $ok = $ok && False; //Ezernl nagyobb rtket ellenrzk ppen $mess_adat = <FONT color=#FF0000>Tl kicsi rtk!</FONT><BR>; } }else{ $mess_adat = <FONT color=#FF0000>Hibs adattpus!</FONT><BR>; } }else{ $mess_adat = <FONT color=#FF0000>Hinyz adat!</FONT><BR>; } //Ellenrizzk, hogy a folyszmla neve megfelel-e? $fszamla = -1; if (isset($_POST[fszamla])){ $fszamla= $_POST[fszamla]; if (is_string($fszamla)){ $fszamla = $urldecode($fszamla); //Esetleges URL kdols dekdolja $fszamla = strip_tags ( $fszamla); //kiveszi a HTML s PHP tageket $fszamla = stripcslashes ( $fszamla); // kiveszi a \ jeleket //SQL injekci kiszrse!!! $keres = array (WHERE,LIKE,(,)); $csere = array ( , , , ); $fszamla = str_replace($keres,$csere,$fszamla); if (van_e_szamla($fszamla)){ $ok = $ok && False; //Ezernl nagyobb rtket ellenrzk ppen $mess_fszamla = <FONT color=#FF0000>Nincs ilyenfolyszmla!</FONT><BR>; } }else{ $mess_fszamla = <FONT color=#FF0000>Hibs adattpus!</FONT><BR>; } }else{ $mess_fszamla = <FONT color=#FF0000>Hinyz adat!</FONT><BR>; } .... itt ellenrizzk a tbbi szksges mez rtkt s ltezst ... } if(!$ok){ print(<FORM name=pelda action=urlap.php method=POST>); print($mess_adat); print(<INPUT type=text name=adat value=<% = $adat %> > ); print($mess_fszamla); print(<INPUT type=text name=fszamla value=<% = $fszamla %> > ); ... tovbbi beviteli mezk ...

print(<INPUT type=submit name =OK value=Elkld>); print(</FORM>); }else{

61

.... adatok feldolgozsa ... header("Location: http://www.example.com/"); exit; }

//A bngszt tdobom a kvetkez oldalra // a kd tbbi rsze ne fusson le

A prbeszdek alkalmazsnl fontos, hogy ellenrizzk a bevitt adatokat, mivel vletlenl, akarva vagy akaratlanul olyan adatok kerlhetnek a meghvott oldalra, aminek tpusa, formtuma nem felel meg az elvrsoknak ennek rdekben az albbi ellenrzseket clszer megtenni: Egy oldalon minden mez ki van-e tltve A megfelel tpus, formtum adat kerlt-e bele Nincs-e benne HTML vagy PHP, vagy SQL utasts kd (ezek sanda szndkok esetn szoktak bekerlni)

Az ellenrzst kt lpcsben clszer megtenni. A kliens oldalon megfelel Javascript kd segtsgvel s a szerveroldalon a PHP kd segtsgvel, mint fent is ltszik. Br a Javascript ennek a jegyzetnek nem tmja, azrt az ellenrzsre adunk pldt itt. A megolds alapja, hogy minden beviteli mez vagy a Formon lv Elkld gomb megnyomsra lefut egy ellenrz script a bngszn, ami ellenrzi, hogy ki vannak-e tltve a megfelel mezk. A Javascript ellenrzs ugyanakkor nem helyettesti a PHP oldali ellenrzst, mert a bngsz oldalon megfelel technikkkal el lehet kerlni az ellenrzst.

62

17 Levlklds, plain text, html levl, attachement


A PHP-ban van lehetsg arra, hogy leveleket kldjnk el megadott cmre, megadott tartalomal. Az zenetkldshez elszr a PHP.INI-ben be kell lenni lltani az albbi szakasz rtkeit. Az albbi sorok a Win32-es rendszeren belltandkat tartalmazza. Be kell lltani annak az SMTP szervernek a cmt kell rni, amelyik elkldi a levelnket s annak a usernek a nevt, akivel defaultban kldnk levelet.
[mail function] SMTP = mail.szily.sulinet.hu ;for win32 only sendmail_from = fz@mail.szily.sulinet.hu ;for win32 only

A levl elkldse a mail paranccsal trtnik, de mieltt elkldennk, ltre kell hozni azokat a stringeket, amelyek segtsgvel a levl klnbz szakaszai ltrejnnek.
$cimzett = fz@mail.szily.sulinet.hu; $tema = drgm; $uzenet = A klykk sszementek. Mind a kettt hiba keresem. Gza $fejlecek .= "From: Tlem <geza@kekazeg.to>\n"; $fejlecek .= "X-Sender: <birthday@php.net>\n"; $fejlecek .= "X-Mailer: PHP\n"; // Levelezprogram $fejlecek .= "X-Priority: 1\n"; // Srgs zenet! $fejlecek .= "Return-Path: <geza@kekazeg.to>\n"; //Hiba esetn ide jn levl mail($cimzett, $tema, $uzenet, $fejlecek);

A levl szvegt s a fejlcet tovbb cifrzhatjuk. A fenti mezkn kvl hasznlhatjuk pldul a cc: bc: Reply-To: s a hasonl fejlc mezket is. Hogy milyen mezket lehet hasznlni, bmelyik leveled fejlcbl kinzheted. Sajnos az attachmentek kezelse nem tartozik ele a php ltal tmogatott dolgok krbe, ezrt kls alkalmazs nlkl nem tudunk attachmentet kldeni php-ben. Egy lehetsg addik komolyabb levelezsi funkcik hasznlatra. Meg kell hvni egy kls, parancssori levelezszoftvert, amelynek a megfelel paramterezsvel tetszleges levelezsi funkckat el lehet rni. Ilyen szoftver pldul a POSTIE.EXE Windows alatt. Ez a program s ms hasonl programok az Internetrl letlthetk. A levelezs krdskrben fontos, hogy formzott leveleket is tudjunk kldeni. Erre alkalmasak a HTML levelek. A HTML levelek kldshez elg sokmindent el kell vgezni, alapesetben a PHP nem tmogatja a HTML levelek kldst, de a NET-en tallhatk egyszer objektumcsomagok, amelyek ebben az esetben segtenek (http://phpmailer.sourceforge.net) Ennek a csomagnak a hasznlatra lljon itt egy plda:
<?php require("class.phpmailer.php"); $mail = new phpmailer(); $mail->IsSMTP(); $mail->Host = "smtp.mydomain.com"; $mail->SMTPAuth = true $mail->Username = "fz" $mail->Password = "titok" // // // // // set mailer to use SMTP specify main and backup server turn on SMTP authentication SMTP username SMTP password

$mail->From = "fz@mail.szily.sulinet.hu; $mail->FromName = "Levelez"; $mail->AddAddress("XY@mail.com", "X Y"); $mail->AddReplyTo("info@mail.com", "Information"); $mail->WordWrap = 50; $mail->AddAttachment("C:\temp\text.zip"); $mail->IsHTML(true); // set word wrap to 50 characters // add attachments // set email format to HTML

63

$mail->Subject = "Ez itt a targy"; $mail->Body = "Ez a HTML szveg rsz <b>vastagon!</b>"; $mail->AltBody = "Ez a rsz a nem HTMl szveg"; if(!$mail->Send()) { echo "A szveg nem ment el. <p>"; echo "Levelez hiba " . $mail->ErrorInfo; exit; } echo "A levl elment"; ?>

A fenti csomag teleptsekor gondoskodni kell arrl, hogy a PHP.INI-ben be legyen lltva az include_path a class.phpmailer.php file-ra, amit az albbi mdon tehetnk meg futs kzben:
$incl_path = ini_get("include_path"); $incl_path .= ;./phpmailer; ini_set("include_path", $incl_path);

64

18 Adatbzisok
A PHP programozsi nyelv gy kezeli az adatbzisokat, hogy a nyelvbe beptettk az elterjedt s tmogatott adatbzis-kezelk tmogatst. Az adatbziskezelk ltalban SQL rendszerek, s kliensszerver minta szerint mkdnek egytt a PHP-val. Egy PHP-val meghajtott adatbzis-kezel rendszernek az albbiakban ehet felrajzolni a mkdsi smjt:
Szerver szmtgp /szerver oldal HDD/ adatbzis Adatbziskezel program Adatbziskezel driver PHP WEB szerver Internet felh Kliens szmtgp WEB bngsz

Egyes adatbzis-kezelket a PHP alapbl beptve tmogatja, mg msokhoz be kell tlteni a PHP.INIben a megfelel sorok segtsgvel a tmogatst. A hasznlhatsg mdja hrom fle lehet: Alapbl tmogatja a PHP az aktulis rendszert Be kell tlteni a megfelel modult A Windows verzi esetn a PHP.INI file Windows Extensions rszben az albbi bejegyzs kell:
Extensions = postgresql.dll

Linux verzi esetn az albbi sor kell:


Extensions = postgresql.so

Fordtskor be kell fordtani a tmogat modult, LIB-bl A mi esetnkben az els s msodik mdszer az, ami rdekes lehet. Termszetesen minden esetben kell telepteni egy adatbzis-szerver szoftvert, amely nem mindig ingyenes! Magyarorszgon elterjedt legfontosabb adatbziskezelk az albbiak
Adatbziskezel MySQL DBASE mSQL Ingres Interbase Microsoft SQL7.0/ 2000 Oracle8 Oracle7 Tmogats mdja Beptve Beptve be kell fordtani be kell fordtani php_interbase.dll php_mssql70.dll php_mssql.dll php_oci8.dll php_oracle.dll Az adatbzis-kezel web cme www.mysql.com www.dbase.com www.hughes.com.au www.ingres.com www.interbase.com www.microsoft.com Tulajdonsgai Free, gyors, Win s LINUX verzi ltezik A dBase 3+ verzi standard, az adatcsere llomnyok gyakori formtuma. Nem ajnlott a hasznlata les alkalmazsban Kicsi, knnyen telepthet, 14 napig free Nem free, a Computer Associates fejleszti Teljes kr, j adatbzis-kezel, ajnlhat, az InterBase 6.01 free! Rgebbi verzi, ltezik un. Personal s Evaulation Edition. Minden MS fejleszttermk rsze a Personal Edition vltozat. Nem free, teljes kr, nagy tuds SQL szerver Nem free, teljes kr, nagy tuds SQL szerver rgebbi verzii

www.oracle.com www.oracle.com

PostGres SQL ODBC

php_pgsql.dll Beptve

www.postgresql.org.

LINUX s Windows verzi is van, free, teljes SQL rendszer Az ODBC = Open DataBaseConnectivity A Microsoft ltal ltrehozott, elvileg platform s adatbzis-kezel fggetlen fellet, minden elterjedt adatforrsnak van ODBC drivere. Win s Linux alatt is lteznek ODBC driverek

65

18.1 MySQL
A fenti adatbzis-kezelkrl annyit, hogy jelenleg a legelterjedtebb ilyen alkalmazs a Linuxon, Netware-en s Windows rendszereken is fut MySQL. Ez a rendszer taln a leggyorsabb az sszes elterjedt adatbzis-kezel kztt, de jelenleg a (MySQL 4.0.*) MySQL nem valstja meg az SQL sszes lehetsgt, s nem tmogatja a trolt eljrsokat, tovbb a tblk kztti lland (perzisztens) kapcsolatokat, csak egy specilis fajta adatbzis esetn (InnoDB). Ez a WEB-es alkalmazsok esetn nem tlsgosan nagy baj, mert azok tipikusan nem adatmdostssal foglalkoznak, hanem inkbb lekrdezssel, ebben pedig a MySQL nagyon gyors. A hrek szerint a MySQL 5.0 a fenti hinyossgokat kikszbli. A MySQL nagyon elnys tulajdonsga, hogy GNU liszensszel lehet hasznlni, azaz akkor is free, ha eladsi cllal hasznljuk, de magt a MySQL adatbzis-kezel programot nem adjuk el ( J). Mirt is tennnk, ha egyszer az Internetrl letlthet. A MySQL letlthet az albbi cmrl: http://www.mysql.com/downloads/mysql-4.0.html Teleptse egyszer Windowson el kell indtani a ZIP-bl val kicsomagols utn a SETUP.EXE programot, a tbbit elkszti . Ha firewall van a gpnkn, akkor a TCP/IP 3306-os portjt kell szabadd tennnk. Ha a szerver ugyanazon a gpen fut, mint amelyiken a WEB szervert s a PHP-t futtatjuk, akkor a Firewallon nem szabad (!) engedlyezni ms gprl ehhez a porhoz val hozzfrst. Ha fejleszts kzben az adatbzisunkat mdostani akarjuk, klnbz dolgokat akarunk elvgezni, akkor ajnlhatjuk a free phpMyAdmin nev csomagot, illetve a professzonlis, de pnzes EMS MySQL Manager programcsomagot. Magban a MySQL csomagban is van egy WinMySQLAdmin nev elgg bugyuta alkalmazs. Ha feltesszk a MySQL ODBC drivert, akkor viszont tetszleges ODBC kompatibilis alkalmazsbl el tudjuk vgezni az adatok mdostst, feltltst stb... Akr ez lehet egy Microsoft Access is. A MySQL hasznlathoz dokumentcit innen lehet letlteni: http://www.mysql.com/get/Downloads/Manual/manual.chm-2002-10-07.zip/from/pick

18.2 PostGres SQL


A PostGres SQL egy kicsit komolyabb alkalmazs, mint a fent emltett adatbzis-kezel. A teleptse sajnos nem egyszer, mivel alapveten Linux-ra rdott program. A telepts menett Molnr Lszl PHP listn kzlt lersa alapjn kzlm.
1. Letoltod: http://www.cygwin.com/setup.exe 2. Ha megvan elinditod a setup.exe -t Lassuk a telepitest: - Indulas utan kerdezi, hogy mit tegyen: * Install from internet * Download form internet <- EZT VALASZD * Install form local directory Megkerdezi, hogy hova telepitsen (oda teszed ahova akarod) Kivalasztod a kapcsolatot Ha keri kivalasztasz egy szimpatikus mirrort ekkor letolti a setup.bz2-t Most jon a lenyeg elso fele SELECT PACKAGES A + jelekre kattintva kijeolheted, hogy mit toltson le ha kibomlik a lista, a 'Skip' szra kattintva kijeloli - itt celszeru minden kijeolni hiszem most csak letoltod a csomagokat. - ha Tovabb lepsz szepen elkezd tolteni. (A teljes csomag lehet, akr 180 MB is!) Ha mr letltttl minden csomagot, johet a telepites: Ujra futtasd a korabban letoltott setup.exe -t. - Most valaszd az Install from local directoy -t - Add meg a root konyvtarat. (default: c:\cygwin) - Add meg a csomagok helyet. (pl: f:\ftproot\ftp%3a%2f%2fftp.univie.ac.at%2fpackages%2fcygwin) - Jelld ki azokat a csomagokat, amire szksged lehet, illetve van, amit nem szabad kihagyni:

66

Archive - zip / unzip Database - postgresql !!!!!!!!! EZT NE HAGYD KI. EZERT JOTTEL :-)) Editors - valassz egyett. vagy mind :-)) Utils - bzip2 - ha nem teszed fel kesobb bajba lehetsz! - Ha kivalasztottad a szukseges csomagokat mehet az telepites (csak kattints a Tovabb gombra :-)))) Telepites kesz johet a postgreSQL. - most mart indulhat: futtasd: C:\cygwin\cygwin.bat - es lass csodat ott a cygwin prompt. (Bshell prompt) Johet a inicializalas: $ ipc-daemon2 & $ initdb -D /var/pgsql/data Ez is kesz! Akkor lassuk a medvet: FIGYELEM! az 'ipc-daemon &' mindig ki kell adni ha nem fut :-)) Ezt eleg 1x megtenni amikor einditod a cygwin -t. Az server inditasahoz itt egy indito script, a neve s elrsi helye: c:\cygwin\bin\pg_start #!/bin/bash ipc-daemon2 & postmaster -i -D /var/pgsql/data >/var/log/pgsql.log & Telepiteskor 1 usert felvesz a szerver, azt aki teleptette, teht pl. magyar WinXP-n Rendszergazda. Ha elinditod pl. pgAdmin3-t, amit szintn le lehet tlteni a NET-rl, pldul innen: ftp://ftp2.cz.postgresql.org/pub/postgresql/pgadmin3/release/win32/pgadmin3-1_0_1.zip Server: localhost Port: 5432 User: Rendszergazda <Login> Ksz.

A PostgresSQL hasznlathoz dokumentcit az albbi helyen lehet elrni: http://www.postgres.org/docs/ Itt HTML s PDF formtumban vannak meg a megfelel dokumentumok.

67

18.3 Adatbzis-kezels natv mdon


Az adatbzis-kezelk hasznlathoz a PHP.INI-ben meg kell adni a megfelel belltst (vagy, mint pldul a MySQL-nl, eleve a tmogats a rendszer rsze), s programunkban hasznlhatjuk az adatbzisra vonatkoz utastsokat. A PHP az adatbziskezelsre ltalban az albbi utastsfajtkat tartalmazza. Az adatbzis-kezel szerverrel kapcsolatot teremt, a kapcsolatot lezr parancsok Az adatbzisokra vonatkoz lekrdez s adminisztrcis parancsok Egy megnyitott adatbzisra vonatkoz adminisztrcis s lekrdez parancsok Az SQL lekrdezseket tkld parancs A lekrdezs eredmnyt feldolgoz parancsok.

A tovbbiakban a MySQL utastsai alapjn mutatom be az adatbziskezelssel kapcsolatos utastsokat. Ms adatbziskezel esetn a vltozs ltalban csak annyi, hogy a nvben az eltag ms. Pldul:
Mysql_connect() //MySQL adatbzis-kezel esetn pg_connect() //PostgresSQL

Kapcsolds egy adatbziskezelhz, amely vagy loklis gpen helyezkedik el, vagy egy tvoli, IP cmmel meghatrozott gpen. A kapcsolat ltrehozsa meg kell adni a kapcsoldsi helyet (localhost, vagy IP cm), a kapcsold user-t, s a user jelszavt.
$link = mysql_connect(localhost,$username,$password);

vagy
$link = mysql_pconnect(localhost,$username,$password);

A fentiekhez egy kis magyarzat. A connect s pconnect kztt az a klnbsg, hogy a connect-tel megnyitott kapcsolat lezrul a krdses php oldal lefutsa utn, mg a pconnect kapcsolat nyitva marad (Persistent connection), s jbli kapcsolds sorn csak akkor kell egy viszonylag sokig tart kapcsoldsi procedrn tmennie a rendszernek, ha a kapcsolat nincsen nyitva. Egybknt a pconnect hasznlata ugyanaz, mint a connect-. A visszaadott rtk a kapcsolat sorszma. Ennek alapjn lehet a tovbbiakban azonostani tbb megnyitott kapcsolat esetn, hogy ppen melyik kapcsolatot hasznljuk. A kapcsolat bezrsa:
mysql_close($kapcsolat)

Plda
<?php $link = mysql_connect ("kraemer", "marliesle", "secret") or die ("Could not connect"); print ("Connected successfully"); mysql_close ($link); ?>

Az adatbziskezeln lv adatbzisokra vonatkoz parancsok


int mysql_list_dbs ([int link_identifier]) int mysql_create_db (string database name [, int link_identifier]) int mysql_drop_db (string database_name [, int link_identifier]) <?php $link = mysql_pconnect ("kron", "jutta", "geheim") or die ("Could not connect"); if (mysql_create_db ("my_db")) { print ("Database created successfully\n");

68

} else { printf ("Error creating database: %s\n", mysql_error ()); } ?>

int mysql_select_db (string database_name [, int link_identifier])

Egy konkrt adatbzis tblinak kilistzsa Egy adatbzis (lekrdezs) oszlopneveinek listzsa. Ugyanez az utasts a lekrdezs eredmnynek tetszleges adatait is kilistzza ...
object mysql_fetch_field (int result [, int result_type])

Meznevek kirsa, s trolsa a mezonev tmbben


<?php $result=mysql_db_query($querydb,$query); $m=mysql_num_rows($result); $n=mysql_num_fields($result); for($i=0;$i<$n;$i++) { //Oszlopnv/meznv bemsolsa tmbbe ksbbi felhasznlsra $mezok=mysql_fetch_field($result); $meznev[]=$mezok->name; //Oszlop/Mez adatainak kilistzsa. echo "<PRE> blob: $meta->blob max_length: $meta->max_length multiple_key: $meta->multiple_key name: $meta->name not_null: $meta->not_null numeric: $meta->numeric primary_key: $meta->primary_key table: $meta->table type: $meta->type unique_key: $meta->unique_key unsigned: $meta->unsigned zerofill: $meta->zerofill </PRE>"; } mysql_close(); ?>

Egy SQL parancs elkldse


resource mysql_query ( string query [, resource link_identifier])

Az Adatbziskezelnek adott SQL, vagy egyb utasts eredmnynek tvtele a pufferbl. Az eredmny ltalban kt dimenzis tmbbe rkezik, amelyet vagy a tmbkezel fggvnyek segtsgvel lehet feldolgozni, vagy indexel s ciklussal vgig kell szaladni rajta. A visszaadott paramterrl mindig meg tudjuk mondani, hogy hny sorbl ll. Az albbi fggvny megadja az eredmny sorainak szmt. Ha nincs eredmny sor, akkor az rtke 0.
int mysql_num_rows()

Ha Delete, Update utastsok eredmnyre vagyunk kivncsiak, akkor az albbi fggvnyt kell hasznlnunk.
int mysql_affected_rows ( [resource link_identifier])

Egy sort ad vissza egy tmbbe az albbi fggvny. A tmb t sorszmokkal lehet indexelni, a sorszmozs 0-val kezddik. Akkor hasznlhatjuk, ha egy lekrdezsrl nem tudjuk elre, hogy hny sort ad majd vissza.
array mysql_fetch_row([resource link_identifier])

69

Ennl a fggvnynl szksgnk lehet a visszaadott oszlopok szmra is. Ezt az albbi fggvnnyel tudjuk meg:
int mysql_num_fields ( [resource result])

Ez a fggvny a sort szintn egy tmbben adja vissza, de a tmbelemek sorszmozva s a meznvvel is, mint asszociatv tmbindexxel elrhetk.
array mysql_fetch_array([resource link_identifier)

Az albbi plda elkld egy lekrdezst, az eredmny oszlopneveit lekrdezi, majd megjelenti tblzatos formban.
int mysql_fetch_object([resource link_identifier])

Az albbi plda elkld egy lekrdezst, az eredmny oszlopneveit lekrdezi, majd megjelenti tblzatos formban.
<?php ...... $qry = SELECT * FROM tabla; $result=mysql_db_query($qry,$query); $m=mysql_num_rows($result); $n=mysql_num_fields($result); echo <TABLE><TR>; for($i=0;$i<$n;$i++) { $mezok=mysql_fetch_field($result); echo "<TD>".$mezok->name."</TD>"; $meznev[]=$mezok->name; } echo"</TR>"; // mezok kiirasanak vege // // mezokben levo adatok kiirasa // for($i=0;$i<$m;$i++) { echo"<TR>"; $adat=mysql_fetch_array($result); for($j=0;$j<$n;$j++) echo "<TD>".$adat[$meznev[$j]]."</TD>"; echo"</TR>"; } echo </TABLE>; ?>

18.4 Tipikus feladatok adatbzis-kezelsnl


Egy adatbzis-kezel hasznlata sorn az albbi tipikusnak mondhat feladatokat kell megoldani PHPban, (de hasonlkppen ms programozsi nyelveken is). Kapcsoldunk a szerveren lv adatbzishoz.(lttunk mintt hozz) Elkldnk egy SQL lekrdezst az adatbzis-kezel programnak (Lttunk mintt) Az elkldtt lekrdezsre kapott vlasz ltalban egy tblzattal, vagy kt-dimenzis tmbbel reprezentlhat. Ezt szoks rekordszet-nek hvni. Egy ilyen rekordszetet megjelentnk, clszeren tblzatos formban. Ha a rekordszet tl sok sorbl ll, akkor vagy a lekrdezskor adunk olyan feltteleket, amely kevesebb sort ada eredmnyl, vagy megalkotjuk annak a lehetsgt, hogy a tblzat eredmnyt grgetni, vagy lapozni lehessen. (ksbb ltalnos mintt lttunk, az elz fejezetben bizonyos specilis eseteket nztnk) A rekordszet egyes sorait rlap formjban meg akarjuk jelenteni (ksbb ltunk mintt a fejezetben) Az rlap vagy a rekordset eredmnyt ki akarjuk nyomtatni Az adatbzisba j adatot akarunk bevinni. 70

o Egy rekordszethez illeszked j sorral o Egy rekordszethez illszked j sor-rlap formjban bevitt adatokkal. o Minden adatbevitelnl valamilyen tipizlhat ellenrzsi feladatot illik elvgezni, vagy a bevitt adatokat szintaktikailag s/vagy szemantikailag ellenrizni illik. o Adatok bevitelekor vagy mdostskakor, amikor csak lehet az adatokat egy felknlt listbl kelljen kivlasztani a tvedsek elkerlse miatt. Adatok mdostsa lehetsg szerint az j adat bevitelvel azonos formtumban s mdon trtnjen. Egyes adatok, adatsorok, rekordok trlse, ellenrztt mdon. Az adatok bevitele vagy mdostsa sorn, hibs adatfelvitel miatti ismtlskor a korbban bevitt vagy meglv adat jelenjen meg a beviteli rlapon.

A fenti feladatokhoz az albbi nem igazn PHP-ben megvalstott fogalmakat trsthatunk: Az adatok tblzatos megjelenshez az albbi sma szerint rdemes eljrni abban az esetben, ha kt dimenzis tblzatban kapom meg az adatokat.
Print( <table>); For($i=0;i<$maxsor;$i++){ Print(<tr>); For($j=0;$j<$maxoszlop; $j++);{ Print(<td>); Print(adat[$i][$j]); Print(</td>); } Print(</tr>); } print(</table>);

Termszetesen a tblzat formzst, a szeglyeket, stb mindenki a sajt zlse szerint alkothatja meg. Ha az adatokat soronknt vezsem t az adatbzis-kezeltl, akkor a fenti algoritmus kicsit megvltozik. Azt is megmutatom a kvetkez pldban, ha nem az oszlopok szma adott a lekrdezett rekordszetben, br ezt is mindig meg lehet tudni egy adott esetben, hanem a meznevekkel, asszociatv mdon tudok hivatkozni egy sorra. Erre az elz fejezetben lttunk pldt.
<?php //egyszer rekord megjelentse $result=mysql_db_query($querydb,$query); $sor=mysql_num_rows($result); $n=mysql_num_fields($result); print(<table>); for($i=0;$i<$n;$i++) { print(<tr>); //Oszlopnv/meznv bemsolsa tmbbe ksbbi felhasznlsra $mezok=mysql_fetch_field($result); $meznev[]=$mezok->name; //Oszlop/Mez adatainak kilistzsa. print(<td align=right>); print($meznev[$i]); print(</td>) print(<td>); print($sor[$meznev]); print(</td>) print(</tr>); } print(</table>); mysql_close(); ?>

//A mez neve

//A mez rtke

A fenti megjelents mg elemi mdomn sem alkalmas j adatok bevitelre, hiszen j adatokat WEB bngsz esetn csakis FORM-okon keresztl vihetnk fel. Mindezek mellett meg kell oldanunk a 71

mezk ellenrzst is. Ennek megfelelen mdostanunk kell a fenti megoldst kiss. A pldrl annyit, hogy egy rlap jelenik meg, amely a megjelenti a mezket egy INPUT HTML tag segtsgvel, amivel a z rtket rgtn mdostani is lehet. A bevitt adatokat minden mez esetn a bngsz javascript kdja rgtn ellenrzi is (Hogy egyltaln ki van-e tltve). Ha nincsen kitltve, akkor hibazenet rkezik.
<HTML> <HEAD> </HEAD> <SCRIPT LANGUAGE="JavaScript1.2" type="text/JavaScript1.2"> function elenoriz() { var k=document.form1.text.value; if (k.length<1){ alert("Nincs kitltve az adat!!"); return false; } else{ return true; } } </SCRIPT> <BODY> <?php //egyszer rekord megjelentse $result=mysql_db_query($querydb,$query); $sor=mysql_num_rows($result); $n=mysql_num_fields($result); print(<FORM name=form1 ACTION=urlap.php method="get" "> print(<table>); for($i=0;$i<$n;$i++) { print(<tr>); //Oszlopnv/meznv bemsolsa tmbbe ksbbi felhasznlsra $mezok=mysql_fetch_field($result); $meznev[]=$mezok->name; //Oszlop/Mez adatainak kilistzsa. print(<td align=right>); print($meznev[$i]); //A mez neve print(</td>); print(<td>); print(<INPUT name=\".$meznev[$i]."\ type=\"text\" value=\.$sor[$meznev].\ onchange=\javascript:ellenoriz(.$meznev[$i].)\>); print($sor[$meznev]); print(</td>) print(</tr>); } print(<tr>); print(<td>); print(<INPUT name=\"OK\" type=\"submit\" value=\"Ok\">); print(<INPUT name=\"Trls\" type=\"reset\" value=\"Mgse\">); print(</td>) print(<td>); print(</td>); print(</tr>); print(</table>); mysql_close(); ?> </BODY> </HTML> //A mez rtke

72

18.5 Hibakezels
A MySQL szerver a lekrdezsek sorn hibakdot s szveges zenetet is kld vissza a kliensnek. A hibk kezelsre az albbi fggvnyewk hasznlhatk:
string mysql_error ([int link_identifier])

A MySQL szerver ltal visszaadott hiba szvegesen


int mysql_errno ([int link_identifier])

A MySQL szerver ltal visszaadott hiba kdja.


<?php mysql_connect("marliesle"); echo mysql_errno().": ".mysql_error()."<BR>"; mysql_select_db("nincsadatbazis"); echo mysql_errno().": ".mysql_error()."<BR>"; $conn = mysql_query("SELECT * FROM nincsadattabla"); echo mysql_errno().": ".mysql_error()."<BR>"; ?>

A fenti lehetsgek csak a MySQL-re vonatkoznak, de hasonlan lehet hasznlni ket ms adatbzisok esetn is.

18.6 Adatbziskezels mskppen absztrakcis rtegek, ADODB, ODBC


Fontos krds, hogy mit tegynk akkor, ha elre nem tudjuk, hogy milyen adatbziskezelt fogunk hasznlni az oldalunkon, vagy ha hozzszoktunk olyan adatbziskezelkhz, mint pldul az ADODB rendszerhez Microsoft Windows krnyezetben. Alapvet dolog, hogy az egyes adatbziskezelk ltalban az SQL szintakszis szerint mkdnek, teht ha ksztnk egy olyan programcsomagot, amely eltakarja ellnk az adatbziskezelk kzti klnbsgeket, akkor tudunk erre alapozva olyan alkalmazst rni, amelynek mindegy, hogy melyik adatbziskezelt hasznlja. Ez az absztrakcis rteg alkalmazsnak mdszere

18.6.1 Az absztrakcis rteg


A konkrt adatbziskezeltl fggetlen olyan utilitycsomag, amely eltakarja az adatbzis-kezelk kztti klnbsgeket, kiegszti azokat plusz funkcikkal knyelmesebb teszi az adatbziskezelssel kapcsolatos programozst. Persze felmerl a krds, hogy vajon nem, lasstja-e le nagyon a programjaink futst egy ilyen rteg alkalmazsa. Megnyugtathatjuk a kedves olvast, hogy brmifle absztrakcis rteg lasstja a rendszert, de csak olyan csekly mrtkben, hogy a lassuls szrevehetetlen, csak extrm nagy szerver terhels, mellett szrevehet, ugyanakkor az alkalmazsfejleszts nagysgrendekkel meggyorsul. Ilyen egyszer absztrakcis rteget tbbet is lehet tallni az interneten:

18.6.2 ODBC programcsomag


A Microsoft mr korbban megvalstott egy adatbziskezels esetn jl hasznlhat absztrakcis eljrst, ez pedig az ODBC driverek csoportja Az ODBC driverek olyan meghajtk, amelyek a windows rendszerre teleptett (szinte) tetszleges adatbziskezelt egysges mdon rnek el. Ennek megfelelen az ilyen drivert hasznl alkalmazsok a Windows rendszeren az SQL szerver mdostsval is mkdnek, ODBC-n keresztl rik el ket. Hasznlatuk: 1. Ltre kell hozni az adatbzist valamilyen adatbziskezelvel: Egy windows rendszeren lehet, Access, MSSQL, MySQL, PostgresSQL, InterBase SQL, vagy brmi ms, amelynek ltezik ODBC drivere. 73

2. Ltre kell hozni egy ODBC kapcsolatot. Ezt az ODBC kezelvel tehetjk meg. A klnbz Windows verzik esetn ez mshol van, de alapveten a Vezrlpult krnykn kell keresni ODBC adatforrsok vagy hasonl nven. Az albbiakban a Windows XP magyar verzijbl vesszk a pldt:

A fenti belltsokkal most egy MySQL adatforrst adtunk meg. Ezek utn az ODBC adatbziskezelt kell hasznlni a PHP-ban. Az ODBC csomag rszletes lerst lsd az albbi helyen: http://www.php.net/manual/hu/ref.odbc.php

18.6.3 Az ADODB rtegezs


(Az albbi lerst az eredeti ADODB manual fordtsval s rvidtsvel ksztettem el.) Az ADODB a Microsoft ltal kifejlesztett adatbziskezelsi programcsomag, amely egyesti az SQL adatkezels s a kliens oldali adatelrs elnyeit. A lnyege, hogy az adatbziskezeltl lekrdezsekkel kapott eredmnyeket rekordszeteket nem csak szekvencilisan dolgozhatunk fel, hanem vletlen elrssel brmelyik rszt elrhetjk. Segtsgvel knnyen tudunk grdthet menket, listboxokat s ehhez hasonl objektumokat kszteni grafikus rndszerben. Az phpADODB knyvtrszerkezete ehhez hasonl funkcikat valst meg. Az ADOdb for PHP-hez legalbb PHP 4.0.2 kell. Hasznlatnak elnyei: 74

Knnyen hasznlhat a windowson programozknak, mivel szintaktikja hasonlt a Microsoft fle ADODB-hez. A PHP natv adatbzis-kezelse fel egy rteget von, ami nem lasstja le lnyegesen az adatbzis elrst, viszont tetszleges adatbzison azonoss teszi az adatbziskok kezelst. Nem csak lekrdezsekre, hanem Update s Insert utastsokra is jl hasznlhat. Tmogatja a PHP4 sessionjt. Alapvet adattpusokkal dolgozik ez is a klnbz rendszerek kompatibilitst segti el.

Teleptse: Az ADODB library-t letlts utn be kell tenni az adodb alknyvtrba, vagy a PHP include library-jai kz. Ez utbbi esetben a PHP.ini file-t meg kell szerkeszteni egy kicsit:
; Windows: "\path1;\path2" include_path = ".;i:\phplibs;i:\phplibs\adodb;"

Ekkor az albbi formt lehet hasznlnunk, mivel a PHP elri mindig az ADODB-t.
<?php include('adodb.inc.php'); $db = ADONewConnection('mysql'); $db->debug = true; $db->Connect($server, $user, $password, $database); $rs = $db->Execute('select * from some_small_table'); print_r($rs->GetRows()); ?>

Ha nem tudjuk library-be tenni, akkor egy alknyvtrba tesszk az ADODB programcsomagot.
<?php include('adodb/adodb.inc.php'); $db = ADONewConnection('mysql'); $db->debug = true; $db->Connect($server, $user, $password, $database); $rs = $db->Execute('select * from some_small_table'); print_r($rs->GetRows()); ?>

A scriptben az
include(adodb/adodb.inc.php);

utastssal mondjuk meg a scriptnek, hogy ADODB adatbzist fog kezelni a program. Az adatbzis tpust az
$conn = ADONewConnection('mysql') vagy a $conn = &ADONewConnection(' mysql');

formt hasznlhatjuk a kapcsolat ltrehozsra. Ennek hatsra ltrejn a $conn nev objektum, amely minden olyan paramtert s metdust tartalmaz, ami a ksbbi kezelshez szksges. Amennyiben egy msik oldalon jra szksgnk van ennek az objektumnak az adataira, az objektumot clszer lementeni sessionba, majd a kvetkez oldal elejn jra betlteni. Feltve azt, hogy az objektum definici mr lefusson, amikor a session elindul, teht, ha van egy ltalnos session kezel rutincsomagunk, akkor a helyes includolsi sorrend az albbi:
include(adodb.inc.php); include(session.php);

75

Az albbi tblzat a leggyakrabban elfordul adatbzisokat sorolja fel.


Nv access ado ll. Adatbzis-kezel B B Microsoft Access/Jet. You need to create an ODBC DSN. Rekord sorsz Y/N Hivatkozs, kliens ODBC Op.rend. W

ltalnos Microsoft ADO, nem specializlva semmilyen Adatbzistl ADO, OLEDB W adatbzisra. Lehet DSN-nlkli Lehetsg szerint OLEDB fgg adatforrs adatbzis. Kapcsolds eltt lltsd be a $db->codePage rtket. Microsoft Access/Jet ADO, DSN-nlkli kapcsolat. Hasznlj Y/N OLEDB adatbzist. Microsoft SQL Server ADO-t hasznlva, DSN-nlkl Microsoft Visual FoxPro. ODBC DSN-nel Microsoft SQL Server 7 / 2000. A dtumok kezelse problms MySQL tranzakci nlkl! MySQL tranzakcival. Y/N Y/N Y/N Y/N Y/N ADO,OLEDB W adatforrs ADO,OLEDB W adatforrs ODBC Mssql client W

ado_access B ado_mssql vfp mssql mysql mysqlt, maxsql oci8 B A A A A A

U, W

MySQL client U, W MySQL client U,W Oracle client U, W

Oracle 8/9. Jobb, mint a tbbi oracle driver. Hasznlnod kell az Y/N albbi parancsot: putenv('ORACLE_HOME=...') Connect/Pconnect eltt. Ktfle kapcsolds ltezik: IP s szerviz nvvel: PConnect('serverip:1521','scott','tiger','service') vagy TNSNAMES.ORA s ONAMES vagy PConnect(false, 'scott', 'tiger', $oraname).

HOSTNAMES: ? depends on ODBC database Y/N Y/N Y/N Y Y ODBC ODBC Oracle client PostgreSQL client PostgreSQL client W,U U,W U, W U, W U,W U,W

odbc

ltalnos ODBC parancs kapcsolds: Connect('DSN','user','pwd'). ODBC, MSSQL kapcsolattal ODBC Oracle kapcsolattal Oracle 7. Jobb az oci8 driver. PostgreSQL 6.4 s kjorbbi esetben LIMIT internally. PostgreSQL7 illetve ksbbi.

odbc_mssql C odbc_oracle C oracle postgres64 postgres7 C A A

A = Jl bevlt, hasznlatos B =Tesztelt, de bizonyos rszei mg nincsenek kszen C = Mg kisrleti llapotban van W= windows U = Unix/Linux Ha a fenti adatbzisok egyikt hasznljuk ADODB-vel, az albbi lehetsgeink vannak A tovbbiakban nzznk egy programot, amely a Microsoft Acces-hez adott NorthWind adatbzisbl egy lekrdezst hajt vgre, vgigmegy a rekordokon s ha dtum vagy id tpus mezt tall, akkor azt megfelel formtumban rja ki.

76

<?php include('adodb.inc.php'); $conn = &ADONewConnection('access'); # Kapcsolat ltrehozsa $conn->PConnect('northwind'); # MS ACCESS-hez kapcsoldunk, northwind dsn-nel $recordSet = &$conn->Execute('select CustomerID,OrderDate from Orders'); if (!$recordSet) print $conn->ErrorMsg(); # Hibazenet, ha nincsen eredmnye a lekrdezsnek else while (!$recordSet->EOF) { $fld = $recordSet->FetchField(1); # Az els mez beolvassa $type = $recordSet->MetaType($fld->type); if ( $type == 'D' || $type == 'T') print $recordSet->fields[0].' '. $recordSet->UserDate($recordSet->fields[1],'m/d/Y').'<BR>'; else print $recordSet->fields[0].' '.$recordSet->fields[1].'<BR>'; $recordSet->MoveNext(); } $recordSet->Close(); # optional $conn->Close(); # optional ?>

A $conn ADO objektumhoz a


$conn->Pconnect(northwind)

metdus kapcsolja hozz a Northwind adatbzist, ami termszetesen elrhet a windowsos rendszerben. Az adatok lekrdezst az
$recordSet = $conn->execute(select * from Orders) ;

metdus hajtja vgre. Ez a $recordSet vltozba visszatr egy ADO rekordszet objektummal. Ha valamilyen ok miatt nem jn ltre a rekordszet, akkor azt le lehet krdezni, s hibakezelst lehet vgrehajtani. A rekordszetnek van kurzora. Ez a kurzor jelli meg az aktulis rekordot. A kurzort
$recordSet->MoveNext()

metdussal tudom tovbb mozgatni. A sorok kztti mozgst tovbbi parancsok is knnytik:
$recordSet->Move($n)

- az aktulis sorhoz kpest n sorral ugrik tovbb a kurzor kvetkez sorra lp a kurzor els sorra ugrik a kurzor Egy abszolt mdon megadott sorra ugrik Az aktulis sor szmt adja vissza utols sorra ugrik a kurzor

$recordSet->MoveNext()

$recordSet->MoveFirst() $recordSet->MoveLast()

$recordSet->AbsolutePosition (n)

$sorszm = $recordSet->CurrentRow ()

A FetchField fggvny teszteli le a mezk tpust. 3 elem objektumot ad vissza. name: oszlop neve type: az eredeti meztpus max_length: a mez max. hossza. Nha nem ad vissza semmit (pl. MySQL)

A MetaType() lefordtja az eredeti tpust ltalnos ADODB tpusra. Az albbi generic tpusok lteznek: C: szveg, a <input type="text"> taggal jelenthet meg X: TeXt, nagy szveg, a <textarea> taggal jelenthet meg B: Blobs, Binary Large Objects. ltalban kpek. D: Dtum T: Idblyeg 77

L: Logikai (boolean vagy bit mez) I: Egsz N: Numerikus, illetve autoinkrementlis. R: Sorozat tpus. Lehet sorozat vagy, autoinkrement egsz.

Dtum vagy Idblyeg esetn a UserDate() fggvny konvertlja s kirja a megfelel formtum idt. 18.6.3.1 Lapozs ADODB-ben

Akkor hasznlhatjuk a z ADODB lapoz funkcijt, ha beincludoljuk az adodb-pager.inc.php fggvnyt. A rekordszet lapokra bonthat, minden lap megadott szm sorbl ll. A lapok kztt is lehet mozogni. Bool AtFirstPage() True, ha az els lapon vagyunk Bool AtLastPage() - True, ha az utols lapon vagyunk $page= AbsolutePage(n) Megadott lapra ugrik. Ezt Az albbi viszonylag egyszer plda ezt mutatja be:
<?php include_once('adodb.inc.php'); include_once('adodb-pager.inc.php'); session_start(); $db = NewADOConnection('mysql'); $db->Connect('localhost','root','','xphplens'); $sql = "select * from adoxyz "; $pager = new ADODB_Pager($db,$sql); $pager->Render($rows_per_page=5); ?> // A $pager objektum ltrejn // Megadjuk, hogy hny sor legyen rajta.

A pldban az adodb-pager.inc.php include engedlyezi a lapozst. A sessionben troljuk az oldal llapott. A ADODB_Pager() ltrehozza az adott oldalon a megfelel lapoz objektumot. A Render metdus ltrehozza a HTML oldalon a megfelel vezrlkkel elltott tblzatot. A PHP adatbzis-motor generlta a $recordSet->fields[] tmbt. Nmelyik adatbzis megengedi, hogy sorszmmal s meznvvel is indexelhessk a kapott eredmnysor tmbjt. Ha mindenkppen nvvel akarunk indexelni, akkor a SetFetchMode fggvnyt kell hasznlnunk. Minden rekorszet letrolja, hogy milyen zemmdban hasznltuk, mikor az Execute() vagy a SelectLimit() parancsot hasznltuk. Az Execute parancs az SQL parancs ltal visszaadott teljes rekordszetet visszadja a hiv eljrsnak, mg a SelectLimit() csak a megadott szm sorral tr vissza.
$db->SetFetchMode(ADODB_FETCH_NUM); $rs1 = $db->Execute('select * from table'); $db->SetFetchMode(ADODB_FETCH_ASSOC); $rs2 = $db->Execute('select * from table'); print_r($rs1->fields); # shows array([0]=>'v0',[1] =>'v1') print_r($rs2->fields); # shows array(['col1']=>'v0',['col2'] =>'v1')

A lekrdezett sorok szmt a $recordSet->RecordCount() utasts adja vissza. -1 az eredmny, ha nem meghatrozhat a visszaadott sorok szma. $rs->GetArray([$number_of_rows]) Az albbi fggvny egy kt dimenzis tmbt hoz ltre a recordset adataibl s azt adja vissza. Ha nem adjuk meg a sorok szmt, akkor az sszes adatot visszadja EOf-ig.
$rs = $db->Execute($sql); if ($rs)

78

while ($arr = $rs->FetchRow()) { # process $arr

} }

Example 3: Inserting
Insert a row to the Orders table containing dates and strings that need to be quoted before they can be accepted by the database, eg: the single-quote in the word John's.
<? include('adodb.inc.php'); # load code common to ADOdb $conn = &ADONewConnection('access'); # create a connection $conn->PConnect('northwind'); # connect to MS-Access, northwind dsn $shipto = $conn->qstr("John's Old Shoppe"); $sql = "insert into orders (customerID,EmployeeID,OrderDate,ShipName) "; $sql .= "values ('ANATR',2,".$conn->DBDate(time()).",$shipto)"; if ($conn->Execute($sql) === false) { print 'error inserting: '.$conn->ErrorMsg().'<BR>'; } ?>

In this example, we see the advanced date and quote handling facilities of ADOdb. The unix timestamp (which is a long integer) is appropriately formated for Access with DBDate(), and the right escape character is used for quoting the John's Old Shoppe, which is John''s Old Shoppe and not PHP's default John's Old Shoppe with qstr(). Observe the error-handling of the Execute statement. False is returned by Execute() if an error occured. The error message for the last error that occurred is displayed in ErrorMsg(). Note: php_track_errors might have to be enabled for error messages to be saved.

Example 4: Debugging
<? include('adodb.inc.php'); # load code common to ADOdb $conn = &ADONewConnection('access'); # create a connection $conn->PConnect('northwind'); # connect to MS-Access, northwind dsn $shipto = $conn->qstr("John's Old Shoppe"); $sql = "insert into orders (customerID,EmployeeID,OrderDate,ShipName) "; $sql .= "values ('ANATR',2,".$conn->FormatDate(time()).",$shipto)"; $conn->debug = true; if ($conn->Execute($sql) === false) print 'error inserting'; ?>

In the above example, we have turned on debugging by setting debug = true. This will display the SQL statement before execution, and also show any error messages. There is no need to call ErrorMsg() in this case. For displaying the recordset, see the rs2html() example. Also see the section on Custom Error Handlers.

79

Example 5: MySQL and Menus


Connect to MySQL database agora, and generate a <select> menu from an SQL statement where the <option> captions are in the 1st column, and the value to send back to the server is in the 2nd column.
<? include('adodb.inc.php'); # load code common to ADOdb $conn = &ADONewConnection('mysql'); # create a connection $conn->PConnect('localhost','userid','','agora');# connect to MySQL, agora db $sql = 'select CustomerName, CustomerID from customers'; $rs = $conn->Execute($sql); print $rs->GetMenu('GetCust','Mary Rosli'); ?>

Here we define a menu named GetCust, with the menu option 'Mary Rosli' selected. See GetMenu(). We also have functions that return the recordset as an array: GetArray(), and as an associative array with the key being the first column: GetAssoc().

Example 6: Connecting to 2 Databases At Once


<? include('adodb.inc.php'); # load code common to ADOdb $conn1 = &ADONewConnection('mysql'); # create a mysql connection $conn2 = &ADONewConnection('oracle'); # create a oracle connection $conn1->PConnect($server, $userid, $password, $database); $conn2->PConnect(false, $ora_userid, $ora_pwd, $oraname); $conn1->Execute('insert ...'); $conn2->Execute('update ...'); ?>

Example 7: Generating Update and Insert SQL


ADOdb 1.31 and later supports two new recordset functions: GetUpdateSQL( ) and GetInsertSQL( ). This allow you to perform a "SELECT * FROM table query WHERE...", make a copy of the $rs->fields, modify the fields, and then generate the SQL to update or insert into the table automatically. We show how the functions can be used when accessing a table with the following fields: (ID, FirstName, LastName, Created). Before these functions can be called, you need to initialize the recordset by performing a select on the table. Idea and code by Jonathan Younger jyounger#unilab.com.
<? #============================================== # SAMPLE GetUpdateSQL() and GetInsertSQL() code #============================================== include('adodb.inc.php'); include('tohtml.inc.php'); #========================== # This code tests an insert $sql = "SELECT * FROM ADOXYZ WHERE id = -1"; # Select an empty record from the database $conn = &ADONewConnection("mysql"); # create a connection $conn->debug=1; $conn->PConnect("localhost", "admin", "", "test"); # connect to MySQL, testdb $rs = $conn->Execute($sql); # Execute the query and get the empty recordset $record = array(); # Initialize an array to hold the record data to insert # Set the values for the fields in the record # Note that field names are case-insensitive $record["firstname"] = "Bob"; $record["lastNamE"] = "Smith"; $record["creaTed"] = time();

80

# Pass the empty recordset and the array containing the data to insert # into the GetInsertSQL function. The function will process the data and return # a fully formatted insert sql statement. $insertSQL = $conn->GetInsertSQL($rs, $record); $conn->Execute($insertSQL); # Insert the record into the database #========================== # This code tests an update $sql = "SELECT * FROM ADOXYZ WHERE id = 1"; # Select a record to update $rs = $conn->Execute($sql); # Execute the query and get the existing record to update $record = array(); # Initialize an array to hold the record data to update # Set the values for the fields in the record # Note that field names are case-insensitive $record["firstname"] = "Caroline"; $record["LasTnAme"] = "Smith"; # Update Caroline's lastname from Miranda to Smith # Pass the single record recordset and the array containing the data to update # into the GetUpdateSQL function. The function will process the data and return # a fully formatted update sql statement with the correct WHERE clause. # If the data has not changed, no recordset is returned $updateSQL = $conn->GetUpdateSQL($rs, $record); $conn->Execute($updateSQL); # Update the record in the database $conn->Close(); ?>

81

Example 8: Implementing Scrolling with Next and Previous


The following code creates a very simple recordset pager, where you can scroll from page to page of a recordset.
include_once('../adodb.inc.php'); include_once('../adodb-pager.inc.php'); session_start(); $db = NewADOConnection('mysql'); $db->Connect('localhost','root','','xphplens'); $sql = "select * from adoxyz "; $pager = new ADODB_Pager($db,$sql); $pager->Render($rows_per_page=5);

This will create a basic record pager that looks like this:
|< ID 36 37 38 39 40 << >> >| First Name Last Name Date Created Alan Turing Sat 06, Oct 2001 Serena Williams Sat 06, Oct 2001 Yat Sun Sun Sat 06, Oct 2001 Wai Hun See Sat 06, Oct 2001 Steven Oey Sat 06, Oct 2001

Page 8/10

The number of rows to display at one time is controled by the Render($rows) method. If you do not pass any value to Render(), ADODB_Pager will default to 10 records per page. You can control the column titles by modifying your SQL (supported by most databases):
$sql = 'select id as "ID", firstname as "First Name", lastname as "Last Name", created as "Date Created" from adoxyz';

The above code can be found in the adodb/tests/testpaging.php example included with this release, and the class ADODB_Pager in adodb/adodb-pager.inc.php. The ADODB_Pager code can be adapted by a programmer so that the text links can be replaced by images, and the dull white background be replaced with more interesting colors. You can also allow display of html by setting $pager->htmlSpecialChars = false. Some of the code used here was contributed by Ivn Oliva and Cornel G.

82

Example 9: Exporting in CSV or Tab-Delimited Format


We provide some helper functions to export in comma-separated-value (CSV) and tab-delimited formats:
include_once('/path/to/adodb/toexport.inc.php'); include_once('/path/to/adodb/adodb.inc.php'); $db = &NewADOConnection('mysql'); $db->Connect($server, $userid, $password, $database); $rs = $db->Execute('select fname as "First Name", surname as "Surname" from table'); print "<pre>"; print rs2csv($rs); # return a string, CSV format print '<hr>'; $rs->MoveFirst(); # note, some databases do not support MoveFirst print rs2tab($rs,false); # return a string, tab-delimited # false == suppress field names in first line print '<hr>'; $rs->MoveFirst(); rs2tabout($rs); # send to stdout directly (there is also an rs2csvout function) print "</pre>";

$rs->MoveFirst(); $fp = fopen($path, "w"); if ($fp) { rs2csvfile($rs, $fp); # write to file (there is also an rs2tabfile function) fclose($fp); }

Carriage-returns or newlines are converted to spaces. Field names are returned in the first line of text. Strings containing the delimiter character are quoted with double-quotes. Double-quotes are doublequoted again. This conforms to Excel import and export guide-lines. All the above functions take as an optional last parameter, $addtitles which defaults to true. When set to false field names in the first line are suppressed.

Example 10: Recordset Filters


Sometimes we want to pre-process all rows in a recordset before we use it. For example, we want to ucwords all text in recordset.
include_once('adodb/rsfilter.inc.php'); include_once('adodb/adodb.inc.php'); // ucwords() every element in the recordset function do_ucwords(&$arr,$rs) { foreach($arr as $k => $v) { $arr[$k] = ucwords($v); } } $db = NewADOConnection('mysql'); $db->PConnect('server','user','pwd','db'); $rs = $db->Execute('select ... from table'); $rs = RSFilter($rs,'do_ucwords');

The RSFilter function takes 2 parameters, the recordset, and the name of the filter function. It returns the processed recordset scrolled to the first record. The filter function takes two parameters, the current row as an array, and the recordset object. For future compatibility, you should not use the original recordset object.

Example 11: Smart Transactions


The old way of doing transactions required you to use 83

$conn->BeginTrans(); $ok = $conn->Execute($sql); if ($ok) $ok = $conn->Execute($sql2); if (!$ok) $conn->RollbackTrans(); else $conn->CommitTrans();

This is very complicated for large projects because you have to track the error status. Smart Transactions is much simpler. You start a smart transaction by calling StartTrans():
$conn->StartTrans(); $conn->Execute($sql); $conn->Execute($Sql2); $conn->CompleteTrans();

CompleteTrans() detects when an SQL error occurs, and will Rollback/Commit as appropriate. To specificly force a rollback even if no error occured, use FailTrans(). Note that the rollback is done in CompleteTrans(), and not in FailTrans().
$conn->StartTrans(); $conn->Execute($sql);

if (!CheckRecords()) $conn->FailTrans();
$conn->Execute($Sql2); $conn->CompleteTrans();

Lastly, StartTrans/CompleteTrans is nestable, and only the outermost block is executed. In contrast, BeginTrans/CommitTrans/RollbackTrans is NOT nestable. $conn->StartTrans();
$conn->Execute($sql);

$conn->StartTrans();

# ignored

if (!CheckRecords()) $conn->FailTrans();

$conn->CompleteTrans(); # ignored
$conn->Execute($Sql2);

$conn->CompleteTrans(); Note: Savepoints are currently not supported.

84

18.7 Using Custom Error Handlers and PEAR_Error


Apart from the old $con->debug = true; way of debugging, ADOdb 1.50 onwards provides another way of handling errors using ADOdb's custom error handlers. ADOdb provides two custom handlers which you can modify for your needs. The first one is in the adodb-errorhandler.inc.php file. This makes use of the standard PHP functions error_reporting to control what error messages types to display, and trigger_error which invokes the default PHP error handler. Including the above file will cause trigger_error($errorstring,E_USER_ERROR) to be called when (a) Connect() or PConnect() fails, or (b) a function that executes SQL statements such as Execute() or SelectLimit() has an error. (c) GenID() appears to go into an infinite loop. The $errorstring is generated by ADOdb and will contain useful debugging information similar to the error.log data generated below. This file adodb-errorhandler.inc.php should be included before you create any ADOConnection objects. If you define error_reporting(0), no errors will be shown. If you set error_reporting(E_ALL), all errors will be displayed on the screen.
<?php error_reporting(E_ALL); # show any error messages triggered include('adodb-errorhandler.inc.php'); include('adodb.inc.php'); include('tohtml.inc.php'); $c = NewADOConnection('mysql'); $c->PConnect('localhost','root','','northwind'); $rs=$c->Execute('select * from productsz'); #invalid table productsz'); if ($rs) $rs2html($rs); ?>

If you want to log the error message, you can do so by defining the following optional constants ADODB_ERROR_LOG_TYPE and ADODB_ERROR_LOG_DEST. ADODB_ERROR_LOG_TYPE is the error log message type (see error_log in the PHP manual). In this case we set it to 3, which means log to the file defined by the constant ADODB_ERROR_LOG_DEST.
<?php error_reporting(0); # do not echo any errors define('ADODB_ERROR_LOG_TYPE',3); define('ADODB_ERROR_LOG_DEST','C:/errors.log'); include('adodb-errorhandler.inc.php'); include('adodb.inc.php'); include('tohtml.inc.php'); $c = NewADOConnection('mysql'); $c->PConnect('localhost','root','','northwind'); $rs=$c->Execute('select * from productsz'); ## invalid table productsz if ($rs) $rs2html($rs); ?>

85

The following message will be logged in the error.log file: (2001-10-28 14:20:38) mysql error: [1146: Table 'northwind.productsz' doesn't exist] in
EXECUTE("select * from productsz")

The second error handler is adodb-errorpear.inc.php. This will create a PEAR_Error derived object whenever an error occurs. The last PEAR_Error object created can be retrieved using ADODB_Pear_Error().

<?php include('adodb-errorpear.inc.php'); include('adodb.inc.php'); include('tohtml.inc.php'); $c = NewADOConnection('mysql'); $c->PConnect('localhost','root','','northwind'); $rs=$c->Execute('select * from productsz'); #invalid table productsz'); if ($rs) $rs2html($rs); else { $e = ADODB_Pear_Error(); echo '<p>',$e->message,'</p>'; } ?>

You can use a PEAR_Error derived class by defining the constant ADODB_PEAR_ERROR_CLASS before the adodb-errorpear.inc.php file is included. For easy debugging, you can set the default error handler in the beginning of the PHP script to PEAR_ERROR_DIE, which will cause an error message to be printed, then halt script execution:
include('PEAR.php'); PEAR::setErrorHandling('PEAR_ERROR_DIE');

Note that we do not explicitly return a PEAR_Error object to you when an error occurs. We return false instead. You have to call ADODB_Pear_Error() to get the last error or use the PEAR_ERROR_DIE technique. 18.7.1.1 Error Messages

Error messages are outputted using the static method ADOConnnection::outp($msg,$newline=true). By default, it sends the messages to the client. You can override this to perform error-logging.

86

18.8 Data Source Names


We now support connecting using PEAR style DSN's. A DSN is a connection string of the form: $dsn = "http://php.weblogs.com/$driver://$username:$password@$hostname/$databasename";; You pass the DSN to the static class function DB::Connect. An example:
include_once('../adodb/adodb-pear.inc.php'); $username = 'root'; $password = ''; $hostname = 'localhost'; $databasename = 'xphplens'; $driver = 'mysql';

$dsn ="http://php.weblogs.com/$driver://$username:$password@$hostname/$databasename";
$db = DB::Connect($dsn); $rs = $db->Execute('select firstname,lastname from adoxyz'); $cnt = 0; while ($arr = $rs->FetchRow()) { print_r($arr); print "<br>"; }

This requires PEAR to be installed and in the default include path in php.ini.

18.9 Caching of Recordsets


ADOdb now supports caching of recordsets using the CacheExecute( ), CachePageExecute( ) and CacheSelectLimit( ) functions. There are similar to the non-cache functions, except that they take a new first parameter, $secs2cache. An example:
include('adodb.inc.php'); # load code common to ADOdb $ADODB_CACHE_DIR = '/usr/ADODB_cache'; $conn = &ADONewConnection('mysql'); # create a connection $conn->PConnect('localhost','userid','','agora');# connect to MySQL, agora db $sql = 'select CustomerName, CustomerID from customers'; $rs = $conn->CacheExecute(15,$sql);

The first parameter is the number of seconds to cache the query. Subsequent calls to that query will used the cached version stored in $ADODB_CACHE_DIR. To force a query to execute and flush the cache, call CacheExecute() with the first parameter set to zero. Alternatively, use the CacheFlush($sql) call. For the sake of security, we recommend you set register_globals=off in php.ini if you are using $ADODB_CACHE_DIR. In ADOdb 1.80 onwards, the secs2cache parameter is optional in CacheSelectLimit() and CacheExecute(). If you leave it out, it will use the $connection->cacheSecs parameter, which defaults to 60 minutes.
$conn->Connect(...); $conn->cacheSecs = 3600*24; # cache 24 hours $rs = $conn->CacheExecute('select * from table');

Please note that magic_quotes_runtime should be turned off. More info.

18.10

Pivot Tables

Since ADOdb 2.30, we support the generation of SQL to create pivot tables, also known as crosstabulations. For further explanation read this DevShed Cross-Tabulation tutorial. We assume that your database supports the SQL case-when expression. In this example, we will use the Northwind database from Microsoft. In the database, we have a products table, and we want to analyze this table by suppliers versus product categories. We will place the suppliers on each row, and pivot on categories. So from the table on the left, we generate the pivottable on the right: 87

Supplier Category supplier1 category1 supplier2 category1 supplier2 category2 --> supplier1 1 supplier2 1 0 1 category1 category2 1 2 total

The following code will generate the SQL for a cross-tabulation:


# # # # # # Query the main "product" table Set the rows to CompanyName and the columns to the values of Categories and define the joins to link to lookup tables "categories" and "suppliers"

include "adodb/pivottable.php"; $sql = PivotTableSQL( $gDB, # adodb connection 'products p ,categories c ,suppliers s', # tables 'CompanyName', # rows (multiple fields allowed) 'CategoryName', # column to pivot on 'p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID' # joins/where );

This will generate the following SQL: SELECT CompanyName, SUM(CASE WHEN CategoryName='Beverages' THEN 1 ELSE 0 END) AS "Beverages", SUM(CASE WHEN CategoryName='Condiments' THEN 1 ELSE 0 END) AS "Condiments", SUM(CASE WHEN CategoryName='Confections' THEN 1 ELSE 0 END) AS "Confections", SUM(CASE WHEN CategoryName='Dairy Products' THEN 1 ELSE 0 END) AS "Dairy Products", SUM(CASE WHEN CategoryName='Grains/Cereals' THEN 1 ELSE 0 END) AS "Grains/Cereals", SUM(CASE WHEN CategoryName='Meat/Poultry' THEN 1 ELSE 0 END) AS "Meat/Poultry", SUM(CASE WHEN CategoryName='Produce' THEN 1 ELSE 0 END) AS "Produce", SUM(CASE WHEN CategoryName='Seafood' THEN 1 ELSE 0 END) AS "Seafood", SUM(1) as Total FROM products p ,categories c ,suppliers s WHERE p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID GROUP BY CompanyName You can also pivot on numerical columns and generate totals by using ranges. This code was revised in ADODB 2.41 and is not backward compatible. The second example shows this:
$sql = PivotTableSQL( $gDB, # adodb connection 'products p ,categories c ,suppliers s', # tables 'CompanyName', # rows (multiple fields allowed) array( # column ranges ' 0 ' => 'UnitsInStock <= 0', "1 to 5" => '0 < UnitsInStock and UnitsInStock <= 5', "6 to 10" => '5 < UnitsInStock and UnitsInStock <= 10', "11 to 15" => '10 < UnitsInStock and UnitsInStock <= 15', "16+" => '15 < UnitsInStock' ), ' p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID', # joins/where 'UnitsInStock', # sum this field 'Sum ' # sum label prefix );

Which generates: 88

SELECT CompanyName, SUM(CASE WHEN UnitsInStock <= 0 THEN UnitsInStock ELSE 0 END) AS "Sum 0 ", SUM(CASE WHEN 0 < UnitsInStock and UnitsInStock <= 5 THEN UnitsInStock ELSE 0 END) AS "Sum 1 to 5", SUM(CASE WHEN 5 < UnitsInStock and UnitsInStock <= 10 THEN UnitsInStock ELSE 0 END) AS "Sum 6 to 10", SUM(CASE WHEN 10 < UnitsInStock and UnitsInStock <= 15 THEN UnitsInStock ELSE 0 END) AS "Sum 11 to 15", SUM(CASE WHEN 15 < UnitsInStock THEN UnitsInStock ELSE 0 END) AS "Sum 16+", SUM(UnitsInStock) AS "Sum UnitsInStock", SUM(1) as Total, FROM products p ,categories c ,suppliers s WHERE p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID GROUP BY CompanyName

89

90

19 Class Reference
Function parameters with [ ] around them are optional.

19.1 Global Variables


$ADODB_COUNTRECS
If the database driver API does not support counting the number of records returned in a SELECT statement, the function RecordCount() is emulated when the global variable $ADODB_COUNTRECS is set to true, which is the default. We emulate this by buffering the records, which can take up large amounts of memory for big recordsets. Set this variable to false for the best performance. This variable is checked every time a query is executed, so you can selectively choose which recordsets to count.

$ADODB_CACHE_DIR
If you are using recordset caching, this is the directory to save your recordsets in. Define this before you call any caching functions such as CacheExecute( ). We recommend setting register_globals=off in php.ini if you use this feature for security reasons. If you are using Unix and apache, you might need to set your cache directory permissions to something similar to the following: chown -R chgrp -R apache /path/to/adodb/cache apache /path/to/adodb/cache

$ADODB_FETCH_MODE
This is a global variable that determines how arrays are retrieved by recordsets. The recordset saves this value on creation (eg. in Execute( ) or SelectLimit( )), and any subsequent changes to $ADODB_FETCH_MODE have no affect on existing recordsets, only on recordsets created in the future. The following constants are defined: define('ADODB_FETCH_DEFAULT',0); define('ADODB_FETCH_NUM',1); define('ADODB_FETCH_ASSOC',2); define('ADODB_FETCH_BOTH',3); An example:
$ADODB_FETCH_MODE = ADODB_FETCH_NUM; $rs1 = $db->Execute('select * from table'); $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC; $rs2 = $db->Execute('select * from table'); print_r($rs1->fields); # shows array([0]=>'v0',[1] =>'v1') print_r($rs2->fields); # shows array(['col1']=>'v0',['col2'] =>'v1')

As you can see in the above example, both recordsets store and use different fetch modes based on the $ADODB_FETCH_MODE setting when the recordset was created by Execute(). If no fetch mode is predefined, the fetch mode defaults to ADODB_FETCH_DEFAULT. The behaviour of this default mode varies from driver to driver, so do not rely on ADODB_FETCH_DEFAULT. For portability, we recommend sticking to ADODB_FETCH_NUM or ADODB_FETCH_ASSOC. Many drivers do not support ADODB_FETCH_BOTH.
SetFetchMode Function

Some programmers prefer to use a more object-oriented solution, where the fetch mode is set by a object function, SetFetchMode. Once this function is called for a connection object, that connection object will ignore the global variable $ADODB_FETCH_MODE and will use the internal fetchMode property exclusively. 91

$db->SetFetchMode(ADODB_FETCH_NUM); $rs1 = $db->Execute('select * from table'); $db->SetFetchMode(ADODB_FETCH_ASSOC); $rs2 = $db->Execute('select * from table'); print_r($rs1->fields); # shows array([0]=>'v0',[1] =>'v1') print_r($rs2->fields); # shows array(['col1']=>'v0',['col2'] =>'v1')

To retrieve the previous fetch mode, you can use check the $db->fetchMode property, or use the return value of SetFetchMode( ).
ADODB_ASSOC_CASE

You can control the associative fetch case for certain drivers which behave differently. For the sybase, oci8po, mssql, odbc and ibase drivers and all drivers derived from them, ADODB_ASSOC_CASE will by default generate recordsets where the field name keys are lower-cased. Use the constant ADODB_ASSOC_CASE to change the case of the keys. There are 3 possible values: 0 = assoc lowercase field names. $rs->fields['orderid'] 1 = assoc uppercase field names. $rs->fields['ORDERID'] 2 = use native-case field names. $rs->fields['OrderID'] -- this is the default since ADOdb 2.90 To use it, declare it before you incldue adodb.inc.php. define('ADODB_ASSOC_CASE', include('adodb.inc.php'); 2); # use native-case for ADODB_FETCH_ASSOC

92

19.2 ADOConnection
Object that performs the connection to the database, executes SQL statements and has a set of utility functions for standardising the format of SQL statements for issues such as concatenation and date formats.

ADOConnection Fields
databaseType: Name of the database system we are connecting to. Eg. odbc or mssql or mysql. dataProvider: The underlying mechanism used to connect to the database. Normally set to native, unless using odbc or ado. host: Name of server or data source name (DSN) to connect to. database: Name of the database or to connect to. If ado is used, it will hold the ado data provider. user: Login id to connect to database. Password is not saved for security reasons. raiseErrorFn: Allows you to define an error handling function. See adodb-errorhandler.inc.php for an example. debug: Set to true to make debug statements to appear. concat_operator: Set to '+' or '||' normally. The operator used to concatenate strings in SQL. Used by the Concat function. fmtDate: The format used by the DBDate function to send dates to the database. is '#Y-m-d#' for Microsoft Access, and ''Y-m-d'' for MySQL. fmtTimeStamp: The format used by the DBTimeStamp function to send timestamps to the database. true: The value used to represent true.Eg. '.T.'. for Foxpro, '1' for Microsoft SQL. false: The value used to represent false. Eg. '.F.'. for Foxpro, '0' for Microsoft SQL. replaceQuote: The string used to escape quotes. Eg. double single-quotes for Microsoft SQL, and backslash-quote for MySQL. Used by qstr. autoCommit: indicates whether automatic commit is enabled. Default is true. charSet: set the default charset to use. Currently only interbase supports this. dialect: set the default sql dialect to use. Currently only interbase supports this. metaTablesSQL: SQL statement to return a list of available tables. Eg. SHOW TABLES in MySQL. genID: The latest id generated by GenID() if supported by the database. cacheSecs: The number of seconds to cache recordsets if CacheExecute() or CacheSelectLimit() omit the $secs2cache parameter. Defaults to 60 minutes. sysDate: String that holds the name of the database function to call to get the current date. Useful for inserts and updates. sysTimeStamp: String that holds the name of the database function to call to get the current timestamp/datetime value. leftOuter: String that holds operator for left outer join, if known. Otherwise set to false. rightOuter: String that holds operator for left outer join, if known. Otherwise set to false. ansiOuter: Boolean that if true indicates that ANSI style outer joins are permitted. Eg. select * from table1 left join table2 on p1=p2.

93

connectSID: Boolean that indicates whether to treat the $database parameter in connects as the SID for the oci8 driver. Defaults to false. Useful for Oracle 8.0.5 and earlier. autoRollback: Persistent connections are auto-rollbacked in PConnect( ) if this is set to true. Default is false.

ADOConnection Main Functions


ADOConnection( ) Constructor function. Do not call this directly. Use ADONewConnection( ) instead. Connect($host,[$user],[$password],[$database]) Non-persistent connect to data source or server $host, using userid $user and password $password. If the server supports multiple databases, connect to database $database. Returns true/false depending on connection. ADO Note: If you are using a Microsoft ADO and not OLEDB, you can set the $database parameter to the OLEDB data provider you are using. PostgreSQL: An alternative way of connecting to the database is to pass the standard PostgreSQL connection string in the first parameter $host, and the other parameters will be ignored. For Oracle and Oci8, there are two ways to connect. First is to use the TNS name defined in your local tnsnames.ora (or ONAMES or HOSTNAMES). Place the name in the $database field, and set the $host field to false. Alternatively, set $host to the server, and $database to the database SID, this bypassed tnsnames.ora. Examples:
# $oraname in tnsnames.ora/ONAMES/HOSTNAMES $conn->Connect(false, 'scott', 'tiger', $oraname); $conn->Connect('server:1521', 'scott', 'tiger', 'ServiceName'); # bypass tnsnames.ora

There are many examples of connecting to a database at php.weblogs.com/ADOdb, and in the testdatabases.inc.php file included in the release. PConnect($host,[$user],[$password],[$database]) Persistent connect to data source or server $host, using userid $user and password $password. If the server supports multiple databases, connect to database $database. We now perform a rollback on persistent connection for selected databases since 2.21, as advised in the PHP manual. See change log or source code for which databases are affected. Returns true/false depending on connection. See Connect( ) above for more info. Since ADOdb 2.21, we also support autoRollback. If you set:
$conn = &NewADOConnection('mysql'); $conn->autoRollback = true; # default is false $conn->PConnect(...); # rollback here

Then when doing a persistent connection with PConnect( ), ADOdb will perform a rollback first. This is because it is documented that PHP is not guaranteed to rollback existing failed transactions when persistent connections are used. This is implemented in Oracle, MySQL, PgSQL, MSSQL, ODBC currently. Since ADOdb 3.11, you can force non-persistent connections even if PConnect is called by defining the constant ADODB_NEVER_PERSIST before you call PConnect. NConnect($host,[$user],[$password],[$database])

94

Always force new connection. In contrast, PHP sometimes reuses connections when you use Connect() or PConnect(). Currently works only on mysql (PHP 4.3.0 or later) and oci8-derived drivers. For other drivers, NConnect() works like Connect(). Execute($sql,$inputarr=false) Execute SQL statement $sql and return derived class of ADORecordSet if successful. Note that a record set is always returned on success, even if we are executing an insert or update statement. Returns derived class of ADORecordSet. Eg. if connecting via mysql, then ADORecordSet_mysql would be returned. False is returned if there was an error in executing the sql. The $inputarr parameter can be used for binding variables to parameters. Below is an Oracle example:
$conn->Execute("SELECT * FROM TABLE WHERE COND=:val", array('val'=> $val));

Another example, using ODBC,which uses the ? convention:


$conn->Execute("SELECT * FROM TABLE WHERE COND=?", array($val));

Binding variables Variable binding speeds the compilation and caching of SQL statements, leading to higher performance. Currently Oracle and ODBC support variable binding. ODBC style ? binding is emulated in databases that do not support binding. Variable binding in the odbc and oci8po drivers.
$rs = $db->Execute('select * from table where val=?', array('10'));

Variable binding in the oci8 driver.


$rs = $db->Execute('select name from table where val=:key', array('key' => 10));

CacheExecute([$secs2cache,]$sql,$inputarr=false) Similar to Execute, except that the recordset is cached for $secs2cache seconds in the $ADODB_CACHE_DIR directory. If CacheExecute() is called again with the same parameters, same database, same userid, same password, and the cached recordset has not expired, the cached recordset is returned.
include('adodb.inc.php'); include('tohtml.inc.php'); $ADODB_CACHE_DIR = '/usr/local/ADOdbcache'; $conn = &ADONewConnection('mysql'); $conn->PConnect('localhost','userid','password','database'); $rs = $conn->CacheExecute(15, 'select * from table'); # cache 15 secs rs2html($rs); /* recordset to html table */

Alternatively, since ADOdb 1.80, the $secs2cache parameter is optional:


$conn->Connect(...); $conn->cacheSecs = 3600*24; // cache 24 hours $rs = $conn->CacheExecute('select * from table');

Note that the $secs2cache parameter is optional. If omitted, we use the value in $connection->cacheSecs (default is 3600 seconds, or 1 hour). Use CacheExecute() only with SELECT statements. Performance note: I have done some benchmarks and found that they vary so greatly that it's better to talk about when caching is of benefit. When your database server is much slower than your Web server or the database is very overloaded then ADOdb's caching is good because it reduces the load on your database server. If your database server is lightly loaded or much faster than your Web server, then caching could actually reduce performance. 95

ExecuteCursor($sql,$cursorName='rs',$parameters=false) Execute an Oracle stored procedure, and returns an Oracle REF cursor variable as a regular ADOdb recordset. Does not work with any other database except oci8. Thanks to Robert Tuttle for the design.
$db = ADONewConnection("oci8"); $db->Connect("foo.com:1521", "uid", "pwd", "FOO"); $rs = $db->ExecuteCursor("begin :cursorvar := getdata(:param1); end;", 'cursorvar', array('param1'=>10)); # $rs is now just like any other ADOdb recordset object rs2html($rs);

ExecuteCursor() is a helper function that does the following internally:


$stmt = $db->Prepare("BEGIN :RS := SP_FOO(); END;"); $db->Parameter($stmt, $cur, 'RS', false, -1, OCI_B_CURSOR); $rs = $db->Execute($stmt);

SelectLimit($sql,$numrows=-1,$offset=-1,$inputarr=false) Returns a recordset if successful. Returns false otherwise. Performs a select statement, simulating PostgreSQL's SELECT statement, LIMIT $numrows OFFSET $offset clause. In PostgreSQL, SELECT * FROM TABLE LIMIT 3 will return the first 3 records only. The equivalent is $connection->SelectLimit('SELECT * FROM TABLE',3). This functionality is simulated for databases that do not possess this feature. And SELECT * FROM TABLE LIMIT 3 OFFSET 2 will return records 3, 4 and 5 (eg. after record 2, return 3 rows). The equivalent in ADOdb is $connection->SelectLimit('SELECT * FROM TABLE',3,2). Note that this is the opposite of MySQL's LIMIT clause. You can also set $connection>SelectLimit('SELECT * FROM TABLE',-1,10) to get rows 11 to the last row. The last parameter $inputarr is for databases that support variable binding such as Oracle oci8. This substantially reduces SQL compilation overhead. Below is an Oracle example:
$conn->SelectLimit("SELECT * FROM TABLE WHERE COND=:val", 100,-1,array('val'=> $val));

The oci8po driver (oracle portable driver) uses the more standard bind variable of ?:
$conn->SelectLimit("SELECT * FROM TABLE WHERE COND=?", 100,-1,array('val'=> $val));

Ron Wilson reports that SelectLimit does not work with UNIONs. CacheSelectLimit([$secs2cache,] $sql, $numrows=-1,$offset=-1,$inputarr=false) Similar to SelectLimit, except that the recordset returned is cached for $secs2cache seconds in the $ADODB_CACHE_DIR directory. Since 1.80, $secs2cache has been optional, and you can define the caching time in $connection>cacheSecs.
$conn->Connect(...); $conn->cacheSecs = 3600*24; // cache 24 hours $rs = $conn->CacheSelectLimit('select * from table',10);

CacheFlush($sql=false,$inputarr=false) Flush (delete) any cached recordsets for the SQL statement $sql in $ADODB_CACHE_DIR. If no parameter is passed in, then all adodb_*.cache files are deleted. If you want to flush all cached recordsets manually, execute the following PHP code (works only under Unix): system("rm -f `find ".$ADODB_CACHE_DIR." -name adodb_*.cache`");

96

For general cleanup of all expired files, you should use crontab on Unix, or at.exe on Windows, and a shell script similar to the following: #-----------------------------------------------------# This particular example deletes files in the TMPPATH # directory with the string ".cache" in their name that # are more than 7 days old. #-----------------------------------------------------AGED=7 find ${TMPPATH} -mtime +$AGED | grep ".cache" | xargs rm -f MetaError($errno=false) Returns a virtualized error number, based on PEAR DB's error number system. You might need to include adodb-error.inc.php before you call this function. The parameter $errno is the native error number you want to convert. If you do not pass any parameter, MetaError will call ErrorNo() for you and convert it. If the error number cannot be virtualized, MetaError will return -1 (DB_ERROR). MetaErrorMsg($errno) Pass the error number returned by MetaError() for the equivalent textual error message. ErrorMsg() Returns the last status or error message. This can return a string even if no error occurs. In general you do not need to call this function unless an ADOdb function returns false on an error. Note: If debug is enabled, the SQL error message is always displayed when the Execute function is called. ErrorNo() Returns the last error number. Note that old versions of PHP (pre 4.0.6) do not support error number for ODBC. In general you do not need to call this function unless an ADOdb function returns false on an error. SetFetchMode($mode) Sets the current fetch mode for the connection and stores it in $db->fetchMode. Legal modes are ADODB_FETCH_ASSOC and ADODB_FETCH_NUM. For more info, see $ADODB_FETCH_MODE. Returns the previous fetch mode, which could be false if SetFetchMode( ) has not been called before. CreateSequence($seqName = 'adodbseq',$startID=1) Create a sequence. The next time GenID( ) is called, the value returned will be $startID. Added in 2.60. DropSequenceD($seqName = 'adodbseq') Delete a sequence. Added in 2.60. GenID($seqName = 'adodbseq',$startID=1) Generate a sequence number (an integer except for mssql). Works for interbase, mysql, postgresql, oci8, oci8po, mssql, ODBC based (access,vfp,db2,etc) drivers currently. Uses $seqName as the name of the sequence. GenID() will automatically create the sequence for you if it does not exist (provided the userid has permission to do so). Otherwise you will have to create the sequence yourself. If your database driver emulates sequences, the name of the table is the sequence name. The table has one column, "id" which should be of type integer, or if you need something larger - numeric(16). For ODBC and databases that do not support sequences natively (eg mssql, mysql), we create a table for each sequence. If the sequence has not been defined earlier, it is created with the starting value set in $startID. 97

Note that the mssql driver's GenID() used to generate 16 byte GUID's. We now return integers since 1.90. UpdateBlob($table,$column,$val,$where) Allows you to store a blob (in $val) into $table into $column in a row at $where. Usage:
# for oracle $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, empty_blob())'); $conn->UpdateBlob('blobtable','blobcol',$blobvalue,'id=1'); # non oracle databases $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)'); $conn->UpdateBlob('blobtable','blobcol',$blobvalue,'id=1');

Returns true if succesful, false otherwise. Supported by MySQL, PostgreSQL, Oci8, Oci8po and Interbase drivers. Other drivers might work, depending on the state of development. Note that when an Interbase blob is retrieved using SELECT, it still needs to be decoded using $connection->DecodeBlob($blob); to derive the original value in versions of PHP before 4.1.0. For PostgreSQL, you can store your blob using blob oid's or as a bytea field. You can use bytea fields but not blob oid's currently with UpdateBlob( ). Conversely UpdateBlobFile( ) supports oid's, but not bytea data. If you do not pass in an oid, then UpdateBlob() assumes that you are storing in bytea fields. UpdateClob($table,$column,$val,$where) Allows you to store a clob (in $val) into $table into $column in a row at $where. Similar to UpdateBlob (see above), but for Character Large OBjects. Usage:
# for oracle $conn->Execute('INSERT INTO clobtable (id, clobcol) VALUES (1, empty_clob())'); $conn->UpdateBlob('clobtable','clobcol',$clobvalue,'id=1'); # non oracle databases $conn->Execute('INSERT INTO clobtable (id, clobcol) VALUES (1, null)'); $conn->UpdateBlob('clobtable','clobcol',$clobvalue,'id=1');

UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB') Similar to UpdateBlob, except that we pass in a file path to where the blob resides. For PostgreSQL, if you are using blob oid's, use this interface. This interface does not support bytea fields. Returns true if successful, false otherwise. BlobEncode($blob) Some databases require blob's to be encoded manually before upload. Note if you use UpdateBlob( ) or UpdateBlobFile( ) the conversion is done automatically for you and you do not have to call this function. For PostgreSQL, currently, BlobEncode() can only be used for bytea fields. Returns the encoded blob value. Note that there is a connection property called blobEncodeType which has 3 legal values: false no need to perform encoding or decoding. 'I' - blob encoding required, and returned encoded blob is a numeric value (no need to quote). 'C' - blob encoding required, and returned encoded blob is a character value (requires quoting). 98

This is purely for documentation purposes, so that programs that accept multiple database drivers know what is the right thing to do when processing blobs.
BlobDecode($blob)

Some databases require blob's to be decoded manually after doing a select statement. If the database does not require decoding, then this function will return the blob unchanged. Currently BlobDecode is only required for one database, PostgreSQL, and only if you are using blob oid's (if you are using bytea fields, we auto-decode for you).
$rs = $db->Execute("select bloboid from postgres_table where id=$key"); $blob = $db->BlobDecode( reset($rs->fields) );

Replace($table, $arrFields, $keyCols,$autoQuote=false) Try to update a record, and if the record is not found, an insert statement is generated and executed. Returns 0 on failure, 1 if update statement worked, 2 if no record was found and the insert was executed successfully. This differs from MySQL's replace which deletes the record and inserts a new record. This also means you cannot update the primary key. The only exception to this is Interbase and its derivitives, which uses delete and insert because of some Interbase API limitations. The parameters are $table which is the table name, the $keyCols which is an associative array where the keys are the field names, and keyCols is the name of the primary key, or an array of field names if it is a compound key. If $autoQuote is set to true, then Replace() will quote all values that are non-numeric; auto-quoting will not quote nulls. Note that auto-quoting will not work if you use SQL functions or operators. Examples:
# single field primary key $ret = $db->Replace('atable', array('id'=>1000,'firstname'=>'Harun','lastname'=>'Al-Rashid'), 'id', 'firstname',$autoquote = true); # generates UPDATE atable SET firstname='Harun',lastname='Al-Rashid' WHERE id=1000 # or INSERT INTO atable (id,firstname,lastname) VALUES (1000,'Harun','Al-Rashid') # compound key $ret = $db->Replace('atable2', array('firstname'=>'Harun','lastname'=>'Al-Rashid', 'age' => 33, 'birthday' => 'null'), array('lastname','firstname'), 'firstname',$autoquote = true); # no auto-quoting $ret = $db->Replace('atable2', array('firstname'=>"'Harun'",'lastname'=>"'Al-Rashid'", 'age' => 'null'), array('lastname','firstname'), 'firstname');

99

GetUpdateSQL(&$rs, $arrFields, $forceUpdate=false,$magicq=false) Generate SQL to update a table given a recordset $rs, and the modified fields of the array $arrFields (which must be an associative array holding the column names and the new values) are compared with the current recordset. If $forceUpdate is true, then we also generate the SQL even if $arrFields is identical to $rs->fields. Requires the recordset to be associative. $magicq is used to indicate whether magic quotes are enabled (see qstr()). The field names in the array are case-insensitive. GetInsertSQL(&$rs, $arrFields,$magicq=false) Generate SQL to insert into a table given a recordset $rs. Requires the query to be associative. $magicq is used to indicate whether magic quotes are enabled (for qstr()). The field names in the array are caseinsensitive. PageExecute($sql, $nrows, $page, $inputarr=false) Used for pagination of recordset. $page is 1-based. See Example 8. CachePageExecute($secs2cache, $sql, $nrows, $page, $inputarr=false) Used for pagination of recordset. $page is 1-based. See Example 8. Caching version of PageExecute. Close( ) Close the database connection. PHP4 proudly states that we no longer have to clean up at the end of the connection because the reference counting mechanism of PHP4 will automatically clean up for us. StartTrans( ) Start a monitored transaction. As SQL statements are executed, ADOdb will monitor for SQL errors, and if any are detected, when CompleteTrans() is called, we auto-rollback. To understand why StartTrans() is superior to BeginTrans(), let us examine a few ways of using BeginTrans(). The following is the wrong way to use transactions:
$DB->BeginTrans(); $DB->Execute("update table1 set val=$val1 where id=$id"); $DB->Execute("update table2 set val=$val2 where id=$id"); $DB->CommitTrans();

because you perform no error checking. It is possible to update table1 and for the update on table2 to fail. Here is a better way:
$DB->BeginTrans(); $ok = $DB->Execute("update table1 set val=$val1 where id=$id"); if ($ok) $ok = $DB->Execute("update table2 set val=$val2 where id=$id"); if ($ok) $DB->CommitTrans(); else $DB->RollbackTrans();

Another way is (since ADOdb 2.0):


$DB->BeginTrans(); $ok = $DB->Execute("update table1 set val=$val1 where id=$id"); if ($ok) $ok = $DB->Execute("update table2 set val=$val2 where id=$id"); $DB->CommitTrans($ok);

Now it is a headache monitoring $ok all over the place. StartTrans() is an improvement because it monitors all SQL errors for you. This is particularly useful if you are calling black-box functions in which SQL queries might be executed. Also all BeginTrans, CommitTrans and RollbackTrans calls inside a StartTrans block will be disabled, so even if the black box function does a commit, it will be ignored.
$DB->StartTrans(); CallBlackBox(); $DB->Execute("update table1 set val=$val1 where id=$id"); $DB->Execute("update table2 set val=$val2 where id=$id"); $DB->CompleteTrans($ok);

100

Note that a StartTrans blocks are nestable, the inner blocks are ignored. CompleteTrans($autoComplete=true) Complete a transaction called with StartTrans(). This function monitors for SQL errors, and will commit if no errors have occured, otherwise it will rollback. Returns true on commit, false on rollback. If the parameter $autoComplete is true monitor sql errors and commit and rollback as appropriate. Set $autoComplete to false to force rollback even if no SQL error detected. BeginTrans( ) Begin a transaction. Turns off autoCommit. Returns true if successful. Some databases will always return false if transaction support is not available. Interbase, Oracle and MSSQL support transactions. Any open transactions will be rolled back when the connection is closed. Note that StartTrans() and CompleteTrans() is a superior method of handling transactions, available since ADOdb 3.40. For a explanation, see the StartTrans() documentation. You can also use the ADOdb error handler to die and rollback your transactions for you transparently. Some buggy database extensions are known to commit all outstanding tranasactions, so you might want to explicitly do a $DB->RollbackTrans() in your error handler for safety. 19.2.1.1 Detecting Transactions

Since ADOdb 2.50, you are able to detect when you are inside a transaction. Check that $connection>transCnt > 0. This variable is incremented whenever BeginTrans() is called, and decremented whenever RollbackTrans() or CommitTrans() is called. CommitTrans($ok=true) End a transaction successfully. Returns true if successful. If the database does not support transactions, will return true also as data is always committed. If you pass the parameter $ok=false, the data is rolled back. See example in BeginTrans(). RollbackTrans( ) End a transaction, rollback all changes. Returns true if successful. If the database does not support transactions, will return false as data is never rollbacked. GetOne($sql,$inputarr=false) Executes the SQL and returns the first field of the first row. The recordset and remaining rows are discarded for you automatically. If an error occur, false is returned. GetRow($sql,$inputarr=false) Executes the SQL and returns the first row as an array. The recordset and remaining rows are discarded for you automatically. If an error occurs, false is returned. GetAll($sql) Executes the SQL and returns the all the rows as a 2-dimensional array. The recordset is discarded for you automatically. If an error occurs, false is returned. GetCol($sql,$inputarr=false,$trim=false) Executes the SQL and returns all elements of the first column as a 1-dimensional array. The recordset is discarded for you automatically. If an error occurs, false is returned. CacheGetOne([$secs2cache,] $sql,$inputarr=false), CacheGetRow([$secs2cache,] $sql,$inputarr=false), CacheGetAll([$secs2cache,] $sql,$inputarr=false), CacheGetCol([$secs2cache,] $sql,$inputarr=false,$trim=false) 101

Similar to above Get* functions, except that the recordset is serialized and cached in the $ADODB_CACHE_DIR directory for $secs2cache seconds. Good for speeding up queries on rarely changing data. Note that the $secs2cache parameter is optional. If omitted, we use the value in $connection->cacheSecs (default is 3600 seconds, or 1 hour). Prepare($sql ) Prepares an SQL query for repeated execution. Only supported internally by interbase, oci8 and selected ODBC-based drivers, otherwise it is emulated. There is no performance advantage to using Prepare() with emulation. Returns an array containing the original sql statement in the first array element; the remaining elements of the array are driver dependent. If there is an error, or we are emulating Prepare( ), we return the original $sql string. This is because all error-handling has been centralized in Execute( ). Example:
$stmt = $DB->Prepare('insert into table (col1,col2) values (?,?)'); for ($i=0; $i < $max; $i++) $DB->Execute($stmt,array((string) rand(), $i));

Important: Due to limitations or bugs in PHP, if you are getting errors when you using prepared queries, try setting $ADODB_COUNTRECS = false before preparing. This behaviour has been observed with ODBC. PrepareSP($sql) In the mssql driver, preparing stored procedures requires a special function call, mssql_init( ), which is called by this function. PrepareSP( ) is available in all other drivers, and is emulated by calling Prepare( ). For examples of usage, see Parameter( ) below. Returns the same array or $sql string as Prepare( ) above. Parameter($stmt, $var, $name, $isOutput=false, $maxLen = 4000, $type = false ) Adds a bind parameter in a fashion that is compatible with Microsoft SQL Server and Oracle oci8. The parameters are: $stmt Statement returned by Prepare() or PrepareSP(). $var PHP variable to bind to. Make sure you pre-initialize it! $name Name of stored procedure variable name to bind to. [$isOutput] Indicates direction of parameter 0/false=IN 1=OUT 2= IN/OUT. This is ignored in oci8 as this driver auto-detects the direction. [$maxLen] Maximum length of the parameter variable. [$type] Consult mssql_bind and ocibindbyname docs at php.net for more info on legal values for type. In mssql, $opt can hold the following elements: array('type' => integer, maxLen =>integer). Example:
# @RETVAL = SP_RUNSOMETHING @myid,@group $stmt = $db->PrepareSP('SP_RUNSOMETHING'); # note that the parameter name does not have @ in front! $db->Parameter($stmt,$id,'myid'); $db->Parameter($stmt,$group,'group',false,64); # return value in mssql - RETVAL is hard-coded name $db->Parameter($stmt,$ret,'RETVAL',true); $db->Execute($stmt);

An oci8 example:
# For oracle, Prepare and PrepareSP are identical $stmt = $db->PrepareSP( "declare RETVAL integer; begin :RETVAL := SP_RUNSOMETHING(:myid,:group);

102

end;"); $db->Parameter($stmt,$id,'myid'); $db->Parameter($stmt,$group,'group',false,64); $db->Parameter($stmt,$ret,'RETVAL',true); $db->Execute($stmt);

Note that the only difference between the oci8 and mssql implementations is the syntax of $sql. If $type parameter is set to false, in mssql, $type will be dynamicly determined based on the type of the PHP variable passed (string => SQLCHAR, boolean =>SQLINT1, integer =>SQLINT4 or float/double=>SQLFLT8). In oci8, $type can be set to OCI_B_FILE (Binary-File), OCI_B_CFILE (Character-File), OCI_B_CLOB (Character-LOB), OCI_B_BLOB (Binary-LOB) and OCI_B_ROWID (ROWID). To pass in a null, use $db->Parameter($stmt, $null=null, 'param'). Lastly, in oci8, bind parameters can be reused without calling PrepareSP( ) or Parameters again. This is not possible with mssql. An oci8 example:
$id = 0; $i = 0; $stmt = $db->PrepareSP( "update table set val=:i where id=:id"); $db->Parameter($stmt,$id,'id'); $db->Parameter($stmt,$i, 'i'); for ($cnt=0; $cnt < 1000; $cnt++) { $id = $cnt; $i = $cnt * $cnt; # works with oci8! $db->Execute($stmt); }

Bind($stmt, $var, $size=4001, $type=false, $name=false) This is a low-level function supported only by the oci8 driver. Avoid using unless you only want to support Oracle. The Parameter( ) function is the recommended way to go with bind variables. Bind( ) allows you to use bind variables in your sql statement. This binds a PHP variable to a name defined in an Oracle sql statement that was previously prepared using Prepare(). Oracle named variables begin with a colon, and ADOdb requires the named variables be called :0, :1, :2, :3, etc. The first invocation of Bind() will match :0, the second invocation will match :1, etc. Binding can provide 100% speedups for insert, select and update statements. The other variables, $size sets the buffer size for data storage, $type is the optional descriptor type OCI_B_FILE (Binary-File), OCI_B_CFILE (Character-File), OCI_B_CLOB (Character-LOB), OCI_B_BLOB (Binary-LOB) and OCI_B_ROWID (ROWID). Lastly, instead of using the default :0, :1, etc names, you can define your own bind-name using $name. The following example shows 3 bind variables being used: p1, p2 and p3. These variables are bound to :0, :1 and :2.
$stmt = $DB->Prepare("insert into table (col0, col1, col2) values (:0, :1, :2)"); $DB->Bind($stmt, $p1); $DB->Bind($stmt, $p2); $DB->Bind($stmt, $p3); for ($i = 0; $i < $max; $i++) { $p1 = ?; $p2 = ?; $p3 = ?; $DB->Execute($stmt); }

You can also use named variables:


$stmt = $DB->Prepare("insert into table (col0, col1, col2) values (:name0, :name1, :name2)"); $DB->Bind($stmt, $p1, "name0"); $DB->Bind($stmt, $p2, "name1"); $DB->Bind($stmt, $p3, "name2"); for ($i = 0; $i < $max; $i++) { $p1 = ?; $p2 = ?; $p3 = ?; $DB->Execute($stmt); }

103

fnExecute and fnCacheExecute properties These two properties allow you to define bottleneck functions for all sql statements processed by ADOdb. This allows you to perform statistical analysis and query-rewriting of your sql. For example, to count all cached queries and non-cached queries, you can do this:
# $db is the connection object function CountExecs($db, $sql, $inputarray) { global $EXECS; $EXECS++; } # $db is the connection object function CountCachedExecs($db, $secs2cache, $sql, $inputarray) { global $CACHED; $CACHED++; } $db = NewADOConnection('mysql'); $db->Connect(...);

$db->fnExecute = 'CountExecs'; $db->fnCacheExecute = 'CountCachedExecs';


: : # After many sql statements:` printf("<p>Total queries=%d; total cached=%d</p>",$EXECS+$CACHED, $CACHED);

The fnExecute function is called before the sql is parsed and executed, so you can perform a query rewrite. If you are passing in a prepared statement, then $sql is an array (see Prepare). The fnCacheExecute function is only called if the recordset returned was cached. The function parameters match the Execute and CacheExecute functions respectively, except that $this (the connection object) is passed as the first parameter.

104

ADOConnection Utility Functions


BlankRecordSet([$queryid]) No longer available - removed since 1.99. Concat($s1,$s2,....) Generates the sql string used to concatenate $s1, $s2, etc together. Uses the string in the concat_operator field to generate the concatenation. Override this function if a concatenation operator is not used, eg. MySQL. Returns the concatenated string. DBDate($date) Format the $date in the format the database accepts; this can be a Unix integer timestamp or an ISO format Y-m-d. Uses the fmtDate field, which holds the format to use. If null or false or '' is passed in, it will be converted to an SQL null. Returns the date as a quoted string. DBTimeStamp($ts) Format the timestamp $ts in the format the database accepts; this can be a Unix integer timestamp or an ISO format Y-m-d H:i:s. Uses the fmtTimeStamp field, which holds the format to use. If null or false or '' is passed in, it will be converted to an SQL null. Returns the timestamp as a quoted string. qstr($s,[$magic_quotes_enabled=false]) Quotes a string to be sent to the database. The $magic_quotes_enabled parameter may look funny, but the idea is if you are quoting a string extracted from a POST/GET variable, then pass get_magic_quotes_gpc() as the second parameter. This will ensure that the variable is not quoted twice, once by qstr and once by the magic_quotes_gpc. Eg. $s = $db->qstr(HTTP_GET_VARS['name'],get_magic_quotes_gpc()); Returns the quoted string. Quote($s) Quotes the string, automatically checking get_magic_quotes_gpc() first. If get_magic_quotes_gpc() is set, then we do not quote the string. Affected_Rows( ) Returns the number of rows affected by a update or delete statement. Returns false if function not supported. Not supported by interbase/firebird currently. Insert_ID( ) Returns the last autonumbering ID inserted. Returns false if function not supported. Only supported by databases that support auto-increment or object id's, such as PostgreSQL, MySQL and MSSQL currently. PostgreSQL returns the OID, which can change on a database reload. MetaDatabases() Returns a list of databases available on the server as an array. You have to connect to the server first. Only available for ODBC, MySQL and ADO. MetaTables()

105

Returns an array of tables and views for the current database as an array. The array should exclude system catalog tables if possible. MetaColumns($table) Returns an array of ADOFieldObject's, one field object for every column of $table. Currently Sybase does not recognise date types, and ADO cannot identify the correct data type (so we default to varchar).. MetaColumnNames($table) Returns an array of column names for $table. MetaPrimaryKeys($table) Returns an array containing column names that are the primary keys of $table. Only supported by mysql, postgres, oci8 currently. ServerInfo($table) Returns an array of containing two elements 'description' and 'version'. The 'description' element contains the string description of the database. The 'version' naturally holds the version number (which is also a string).

106

19.3 ADORecordSet
When an SQL statement successfully is executed by ADOConnection->Execute($sql),an ADORecordSet object is returned. This object contains a virtual cursor so we can move from row to row, functions to obtain information about the columns and column types, and helper functions to deal with formating the results to show to the user.

ADORecordSet Fields
fields: Array containing the current row. This is not associative, but is an indexed array from 0 to columns-1. See also the function Fields, which behaves like an associative array. dataProvider: The underlying mechanism used to connect to the database. Normally set to native, unless using odbc or ado. blobSize: Maximum size of a char, string or varchar object before it is treated as a Blob (Blob's should be shown with textarea's). See the MetaType function. sql: Holds the sql statement used to generate this record set. canSeek: Set to true if Move( ) function works. EOF: True if we have scrolled the cursor past the last record.

ADORecordSet Functions
ADORecordSet( ) Constructer. Normally you never call this function yourself. GetAssoc([$force_array]) Generates an associative array from the recordset if the number of columns is greater than 2. The array is generated from the current cursor position till EOF. The first column of the recordset becomes the key to the rest of the array. If the columns is equal to two, then the key directly maps to the value unless $force_array is set to true, when an array is created for each key. Inspired by PEAR's getAssoc. Example: We have the following data in a recordset:
row1: Apple, Fruit, Edible row2: Cactus, Plant, Inedible row3: Rose, Flower, Edible

GetAssoc will generate the following associative array:


Apple => [Fruit, Edible] Cactus => [Plant, Inedible] Rose => [Flower,Edible]

Returns: The associative array, or false if an error occurs. GetArray([$number_of_rows]) Generate a 2-dimensional array of records from the current cursor position, indexed from 0 to $number_of_rows - 1. If $number_of_rows is undefined, till EOF. GetRows([$number_of_rows]) Generate a 2-dimensional array of records from the current cursor position. Synonym for GetArray() for compatibility with Microsoft ADO. GetMenu($name, [$moreAttr='']) [$default_str=''], [$blank1stItem=true], 107 [$multiple_select=false], [$size=0],

Generate a HTML menu (<select><option><option></select>). The first column of the recordset (fields[0]) will hold the string to display in the option tags. If the recordset has more than 1 column, the second column (fields[1]) is the value to send back to the web server.. The menu will be given the name $name. If $default_str is defined, then if $default_str == fields[0], that field is selected. If $blank1stItem is true, the first option is empty. You can also set the first option strings by setting $blank1stItem = "$value:$text". $Default_str can be array for a multiple select listbox. To get a listbox, set the $size to a non-zero value (or pass $default_str as an array). If $multiple_select is true then a listbox will be generated with $size items (or if $size==0, then 5 items) visible, and we will return an array to a server. Lastly use $moreAttr to add additional attributes such as javascript or styles. Menu Example 1: GetMenu('menu1','A',true) will generate a menu: (C,3). Also see example 5.
A

for the data (A,1), (B,2),

Menu Example 2: For the same data, GetMenu('menu1',array('A','B'),false) will generate a menu with both A and B selected:
A B C

GetMenu2($name, [$moreAttr=''])

[$default_str=''],

[$blank1stItem=true],

[$multiple_select=false],

[$size=0],

This is nearly identical to GetMenu, except that the $default_str is matched to fields[1] (the option values). Menu Example 3: Given the data in menu example 2, GetMenu2('menu1',array('1','2'),false) will generate a menu with both A and B selected in menu example 2, but this time the selection is based on the 2nd column, which holds the values to return to the Web server. UserDate($str, [$fmt]) Converts the date string $str to another format.UserDate calls UnixDate to parse $str, and $fmt defaults to Y-m-d if not defined. UserTimeStamp($str, [$fmt]) Converts the timestamp string $str to another format. The timestamp format is Y-m-d H:i:s, as in '200202-28 23:00:12'. UserTimeStamp calls UnixTimeStamp to parse $str, and $fmt defaults to Y-m-d H:i:s if not defined. UnixDate($str) Parses the date string $str and returns it in unix mktime format (eg. a number indicating the seconds after January 1st, 1970). Expects the date to be in Y-m-d H:i:s format, except for Sybase and Microsoft SQL Server, where M d Y is also accepted (the 3 letter month strings are controlled by a global array, which might need localisation). This function is available in both ADORecordSet and ADOConnection since 1.91. UnixTimeStamp($str) Parses the timestamp string $str and returns it in unix mktime format (eg. a number indicating the seconds after January 1st, 1970). Expects the date to be in Y-m-d H:i:s format, except for Sybase and Microsoft SQL Server, where M d Y h:i:sA is also accepted (the 3 letter month strings are controlled by a global array, which might need localisation). This function is available in both ADORecordSet and ADOConnection since 1.91. 108

OffsetDate($dayFraction, $basedate=false) Allows you to calculate future and past dates based on $basedate in a portable fashion. If $basedate is not defined, then the current date (at 12 midnight) is used. Returns the SQL string that performs the calculation when passed to Execute(). For example, in Oracle, to find the date and time that is 2.5 days from today, you can use:
# get date one week from now $fld = $conn->OffsetDate(7); // returns "(trunc(sysdate)+7") # get date and time that is 60 hours from current date and time $fld = $conn->OffsetDate(2.5, $conn->sysTimeStamp); // returns "(sysdate+2.5)" $conn->Execute("UPDATE TABLE SET dodate=$fld WHERE ID=$id");

This function is available for mysql, mssql, oracle, oci8 and postgresql drivers since 2.13. It might work with other drivers provided they allow performing numeric day arithmetic on dates. SQLDate($dateFormat, $basedate=false) Use the native SQL functions to format a date or date column $basedate, using a case-insensitive $dateFormat, which supports:
Y: Q: M: D: 4-digit Year Quarter (1-4) Month (01-12) Day (01-31)

All other characters are treated as strings. You can also use to escape characters. Available on selected databases, including mysql, postgresql, mssql, oci8 and DB2. This is useful in writing portable sql statements that GROUP BY on dates. For example to display total cost of goods sold broken by quarter (dates are stored in a field called postdate):
$sqlfn = $db->SQLDate('Y-QQ','postdate'); # get sql that formats postdate to output 2002-Q1 $sql = "SELECT $sqlfn,SUM(cogs) FROM table GROUP BY $sqlfn ORDER BY 1 desc";

MoveNext( ) Move the internal cursor to the next row. The $this->fields array is automatically updated. Return false if unable to do so (normally because EOF has been reached), otherwise true. If EOF is reached, then the $this->fields array is set to false (this was only implemented consistently in ADOdb 3.30). Note that if false is returned, then the previous array in $this->fields is preserved. Example:
$rs = $db->Execute($sql); if ($rs) while (!$rs->EOF) { ProcessArray($rs->fields); $rs->MoveNext(); }

Move($to) Moves the internal cursor to a specific row $to. Rows are zero-based eg. 0 is the first row. The fields array is automatically updated. For databases that do not support scrolling internally, ADOdb will simulate forward scrolling. Some databases do not support backward scrolling. If the $to position is after the EOF, $to will move to the end of the RecordSet for most databases. Some obscure databases using odbc might not behave this way. Note: This function uses absolute positioning, unlike Microsoft's ADO. Returns true or false. If false, the internal cursor is not moved in most implementations, so AbsolutePosition( ) will return the last cursor position before the Move( ). MoveFirst() 109

Internally calls Move(0). Note that some databases do not support this function. MoveLast() Internally calls Move(RecordCount()-1). Note that some databases do not support this function. GetRowAssoc($toUpper=true) The above function is no longer the prefered way of getting associative arrays. Use the $ADODB_FETCH_MODE variable instead. Returns an associative array containing the current row. The keys to the array are the column names. The column names are upper-cased for easy access. To get the next row, you will still need to call MoveNext(). For example: Array ( [ID] =>1 [FIRSTNAME] =>Caroline [LASTNAME] =>Miranda [CREATED] =>2001-07-05 ) Note: do not use GetRowAssoc() with $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC. Because they have the same functionality, they will interfere with each other. AbsolutePage($page=-1) Returns the current page. Requires PageExecute()/CachePageExecute() to be called. See Example 8. AtFirstPage($status='') Returns true if at first page (1-based). Requires PageExecute()/CachePageExecute() to be called. See Example 8. AtLastPage($status='') Returns true if at last page (1-based). Requires PageExecute()/CachePageExecute() to be called. See Example 8. Fields($colname) This function is deprecated. Use $ADODB_FETCH_MODE instead. Some database extensions (eg. MySQL) return arrays that are both associative and indexed if you use the native extensions. GetRowAssoc() does not return arrays that combine associative and indexed elements. Returns the value of the associated column $colname for the current row. The column name is case-insensitive. FetchRow() Returns array containing current row, or false if EOF. FetchRow( ) internally moves to the next record after returning the current row. Warning: Do not mix using FetchRow() with MoveNext(). Usage:
$rs = $db->Execute($sql); if ($rs) while ($arr = $rs->FetchRow()) { # process $arr }

FetchInto(&$array) Sets $array to the current row. Returns PEAR_Error object if EOF, 1 if ok (DB_OK constant). If PEAR is undefined, false is returned when EOF. FetchInto( ) internally moves to the next record after returning the current row. FetchRow() is easier to use. See above. FetchField($column_number) 110

Returns an object containing the name, type and max_length of the associated field. If the max_length cannot be determined reliably, it will be set to -1. The column numbers are zero-based. See example 2. FieldCount( ) Returns the number of fields (columns) in the record set. RecordCount( ) Returns the number of rows in the record set. If the number of records returned cannot be determined from the database driver API, we will buffer all rows and return a count of the rows after all the records have been retrieved. This buffering can be disabled (for performance reasons) by setting the global variable $ADODB_COUNTRECS = false. When disabled, RecordCount( ) will return -1 for certain databases. See the supported databases list above for more details. RowCount is a synonym for RecordCount. PO_RecordCount($table, $where) Returns the number of rows in the record set. If the database does not support this, it will perform a SELECT COUNT(*) on the table $table, with the given $where condition to return an estimate of the recordset size. $numrows = $rs->PO_RecordCount("articles_table", "group=$group"); NextRecordSet() For databases that allow multiple recordsets to be returned in one query, this function allows you to switch to the next recordset. Currently only supported by mssql driver.
$rs = $db->Execute('execute return_multiple_rs'); $arr1 = $rs->GetArray(); $rs->NextRecordSet(); $arr2 = $rs->GetArray();

FetchObject($toupper=true) Returns the current row as an object. If you set $toupper to true, then the object fields are set to uppercase. Note: The newer FetchNextObject() is the recommended way of accessing rows as objects. See below. FetchNextObject($toupper=true) Gets the current row as an object and moves to the next row automatically. Returns false if at end-offile. If you set $toupper to true, then the object fields are set to upper-case.
$rs = $db->Execute('select firstname,lastname from table'); if ($rs) { while ($o = $rs->FetchNextObject()) { print "$o->FIRSTNAME, $o->LASTNAME<BR>"; } }

There is some trade-off in speed in using FetchNextObject(). If performance is important, you should access rows with the fields[] array. FetchObj() Returns the current record as an object. Fields are not upper-cased, unlike FetchObject. FetchNextObj() Returns the current record as an object and moves to the next record. If EOF, false is returned. Fields are not upper-cased, unlike FetctNextObject. CurrentRow( ) Returns the current row of the record set. 0 is the first row. 111

AbsolutePosition( ) Synonym for CurrentRow for compatibility with ADO. Returns the current row of the record set. 0 is the first row. MetaType($nativeDBType[,$field_max_length],[$fieldobj]) Determine what generic meta type a database field type is given its native type $nativeDBType as a string and the length of the field $field_max_length. Note that field_max_length can be -1 if it is not known. The field object returned by the database driver can be passed in $fieldobj. This is useful for databases such as mysql which has additional properties in the field object such as primary_key. Uses the field blobSize and compares it with $field_max_length to determine whether the character field is actually a blob. For example, $db->MetaType('char') will return 'C'. Returns: C: Character fields that should be shown in a <input type="text"> tag. X: Clob (character large objects), or large text fields that should be shown in a <textarea> D: Date field T: Timestamp field L: Logical field (boolean or bit-field) N: Numeric field. Includes decimal, numeric, floating point, and real. I: Integer field. R: Counter or Autoincrement field. Must be numeric. B: Blob, or binary large objects.

Since ADOdb 3.0, MetaType accepts $fieldobj as the first parameter, instead of $nativeDBType. Close( ) Close the recordset.

function rs2html($adorecordset,[$tableheader_attributes], [$col_titles])


This is a standalone function (rs2html = recordset to html) that is similar to PHP's odbc_result_all function, it prints a ADORecordSet, $adorecordset as a HTML table. $tableheader_attributes allow you to control the table cellpadding, cellspacing and border attributes. Lastly you can replace the database column names with your own column titles with the array $col_titles. This is designed more as a quick debugging mechanism, not a production table recordset viewer. You will need to include the file tohtml.inc.php. Example of rs2html:
<? include('tohtml.inc.php'); # load code common to ADOdb include('adodb.inc.php'); # load code common to ADOdb $conn = &ADONewConnection('mysql'); # create a connection $conn->PConnect('localhost','userid','','agora');# connect to MySQL, agora db $sql = 'select CustomerName, CustomerID from customers'; $rs = $conn->Execute($sql); rs2html($rs,'border=2 cellpadding=3',array('Customer Name','Customer ID')); ?>

112

Differences between this ADOdb library and Microsoft ADO


1. ADOdb only supports recordsets created by a connection object. Recordsets cannot be created independently. 2. ADO properties are implemented as functions in ADOdb. This makes it easier to implement any enhanced ADO functionality in the future. 3. ADOdb's ADORecordSet->Move() uses absolute positioning, not relative. Bookmarks are not supported. 4. ADORecordSet->AbsolutePosition() cannot be used to move the record cursor. 5. ADO Parameter objects are not supported. Instead we have the ADOConnection::Parameter( ) function, which provides a simpler interface for calling preparing parameters and calling stored procedures. 6. Recordset properties for paging records are available, but implemented as in Example 8.

113

20 Database Driver Guide


This describes how to create a class to connect to a new database. To ensure there is no duplication of work, kindly email me at jlim#natsoft.com.my if you decide to create such a class. First decide on a name in lower case to call the database type. Let's say we call it xbase. Then we need to create two classes ADODB_xbase and ADORecordSet_xbase in the file adodbxbase.inc.php. The simplest form of database driver is an adaptation of an existing ODBC driver. Then we just need to create the class ADODB_xbase extends ADODB_odbc to support the new date and timestamp formats, the concatenation operator used, true and false. For the ADORecordSet_xbase extends ADORecordSet_odbc we need to change the MetaType function. See adodb-vfp.inc.php as an example. More complicated is a totally new database driver that connects to a new PHP extension. Then you will need to implement several functions. Fortunately, you do not have to modify most of the complex code. You only need to override a few stub functions. See adodb-mysql.inc.php for example. The default date format of ADOdb internally is YYYY-MM-DD (Ansi-92). All dates should be converted to that format when passing to an ADOdb date function. See Oracle for an example how we use ALTER SESSION to change the default date format in _pconnect _connect. ADOConnection Functions to Override Defining a constructor for your ADOConnection derived function is optional. There is no need to call the base class constructor. _connect: Low level implementation of Connect. Returns true or false. Should set the _connectionID. _pconnect: Low level implemention of PConnect. Returns true or false. Should set the _connectionID. _query: Execute a query. Returns the queryID, or false. _close: Close the connection -- PHP should clean up all recordsets. ErrorMsg: Stores the error message in the private variable _errorMsg. ADOConnection Fields to Set _bindInputArray: Set to true if binding of parameters for SQL inserts and updates is allowed using ?, eg. as with ODBC. fmtDate fmtTimeStamp true false concat_operator replaceQuote hasLimit support SELECT * FROM TABLE LIMIT 10 of MySQL. hasTop support Microsoft style SELECT TOP 10 * FROM TABLE. ADORecordSet Functions to Override You will need to define a constructor for your ADORecordSet derived class that calls the parent class constructor. FetchField: as documented above in ADORecordSet

114

_initrs: low level initialization of the recordset: setup the _numOfRows and _numOfFields fields -called by the constructor. _seek: seek to a particular row. Do not load the data into the fields array. This is done by _fetch. Returns true or false. Note that some implementations such as Interbase do not support seek. Set canSeek to false. _fetch: fetch a row using the database extension function and then move to the next row. Sets the fields array. If the parameter $ignore_fields is true then there is no need to populate the fields array, just move to the next row. then Returns true or false. _close: close the recordset Fields: If the array row returned by the PHP extension is not an associative one, you will have to override this. See adodb-odbc.inc.php for an example. For databases such as MySQL and MSSQL where an associative array is returned, there is no need to override this function. ADOConnection Fields to Set canSeek: Set to true if the _seek function works.

20.1 Id kezelse PHP MySQL esetn


Az idpontok kezelse a Unix hagyomnyokra pl. A Unix idszmts kezdete 1970. janur.01, 0 ra 0 perc. Az idt a Unix rendszerek innen szmtott msodpercekben mrik s troljk. Ennek megfelelen a PHP s a MySQL is innen indul ki. A UNIX id elnevezse TIMESTAMP. Az gy kapott idpont azonban egy nagy egsz szm, amit az adatok bevitelnl s kiiratsnl nemigen lehet hasznlni, ezrt lteznek konverzis fggvnyek ilyen clokra. A PHP esetn az aktulis idpontot a string Date(formtumstring [,timestamp]) fggvny lltja el A fromtumstringben az albbi megjegyzsek lehetnek: v y kt karakter (01), Y 4 karakter hossz (2001) Hnap - m kt karakter, sorszm 01, 02,, M a hnap angol neve (January, February, ) Nap d kt karakter, a hnapban a nap sorszma, D elnevezse angolul (Monday, Thuesday, ) ra h 12 rs ciklus 00-12, H 24 rs ciklus kt karakter 00 - 23 Perc i kt karakter 00-59 Az eredmny teht string! Az idpont talaktsa TIMESTAMP formtumra az albbi fggvnnyel lehetsges:
int mktime (int ra, int perc, int msodperc, int hnap, int nap, int v [, int is_dst])

Amennyiben nem akarunk kitlteni bizonyos rtkeket, akkor 0-val kell feltlteni ket. Az utols paramter a nappal rtkt tartalmazza, ltalban elhagyhat, st gyakorlatilag elhagyand. A MySQL esetn az idpont trolsa s formtuma hasonlan ketts. Lehet trolni idpontot TIMESTAMP formtumban. Ekkor a UNIX timestamp lesz a bels trolsi formtum, de a megjelentsnl mr karaktersorozatot kapunk vissza. Ahhoz, hogy a PHP-nek megfelel Timestamp legyen egy lekrdezs eredmnye, a MySQL TIMESTAMP()fggvnyt kell hasznlni. Az albbiakban egy ilyen megoldsra ltunk pldt.
Function koncertlista($datum) { // A lekrdezs sszelltsa

115

$qry ="SELECT UNIX_TIMESTAMP(Mikor) AS Ido,Mi,Hol FROM esemeny WHERE Mikor > '".$datum."'"; $result = @mysql_query($qry, $fc); $str ="<UL>"; while ($a = mysql_fetch_object($result)) { $str .= "<LI>".date("Y.M.d, D H:i",$a->Ido).", ".$a->Mi."<BR>"; $str .= $a->Hol."<BR>Belp:".$a->Belepo." Ft</LI>"; } $str .="</UL>"; echo $str; return; } // Itt hvom meg az aktulis dtummal a fggvnyt. A formtum azrt fontos, mert csak gy // hasonlthat ssze a MySQL Timestamp-jvel. koncertlista(date("YmdHis")); Az eredmny az albbi lesz: 2002.Jan.12, Sat 09:12, Koncert Uj vrklub Belp:500 Ft

Az alkalmazott adattpus az SQL tblban a TIMESTAMP(14)

20.2 Sokig fut programok


A PHP scriptek futsnak a maximlis ideje korltozva van a PHP-ben, mert ha egy vgtelen ciklust r az ember, akkor lefagyaszthatja a szervert. A korlt default rtke 30 sec. Ha egy scriptnk mgis tovbb futna, mert valamilyen oknl fogva a feldolgozs lass, vagy esetleg egy adatbzisszervertl vr adatokat, akkor clszer hasznlnunk az albbi fggvnyt a PHP oldalunk elejn, mivel ez a kvnt ideig engedi futni a scriptet
Set_time_limit( msodperc)

Clszeren csak akkora rtket rjunk be, hogy a script biztonsgosan lefusson, ugyanakkor idejben ki is lpjen, ha kell. Ha idnek 0-t runk, akkor soha nem jr le a script, s ha vgtelen ciklust tesznk bele, akkor rkhajts lesz a scriptnk.

116

21 File-ok, knyvtrak kezelse a szerveren s tvoli URL-eken


Az albbi fejezetben megnzzk, hogy melyek a leggyakrabban hasznlt fggvnyek s mdszerek a PHP programokban. Amennyiben valaki gy vln, hogy ms fggvnyek gyakrabban hasznlatosak az programjaiban, nagyon sajnlom, a help alapjn kell megnzni a mkdsket sokszor n is ott nzem meg. Az albbi esetek fordulnak el a filekezelsnl leggyakrabban a PHP programok esetn: Tvoli szerverrl szeretnnk olvasni, vagy tvoli szerverre rni Helyi knyvtrszerkezetbl szeretnnk olvasni, vagy ide szeretnnk rni. Az rsnl elfordulhat, hogy a kimenetet a helyi standard outputra szeretnnk tenni. A fenti esemnyeket binris vagy text file esetn is meg akarjuk valstani. Helyi s tvoli gpen is szeretnnk knyvtrakat ltrehozni, vagy knyvtrakat trlni. Alkalmanknt kell vizsglnunk, hogy a krdses file a helyi filestruktrban vagy tvoli szerveren ltezik-e? Egy megadott elrsi tvonal file-ra, knyvtrra vagy link-re mutat-e? A fileok kezelshez j, ha tudjuk az albbiakat: o Az ppen aktulisan fut alkalmazs loklis szerveren lv elrsi tvonalt a $_SERVER[PATH_TRANSLATED] stringvltoz tartalmazza $_SERVER[SERVER_ROOT] vltoz tartalmazza a $_ENV[TEMP] vagy hasonl nev szupergloblis vltoz tartalmazza. o A WEB szerver gykrknyvtrt a o Az opercis rendszer temporary knyvtrt A file kezelsnl tundnunk kell, hogy az otthoni krnyezetben futtatott program elri-e az les szerveren is ugyanazt a knyvtrat. Ha egy web struktrban lv file-t kell elrnnk, akkor clszer kiindulnunk az ppen fut alkalmazs knyvtrbl. A fentiek alapjn, ha az index.php alkalmazsunk az albbi helyen fut: C:\wwwroot\valami s egy geza nev alknyvtrban lv szoveg.txt file-ra szeretnnk hivatkozni, akkor az albbi elrst kell alkalmazni:
$el = $_SERVER[PATH_TRANSLATED]./geza/szoveg.txt;

Az elrsi tvonalak kezelse sorn gyakori, hogy szt kell vlasztanom az elrsi utat knyvtr, filenv illetve kiterjeszts rszre. Az albbi fggvnyek a fenti elrsi utat vlasztjk szt:
$path = C:/wwwroot/valami/geza/szoveg.txt; $file = basename ($path); // $file rtke "szoveg.txt" $file = basename ($path,".txt"); // $file rtke "szoveg", mivel a msodik paramter hatsra // a vgrl levgja a megadott stringet. $dir = dirname ($path); // $d rtke C:\wwwroot\valami\geza" lesz.

Alternatv megolds a fenti feladatra lehet a pathinfo fggvny:


<?php $path_parts = pathinfo("/www/htdocs/index.html"); echo $path_parts["dirname"] . "\n"; echo $path_parts["basename"] . "\n"; echo $path_parts["extension"] . "\n"; ?>

117

Ha el akarjuk dnteni, hogy a filerendszer egy bejegyzse knyvtr, file, vagy egy link, akkor az albbi fggvnyeket hasznlhatjuk: boolean is_dir($path); boolean is_file($path); boolean is_link($path); Egy file tovbbi tulajdonsgait attributumait az albbi fggvnyekkel kaphatjuk meg: int is_executable($path )- Megmondja, hogy a bejegyzs futtathat-e int is_readable($filename) Megmondja, hogy a file olvashat-e int is_writeable($filename) Megmondja, hogy a file rhat-e int fileatime ($filename)- A file utols elrsi ideje. A visszaadott id UNIX idblyeg formjban int filemtime($filename) A file utols mdostsnak ideje Unix idblyeg formjban int Fileowner($filename) A file tulajdonosnak ID-je. Csak loklis filerendszerben hasznlhat. int fileperms($filename) A filera vonatkoz jogokat adja vissza. Csak loklis filerendszerben hasznlhat. int filesize($filename) - a file mrete
$filename = C:/wwwroot/valami/geza/szoveg.txt; echo filesize($filename);

A filekezels meglehetsen hasonlt a C-ben megszokottakra: Egy file olvassa eltt meg kell nyitnunk azt. Erre a clra az $fp = fopen($filenev, md) fggvnyt hasznlhatjuk, ahol a $filenv egy loklis filerendszer egy file-ja vagy egy URL-lel megadott file lehet. Ha windows rendszert hasznlunk, akkor a filenvben az elrsi tban szerepl knyvtrneveket a \\ jellel kell elvlasztani.
$fp=fopen (C:\\wwwroot\\index.htm,w);

Ha a $filenv a http:// vagy az ftp:// jelekkel kezddik, akkor egy tvoli szerveren lv file-rl van sz.
$fp = fopen(http://www.szily.sulinet.hu/index.html,r);

A file megnyitsnak mdja az albbi lehet: md lers r w Olvassra nyitom meg a file-t. File pointer a file elejn ll rsra nyitom meg a file-t. A file pointer a file elejre ll s ha volt ilyen file, akkor megsemmisl, zr hosszsgv vlik rsra s olvassra nyitom meg a file-t. A pointer a file elejre ll. rsra s olvassra nyitom meg a file-t. A pointer 118 Plda
$fp=fopen(C:\\autoexec.bat,r)

$fp=fopen(C:\\inetpub\\default.htm,w)

'r+' w+

$fp=fopen(C:\\inetpub\\adat.ini,r+)

$fp=fopen(C:\\inetpub\\adat.ini,w+)

'a' a+ b

a file elejre ll. A file megnyitskor 0 hosszsgra csonkoldik rsra nyitom meg a file-t. A pointer a file vgre ll. rsra s olvassra nyitom meg a file-t. A pointer a file vgre ll. Ha biztosan binris file-t akarok olvasni vagy rni, akkor a megnyitskor a md stringbe be kell rni ezt is.
$fp=fopen(C:\\inetpub\\adat.ini,a)

$fp=fopen(C:\\inetpub\\adat.ini,a+)

$fp=fopen(C:\\autoexec.bat,rb)

A fenti utasts hibazenetet ad, ha nem ltezik az olvassra megnyitni akart file. Ezrt a hibakezelshez az albbiakat kell tenni:
if (file_exists($File)) // Ltezik a file? { $fp = fopen($File,"r"); // Megnyitjuk olvassra .....

Mieltt olvasni szeretnnk egy file-t, meg kell nzni, hogy ltezik-e. A ltezs ellenrzsre a Boolean file_exists($filename) fggvnyt hasznlhatjuk. A visszatrsi rtke igaz, ha a file ltezik, hamis egybknt. Ha az fopen-nel megnyitottunk egy filet rsra s egy karaktert vagy byte informcit akarunk beolvasni, akkor az albbi fggvnyt hasznlhatjuk $c =fgetch($fp); Ha az fopen-nel megnyitottunk egy filet rsra, s egy text file egy sort akarjuk beolvasni, akkor az albbi fggvnyt hasznljuk: $sor = fgets($fp[,sorhossz]); A sorhossz paramter nem ktelez, ha nem tesszk ki, akkor alaprtke 1024 karaktert olvas a fggvny. Ha az fopen-nel megnyitottunk egy filet rsra s, ki akarom szedni a beolvasott filebl az esetlegesen benne lv html tag-okat, akkor ezt kell hasznlni. $sor=fgetss($fp[,sorhossz]); Ha nem adjuk meg a sorhosszat, akkor max 1024 hossz stringet olvas be. Ha egy text file sszes sort be akarjuk olvasni egy tmbbe, akkor az albbi fggvnyt kell hasznlni: $aline =file($Filename[,int include_path]) A fggvny beolvassa a megadottt $Filename elrsi tvonal text file sorait egy $aline nev tmbbe. A fggvnnyel nemcsak a loklis filerendszerbl, hanem URL-lel megadott file-bl is lehet olvasni! Ha a file nem ltezik, akkor hibazenet keletkezik, s a tmb elemszma 0 marad. A kezelsre nzzk az albbi pldt a Help alapjn:
<?php // A beolvasand file egy URL-lel van megadva. $filename =http://www.szily.hu/szily/szily.css; $asor = @file($filename); if(count($asor==0)){ die(Nem ltez file); }

119

// A beolvasott file feldolgozsa s a sorok kiiratsa. // A html sorokat kirja, mint html szveg, sor s sorszmot is kir. foreach ($asor as $line_num => $sor) { echo "#<b>{$line_num}</b> sor : " . htmlspecialchars($sor) . "<br>\n"; } // Ez a plda egy file-t beolvas, majd a sorokat egy stringg sszevonja. $html = implode ('', file ('http://www.szily.hu/szily/')); ?>

Ha egy teljes file-t akarunk beolvasni, akkor az albbi fggvnyt kell hasznlnunk: $t=fread($fp,$filesize( $filenev)); A filesize($filenev) fggvny megadja az adott file mrett byte-okban s a paramter hatsra a filemretnek megfelel puffert foglal le a memriban a PHP. A visszatrsi rtk vltozja tartalmazza majd a file sszes byte-jt, mint string. Ez a fggvny binris olvasskor hasznlhat igazn, mert a beolvasott tartalommal semmifle konverzi nem trtnik. Egy rsra vagy rsra/olvassra megnyitott fileokba val rsnl alapvet fggvny az int fwrite($fp,$c); Ha a kiirand rtk egy karakter, akkor karakterenknt runk, ha egy textfile egy sora, akkor a sorvge jelet hozz kell tennnk a kiirand tartalomhoz az albbi mdon:
$c=$sor,\r\n;

Ha egy file tartalmt akarjuk kiiratni, akkor a vltoz tartalmazza a teljes tartalmat. lljon itt filekezelsre egy komplexebb plda. Egy file-bl olvasnom kell, de ehhez elszr meg kell nyitnom.
<!Ez a program megvalst egy egyszer karakter alap szmllt. A szmll pillanatnyi rtke a counter.txt llomnyban van, amit a szkript beolvas rtkt minden egyes beolvass sorn megnveli, a megnvelt rtket ugyanabba a fileb visszarja, majd a szmll llst megjelenti. Ahhoz, hogy program megfelelen mkdjn a counter.txt llomnyt ltre kell hoznunk, melynek tartalma csak '1' legyen, ezt a filet fel kell tltennk ugyanabba a knyvtrba, ahol a program van, s rsi jogosultsgot kell adnunk r. --> <hr> Ltogatk szma:<BR> <?php $File = 'counter.txt'; // A szmll file neve if (file_exists($File)) // Ltezik a file? { $fp = fopen($File,"r"); // Megnyitjuk olvassra $num = fread($fp, filesize($File)); // Beolvassuk a tartalmt a $num vltozba. fclose($fp); // Zrjuk a filet. $num=$num+1; // A vltoz rtkt megnveljk $fp = fopen($File,"w"); // Megnyitjuk ugyanazt a filet, de most rsra fwrite($fp, $num, 10); // Kirjuk a vltoz rtkt. fclose($fp);

120

// Zrjuk a filet echo('<b>'.chop($num).'</b>'); // Kirjuk a HTML-kdba a vltoz rtkt. } ?> <hr>

Az albbiakban elmondjuk a filekezelshez szksges tudnivalkat.

121

22 Grafika
A PHP-ban a grafikai modult nem a kpek egyszer kittelre hasznlhatjuk, hanem a szerver oldalon kpekkel vgzett manipulcikra. A PHP grafikhoz szksges, hogy a szerver oldalon be legyen tltve a GD.DLL vagy a GD_2.DLL (Windows szerver esetn). A GD_2.DLL tmogatja a BMP, JPEG, GIF, s PNG kpekkel vgzett manipulcikat. Az albbi mintban egy fotoalbum kszt s hazsnl programot mutatunk be. A program az els meghvsakor az aktulis knyvtrban lv kpekrl kiskpeket kszt, majd tblzatos formban megjelenti azokat. A programot objektum-orientlt formban rtam meg.
<?php /* Simple PhotoAlbum 2.2.1.2004.06.02 (c) by Zoltn Fbin, 1999-2004 Use the program free. email: fz@szily.hu This script works on this site: http://fz.szily.hu, http://www.alarmsystem.hu/fotoalbum Hasznlata include("../photoalbum.php"); */ if(stristr($_SERVER["PHP_SELF"], __FILE__)) die("Nem hvhatod meg a file-t kzvetlenl!..."); if(!defined("THUMBNAIL_WIDTH")) define("THUMBNAIL_WIDTH",150); define("SERVERTARGET",str_replace(".","_",$_SERVER["SERVER_NAME"])); define("DOCUMENT_ROOT",$_SERVER["DOCUMENT_ROOT"].(( substr($_SERVER["DOCUMENT_ROOT"],-1)!="/") ? "/" :"")); define("PHOTOSCRIPT",relpath(__FILE__)); //The path of this script define("PHOTOALBUM","__photoalbum.txt"); define("DELIMITER","#"); define("CSV_OK",True); if(!isset($col)) $col = 4; define("COLUMNS", $col); if(!isset($slide)) $slide = 5; define("SLIDE", $slide); //Needed gd extension DEFINE("GD",True); if(!extension_loaded ("gd")) { if(ini_get("enable_dl")) { DEFINE("GD",dl("gd.dll")); }else{ DEFINE("GD",False); } } // Number of columns

//The DO

// timeout of the sliding

122

// ---------- Image class image { var $Name; // var $Thumb; // var $dx; // var $dy; var $Text; //

osztly ----------Picture picture Thumbnail name size of picture text under the picture

function image($Entry="",$Txt="") { global $aktdir,$newThumbnails; if(strlen($Entry)>0) { $this->Name = $Entry; //get size of picture if(GD) { $size = GetImageSize($aktdir.$this->Name); }else{ $size=array(800,600); } $this->dx = $size[0]; $this->dy = $size[1]; //Text under the pictures if (strlen($Txt)>0){ $this->Text = $Txt; }else{ $pos = explode(".",$Entry); $this->Text = str_replace("_"," ",$pos[0]); } //Is there thumbnail of image? $thn = $aktdir."tn_".$this->Name; $origDate = filemtime ( $aktdir.$this->Name); $isthn = is_file($thn); $thDate = $isthn ? filemtime ( $thn): 0; //print($origDate ." ".$thDate."<BR>"); if((!$isthn || ($origDate > $thDate ))&& GD ) { $this->NewThumbnail(); $newThumbnails++; }else{ $this->ReadThumbnail(); } }else{ $this->Name = ""; $this->dx = 0; $this->dy = 0; $this->Text = ""; } }

123

//Make new thumbnails from GIF, PNG or JPG | JPEG |bmp! function NewThumbnail () { global $gd, $aktdir; //size of original big picture $size = GetImageSize($aktdir.$this->Name); $dx = $size[0]; $dy = $size[1]; $a = eregi("\.gif",$aktdir.$this->Name); if((!eregi("\.gif",$aktdir.$this->Name)) && (($dx> THUMBNAIL_WIDTH) |($dy>THUMBNAIL_WIDTH))) { if (eregi("\.jpg|\.jpeg",$aktdir.$this->Name)) { $im = ImageCreateFromJPEG ($aktdir.$this->Name); //Empty destination image $dst_im = @ImageCreateTrueColor( THUMBNAIL_WIDTH, THUMBNAIL_WIDTH*$dy /$dx); } if (eregi("\.png",$aktdir.$this->Name)){ $im = @ImageCreateFromPNG ($pics->ImagePath.$this->Name); $dst_im = @ImageCreateTrueColor(THUMBNAIL_WIDTH, THUMBNAIL_WIDTH*$dy /$dx); } if (eregi("\.wbmp",$aktdir.$this->Name)){ $im = @ImageCreateFromwbmp ($pics->ImagePath.$this->Name); $dst_im = @ImageCreateTrueColor(THUMBNAIL_WIDTH, THUMBNAIL_WIDTH*$dy /$dx); } if (eregi("\.bmp",$aktdir.$this->Name)){ $im = @ImageCreateFromwbmp ($aktdir.$this->Name); $dst_im = @ImageCreateTrueColor(THUMBNAIL_WIDTH, THUMBNAIL_WIDTH*$dy /$dx); } // Image resize and copy from source to destination $a = imagecopyresized ($dst_im, $im, 0, 0, 0, 0, THUMBNAIL_WIDTH, THUMBNAIL_WIDTH*$dy/$dx, $dx, $dy); $this->Thumb = $aktdir."tn_".$this->Name; //New image on disk Imagejpeg ($dst_im, $this->Thumb); }else{ $this->Thumb = $aktdir."tn_".$this->Name; copy($aktdir.$this->Name,$aktdir."tn_".$this->Name); } } //Thumbnail reading function ReadThumbnail(){ if(GD) { $this->Thumb = "tn_".$this->Name; }else{ $this->Thumb = $this->Name; } }

124

//Write out a thumbnail into the table function ShowThumbnail() { $str=$this->GetString(); print($str); } //get the string of a thumbnail function GetString() { global $css_td,$css_link,$pics; $str = "<TD ".$css_td." ALIGN=\"CENTER\" VALIGN=\"top\">"; $str .= "<a href='javascript:picturepopup(\"". PHOTOSCRIPT."?getimg=".$this->Name."&picpath=". $pics->ImageWebPath."\",\"".SERVERTARGET."\")' ". $css_link.">\n"; $str .= "<IMG SRC=\"".$this->Thumb."\" ALT=\"".$this->Name. "\" border=\"0\" width=\"".THUMBNAIL_WIDTH."\" ><BR>". $this->Text."</a>\n"; $str .= "</TD>"; return $str; } } //-------- Image list class ----------class ImageList { var $aPictures = array(); //Array of images var $ImageNumber; var $RowNumber; //number of rows var $ImagePath; //The directory of list var $ImageWebPath; //The Path in the website var $CSV_OK; var var var var var var var $css_file; $css_link; $css_body; $css_table; $css_tr; $css_td; $css_tag; //styles

//It makes a list from the actual directory function ImageList($path) { $this->newThumbnails = 0; $this->ImageNumber = 0; $this->ImagePath = $path; $this->ImageWebPath = substr(relpath($path),0,-1); if(CSV_OK){ $aCSV = array(); if (file_exists(PHOTOALBUM)){ $row = 1; $handle = fopen (PHOTOALBUM,"r"); while ($row = fgetcsv ($handle, 1000, DELIMITER)) { $aCSV[$row[0]] = $row[1]; } fclose ($handle); }else{ $handle=fopen(PHOTOALBUM,"w"); fclose($handle); } } //Make an Image object $d=opendir($path); while($entry=readdir($d)){ if ($this->is_image($entry)) {

125

$text=$entry; //Handling CSS text if(CSV_OK){ if(isset($aCSV)){ if(isset($aCSV[$entry])){ $text=$aCSV[$entry]; }else{ $handle = fopen(PHOTOALBUM,"a"); fwrite($handle,$entry.DELIMITER.$entry."\n"); fclose($handle); } }else{ $handle = fopen(PHOTOALBUM,"a"); fwrite($handle,$entry.DELIMITER.$entry."\n"); fclose($handle); } } $this->aPictures[] = new Image($entry,$text); $this->ImageNumber++; } } closedir($d); sort($this->aPictures); $this->RowNumber = (int) ($this->ImageNumber / COLUMNS ); } //Is Image this filename function is_image($str){ //This is the right soluton. $str="_".strtolower($str); //exclude thumbnails $pos = strpos ($str, "tn_"); if ($pos ==1){ return FALSE; }else{ return eregi("\.gif|\.jpg|\.jpeg|\.bmp|\.png",$str); } } function css(){ global $css_file,$css_link,$css_body,$css_table,$css_tr,$css_td,$css_tr; $this->css_file = ( isset($_GET["css_file"]) )? $_GET["css_file"] : (isset($css_file) ? $css_link : False); $this->css_link = ( isset($_GET["css_link"]) )? $_GET["css_link"] : (isset($css_link) ? $css_link : "style=\"font-family: Verdana,Arial, Helvetica, sans-serif; font-size: x-small; color: #000000\""); $this->css_body = ( isset($_GET["css_body"]) )? $_GET["css_body"] : (isset($css_body) ? $css_body : "style=\"background-color: #666666;\""); $this->css_table = ( isset($_GET["css_table"]))? $_GET["css_table"]: (isset($css_table)? $css_table: "style=\"border:0;\""); $this->css_tr = ( isset($_GET["css_tr"] ))? $_GET["css_tr"] : (isset($css_tr) ? $css_tr : "style=\"vertical-align:top;\""); $this->css_td = ( isset($_GET["css_td"] ))? $_GET["css_td"] : (isset($css_td) ? $css_td : "align=\"center\""); $this->css_tag = ( isset($_GET["css_tag"] ))? $_GET["css_tag"] : (isset($css_tag) ? $css_tag : "class=\"kapcsolat\""); } //It makes a table from the pictures function ShowList() { $str=$this->GetString(); print($str); }

function GetString() { global $css_table,$css_tr,$css_td,$newThumbnails;

126

$str = picturepopup(); $str .= "<TABLE ".$css_table.">";// Border=\"0\">\n\r"; $str .= "<TR ".$css_tr.">\n\r"; $j=0; while (list ($key, $ertek) = each ($this->aPictures)) { $str .=$this->aPictures[$key]->GetString(); $j++; if ($j == COLUMNS){ $str .="</TR>\n\r<TR>"; $j =0; } } while(0<$j && $j<COLUMNS){ $str .= "<TD ".$css_td.">&nbsp;</TD>"; $j++; } $str .="</TR>\n\r"; $str .="</TABLE>\n\r"; if ($newThumbnails>0){ $str .="<p align='center' style='color: #ff0000'> Found ". $newThumbnails." new pictures and made thumbnails!</p>"; $newThumbnails=0; } Return $str; } //Searches an image in array function Search($image) { $i =0; while( ($i<sizeof($this->aPictures) ) && ($this->aPictures[$i]->Name != $image) ) { $i++; } return $i; } function PreviousImage($idx){ if($idx==0) $idx = sizeof($this->aPictures); $idx--; Return $idx; } function NextImage($idx) { if($idx==sizeof($this->aPictures)-1) $idx=-1; $idx++; Return $idx; } } class popup { var $Image; var $PrevImage; var $NextImage; var $dx; //width of popup var $dy; //height of popup var $dxx; //width of picture var $dyy; //height of picture function popup($getimg){ global $pics; $idx= $pics->Search($getimg); $this->Image = new Image();

127

$this->PrevImage $this->NextImage $this->Image $this->PrevImage $this->NextImage $this->dxx

= = = = = =

new Image(); new Image(); $pics->aPictures[$idx]; $pics->aPictures[$pics->PreviousImage($idx)]; $pics->aPictures[$pics->NextImage($idx)]; ($this->Image->dx<600) ? (600) :($this->Image->dx);

if ($this->dxx>1024) $this->dxx = 1024; $this->dyy = ($this->Image->dy) *$this->dxx/$this->Image->dx; $this->dx = $this->dxx + 28; $this->dy = $this->dyy + 40; } function GetString(){ global $pics,$isslide; //Javascript for show the picture $str ="<HTML>\n"; $str .="<HEAD>\n"; $str .="<TITLE>Kep:".$this->Image->Name."</TITLE>\n"; if($isslide) { $str .="<META HTTP-EQUIV=REFRESH CONTENT=\"".SLIDE.";URL=".basename($_SERVER["PATH_TRANSLATED"])."?getimg=".urlenco de($this->NextImage->Name)."&isslide=1\">"; } $str .="</HEAD>\n"; $str .= picturepopup(); $str .="<BODY style=\"background-color: #666666;\" style=\"margin:0\">\n"; $str .="<DIV ALIGN=CENTER>\n"; $str .="<A HREF='javascript:picturepopup(\"".PHOTOSCRIPT."?getimg=".$this>PrevImage->Name."&picpath=".$pics->ImageWebPath."\",\"".SERVERTARGET."\")' style=\"font-family: Verdana,Arial, Helvetica, sans-serif; font-size: x-small; color: #000000\" ".$pics->css_tag.">[::Prev::</A>\n"; $str .="<A HREF='javascript:picturepopup(\"".PHOTOSCRIPT."?getimg=".$this>NextImage->Name."&picpath=".$pics->ImageWebPath."\",\"".SERVERTARGET."\")' style=\"font-family: Verdana,Arial, Helvetica, sans-serif; font-size: x-small; color: #000000\" ".$pics->css_tag.">::Next::</A>\n"; $str .="<A HREF='javascript:picturepopup(\"".PHOTOSCRIPT."?getimg=".$this>NextImage->Name."&picpath=".$pics>ImageWebPath."&isslide=1\",\"".SERVERTARGET."\")' style=\"font-family: Verdana,Arial, Helvetica, sans-serif; font-size: x-small; color: #000000\" ".$pics->css_tag.">::Slide::</A>\n"; $str .="<A HREF='javascript:picturepopup(\"".PHOTOSCRIPT."?getimg=".$this>Image->Name."&picpath=".$pics->ImageWebPath."\",\"".SERVERTARGET."\")', style=\"font-family: Verdana,Arial, Helvetica, sans-serif; font-size: x-small; color: #000000\" ".$pics->css_tag.">::Stop::</A>\n"; $str .="<A HREF=\"Javascript:void()\" onClick=\"self.close()\" ".$pics>css_tag.">::Close::]</A>\n"; $str .="<BR>\n"; $str .="<IMG SRC=\"".$pics->ImageWebPath."/".$this->Image->Name."\" width=\"".$this->dxx."\">\n"; $str .="</DIV>\n"; $str $str $str $str $str $str $str $str $str $str $str .="<SCRIPT language=\"JAVASCRIPT1.4\">\n"; .=" dx = ".$this->dx.";\n"; .=" dy = ".$this->dy.";\n"; .=" if(self.OuterWidth < dx) {\n"; .=" dy = (int)(dy * self.OuterWidth /dx);\n"; .=" dx = self.innerWidth;\n"; .=" }\n"; .=" if(self.OuterHeight < dy) {\n"; .=" dx = (int)(dx * self.OuterHeight /dy);\n"; .=" dy = self.OuterHeight;\n"; .=" }\n";

128

$str .=" self.resizeTo(dx, dy)\n"; $str .="</SCRIPT>\n"; $str .="</BODY>\n"; $str .="</HTML>\n"; return $str; } function Show() { print($this->GetString()); } } // ************ Some functions ************ function picturepopup(){ $str = "<SCRIPT LANGUAGE=\"JAVASCRIPT1.2\">\n"; $str .= " function picturepopup(url,target){\n"; $str .= " winpops=window.open(url,target,\"status=0,resizable=1,location=0,menubar=0,scr ollbars=0,toolbar=0\");\n"; $str .= " }\n"; $str .= "</SCRIPT>\n"; return $str; } function CSS_File_search() { $lines = file ($_SERVER["PATH_TRANSLATED"]); $keresendo = "text/css"; $csere = array("<",">","\""); $lnk = " "; $ok = False; while ((list ($kulcs, $ertek) = each ($lines)) && !$ok){ $e = strtolower($ertek); $p = strpos($e,$keresendo); if($p>0) { $ok = True; $p1 = strpos($e,"href"); $e1 = substr($e,$p1+6); $e2 = explode(" ",$e1); $lnk= substr($e2[0],0,-1); } } Return $lnk; } //Searching for the css style after the body tag function CSS_Body_search() { $fname =$_SERVER["PATH_TRANSLATED"]; $handle = fopen ($fname, "r"); $contents = fread ($handle, filesize ($fname)); fclose ($handle); $text = strtolower($contents); $text = str_replace(" ", "", $text); $atags = array(); $atags = explode("<body",$text); if (sizeof($atags) >1 ){ $lnk =""; $p = explode("\"",$atags[1]); $lnk = $p[0]; }else { $lnk ="style=\"background-color: #666666\""; } Return $lnk; }

129

function relpath($dir){ $dir=str_replace("\\","/",$dir); $len = strlen(DOCUMENT_ROOT); return substr($dir,$len-1); } function pathcomp($p){ return (( substr($p,-1)!= "/") ? ($p."/") : ($p) ); } /************* end of functions ***********/ /****************** * The main program ****************/ $newThumbnail =0; //*********************** Calling parameters ************** $isslide = ( isset($_GET["isslide"] ) )? $_GET["isslide"] : (isset($isslide) ? $isslide :False); $getimg = ( isset($_GET["getimg"] ) )? $_GET["getimg"] : (isset($getimg) ? $getimg : ""); //The name of viewing picture //The path of actual pictures if (!isset($aktdir)){ //from calling script first if (isset($_GET["picpath"])){ //From somewhere $aktdir =substr(DOCUMENT_ROOT,0,-1).$_GET["picpath"]; } else { //Slide $aktdir = dirname($_SERVER["PATH_TRANSLATED"])."/"; } } $aktdir=pathcomp($aktdir); $pics = new ImageList($aktdir); //******************* searching for css style settings ***************** if(!isset($pics->css_file)) $pics->css_file = CSS_File_search(); if(!isset($pics->css_link)) $pics->css_body = CSS_Body_Search(); //****************** main things ***************** if( !$getimg){ $pics->Showlist(); }else{ $p = new popup($getimg); $p->show(); } ?>

// ************* show one Image ******************

130

23 A krnyezet feldolgozsa, azonosts

131

24 Belptets, jelszavak alkalmazsa, titkosts


Az albbi forrst hasznltam fel a kvetkez oldalak lershoz: http://hotwired.lycos.com/webmonkey/00/05/index2a_page2.html?tw=programming Amikor egy knyvtrat vagy html oldalt le akarunk vdeni azonost nvvel s jelszval, akkor elszr is meg kell szerveznnk a WEB szerver oldali vdelmet. Ez a klnbz WEB szerverek esetn mindig egy kicsit mskppen megy. Az Apache WEB szerver esetn is tbb lehetsg knlkozik, de taln a kvetkez a legegyszerbb: Tegyk fel, hogy a /wwwroot/ceg nev knyvtrat szeretnnk levdeni: A vdett knyvtrban ltre kell hozni a .htaccess nev file-t. Ennek a tartalma:
AuthType Basic AuthName "Vedett terlet" AuthUserFile /wwwroot/ceg/.htpasswd AuthGroupFile /dev/null <Limit GET POST PUT> require valid-user </Limit>

A szerveren be kell lltani a megfelel knyvtrra az albbi sorokat:


httpd.conf <Directory "/wwwroot"> ... AllowOverride AuthConfig ... </Directory> //itt a www gykrknyvtrrl van sz

// a ksbbiek sorn be kell tltve lennik az albbi soroknak LoadModule LoadModule LoadModule LoadModule LoadModule LoadModule LoadModule LoadModule LoadModule anon_auth_module modules/mod_auth_anon.so dbm_auth_module modules/mod_auth_dbm.so digest_auth_module modules/mod_auth_digest.so digest_module modules/mod_digest.so expires_module modules/mod_expires.so headers_module modules/mod_headers.so info_module modules/mod_info.so status_module modules/mod_status.so php4_module x:/php/sapi/php4apache.dll #Ez itt a PHP4 miatt kell

Az albbi knyvtrban /apache/bin le kell futtatni az albbi parancsot:


htpasswd /wwwroot/ceg/.htpasswd usernv

Ennek hatsra ltrejn egy text file, amiben a usernv s a hozz tartoz jelsz tallhat. Ha tbb usert akarunk azonosttatni, akkor ltre kell hozni egy user groupot s abban a usereket definilni. Pldul ltrehozzuk a .htgroup nev file-t, amiben definiljuk a csoportot:
userek: bela geza user1 user2

Lefuttatjuk a jelszgenerlst tbbszr


htpasswd htpasswd htpasswd htpasswd /wwwroot/ceg/.htpasswd /wwwroot/ceg/.htpasswd /wwwroot/ceg/.htpasswd /wwwroot/ceg/.htpasswd bela geza user1 user2

Mdostjuk a htaccess file tartalmt: 132

AuthUserFile /wwwroot/ceg/.htpasswd AuthGroupFile /wwwroot/ceg/.htgroup AuthName userek AuthType Basic <Limit GET> require group dorks </Limit>

Az adott knyvtr oldalnak lekrsekor a szerver elkldi a bngsznek a 401-es hibakdot, amely utastja a bngszt, hogy jelentse meg az adatok bevitelre alkalmas oldalt prbeszdablakot.

Itt beviszi a felhasznl az adatokat, amit a szerver ellenriz. A fenti mdszer hasznlathoz nincsen szksg PHP kzremkdsre, ugyanakkor nagy szm felhasznl esetn nem tl gyors a mdszer, csak a szerveren lehet mdostani a userlistt s a jelszavakat. A belptetsre tbb megfelel mdszer knlkozik a PHP esetn. Ha modulknt futtatjuk a PHP-t, akkor viszonylag egyszeren biztosthatjuk, hogy egy HTTP bekrst szimullhassunk, csak az albbi sorokat kell elkldeni a bngsznek:
header('WWW-Authenticate: Basic realm="Magnterlet!"'); header('HTTP/1.0 401 Unauthorized'); echo 'Authorization Required.'; exit;

Ennek hatsra a $PHP_AUTH_USER s $PHP_AUTH_PWD vltozk fogjk tartalmazni a bevitelnl adott vlaszt. Ekkor sessionok segtsgvel minden oldalon felhasznlhatjuk a vltozk rtkeit. Ha CGI mdszerrel futtatjuk a PHP-t, akkor sajnos nem egyszer a fenti vltozk hasznlata, ekkor gondoskodni kell arrl, hogy minden oldal hvsakor a vltoz tartalma taddjon. A tovbbiakban bemutatjuk kt pldn, hogy mi trtnik akkor, ha egy prbeszdablakban bekrtk a kt vltoz rtkt. Egy lehetsg, hogy ltrehozzunk egy beviteli ablakot egy HTML form segtsgvel, majd POST metdussal elkldjk az eredmnyt a kvetkez oldalnak.
<Form method=POST ACTION=login.php> <p>Krem a usernevet: <INPUT Type=text NAME=PHP_AUTH_USER SIZE=60><BR> Krem a jelszt: <INPUT TYPE =PASSWORD NAME=PHP_AUTH_PWD><BR> <INPUT TYPE=SUBMIT NAME=OK> <INPUT TYPE=RESET NAME=RESET> </Form>

A login.php oldal leellenrzi, hogy a megfelel usernv jelsz pros szerepel-e benne. Az ellenrzs trtnhet adatbzisbl vagy sima text file-bl is.

133

<?php // Megvizsgljuk, hogy az elz form-bl kapott adatok kztt ltezik-e //a $PHP_AUTH_USER vltoz s tartalmaz-e adatokat. if (!isset($PHP_AUTH_USER)) { // Ha nem ltezik, a vltoz, akkor elkldnk egy fejlcet a bngsznek. header('WWW-Authenticate: Basic realm="Magnterlet!"'); header('HTTP/1.0 401 Unauthorized'); exit; } else if (isset($PHP_AUTH_USER)) { // Ha nem res a vltoz, akkor megnzzk, hogy az adatbzisban megvan-e // a megfelel usernv jesz pros // MySQL kapcsolatot hozunk ltre. Az itteni usernv nem azonos a belptet userrel! mysql_connect("hostname", "username", "password") or die ("Unable to connect to database."); // Megnyitjuk a jelszadatbzist mysql_select_db("Userlista") or die ("Unable to select database.");

// Elkldjk a lekrdezst a users tblra $sql = "SELECT * FROM users WHERE username='$PHP_AUTH_USER' and password='$PHP_AUTH_PW'"; // Vgrehajtjuk, majd az eredmny a $result vltozba kerl $result = mysql_query($sql); // Ha az eredmnynek 0 sora van, akkor nincs ilyen user s jelsz pros, // ha 1, akkor van $num = mysql_numrows($result); if ($num != "0") { echo "<P>Isten hozott!</p>"; exit; } else { header('WWW-Authenticate: Basic realm="Magnterlet!"'); header('HTTP/1.0 401 Unauthorized'); echo 'Authorization Required.'; exit; } } ?>

Hasonl megolds, amikor egy text file-t hasznlunk az authentikcihoz:


<?php // Megvizsgljuk, hogy az elz form-bl kapott adatok kztt ltezik-e //a $PHP_AUTH_USER vltoz s tartalmaz-e adatokat. if (!isset($PHP_AUTH_USER)) { // Ha nem ltezik, a vltoz, akkor elkldnk egy fejlcet a bngsznek. header('WWW-Authenticate: Basic realm="Magnterlet!"'); header('HTTP/1.0 401 Unauthorized'); exit; } else if (isset($PHP_AUTH_USER)) { // Ha nem res a vltoz, akkor megnzzk, hogy egy text file-ban megvan-e // a megfelel usernv jesz pros. Beolvassuk a file-t a $file_tartalom nev // vltozba $filename = "/wwwroot/ceg/file.txt"; $fp = fopen($filename, "r"); $file_tartalom = fread($fp, filesize($filename)); fclose($fp);

134

// A text file sorait egy $sor nev tmbbe visszk be. //A sorok vgt a \n karakter jelzi. $sor = explode("\n", $file_tartalom); // // // // Vgignzzk a $sor tombot, hogy a megfelel rtket megtalljuk-e benne A sor minden elemt kt rszre bontjuk, usernv s jelsz prra. Az elvlaszt jel a : A kvetkezben a keress programozsi ttelt alkalmazzuk.

$i = 0; $adatok = explode(":", $sor[$i]); while($i<=sizeof($sor))&& !(($adatok[0]=="$PHP_AUTH_USER") &&($adatok[1]== "$PHP_AUTH_PW")) { $data_pair = explode(":", $sor[$i]); i++; } if ($i<=sizeof($sor)) $auth = 1; else $auth = 0;

if ($auth == "1") { echo "<P>Isten hozott!</p>"; exit; } else { header('WWW-Authenticate: Basic realm="Magnterlet!"'); header('HTTP/1.0 401 Unauthorized'); echo 'Authorization Required.'; exit; } ?>

A fenti rutinokat kiss mdostva berhatjuk ket egy include file-ba. Ha minden php oldalon beszrjuk a file-t, akkor automatikusan az oldal bekrsekor lefut s ellenrzi a jogosultsgot. Mindenesetre ekkor biztostani kell, hogy tlpve a kvetkez oldalra a $PHP_AUTH_USER s $PHP_AUTH_PWD vltozk tartalma megmaradjon s elrhet legyen.

135

Egy harmadik s taln elg jl hasznlhat megolds. Alapja, hogy egy scriptet minden vdett oldal elejre beszrunk, ami az oldal hvsakor lefut s SESSION vltozban troljuk a belptets eredmnyt, illetve a belptetett user-t.
$name =""; $pwd =""; Session_start(); if(!isset($_SESSION["logged_in"])) $_SESSION["logged_in"] = False; If (!$_SESSION["logged_in"]){ if( isset($_POST["name"]) && isset($_POST["pwd"])){ //Ha ksbb login formot hasznlunk POST-tal $name = $_POST["name"]; $pwd = $_POST["pwd"]; //Ha a Bngsz authhentikcis ablakt hasznljuk // if (isset($PHP_AUTH_USER) && isset ($PHP_AUTH_PW)){ // $name = $PHP_AUTH_USER; // $pwd = $PHP_AUTH_PW; // //A jelsz s usernv ellenrzse adatbzisbl mysql_connect("hostname", "username", "password") or die ("Unable to connect to database."); // Megnyitjuk a jelszadatbzist mysql_select_db("Userlista") or die ("Unable to select database."); // Elkldjk a lekrdezst a users tblra $sql = "SELECT * FROM users WHERE username='$name' and password='$pwd'"; // Vgrehajtjuk, majd az eredmny a $result vltozba kerl $result = mysql_query($sql); // Ha az eredmnynek 0 sora van, akkor nincs ilyen user s jelsz pros, // ha 1, akkor van $num = mysql_numrows($result); if($num>0){ //Ide kell betenni a jelszellenrzst $_SESSION["logged_in"] = True; //vagy sima text vagy mysql lekrdezs stb... } } } If (!($_SESSION["logged_in"])){ //Vagy egy login formot hasznlunk, ekkor POST-tal kldjk el a megfelel rtkeket include ("login.html"); // vagy szimulljuk a WEBbngsz belptet oldalt. //header('WWW-Authenticate: Basic realm="Belptets!"'); //header('HTTP/1.0 401 Unauthorized'); exit; }

24.1 Titkostott tvitele a kliens s a szerver kztt: MD5()


A PHP-ban van egy jl hasznlhat fggvny, amellyel adatok mdostatlanst tudjuk vizsglnialapvet titkostst tudjuk elvgezni, illetve a titkostott adatokat tudjuk visszakdolni plain text-. Az adatoknak karakter formtumaknak kell lenni. A fggvny az String md5( string)

/* * md5.jvs 1.0b 27/06/96 * * Javascript implementation of the RSA Data Security, Inc. MD5

136

* Message-Digest Algorithm. * * Copyright (c) 1996 Henri Torgemane. All Rights Reserved. * * Permission to use, copy, modify, and distribute this software * and its documentation for any purposes and without * fee is hereby granted provided that this copyright notice * appears in all copies. * * Of course, this soft is provided "as is" without express or implied * warranty of any kind. * * $Id: md5.js,v 1.2 1998/11/22 14:27:42 sas Exp $ * */

function array(n) { for(i=0;i<n;i++) this[i]=0; this.length=n; } /* Some basic logical functions had to be rewritten because of a bug in * Javascript.. Just try to compute 0xffffffff >> 4 with it.. * Of course, these functions are slower than the original would be, but * at least, they work! */ function integer(n) { return n%(0xffffffff+1); } function shr(a,b) { a=integer(a); b=integer(b); if (a-0x80000000>=0) { a=a%0x80000000; a>>=b; a+=0x40000000>>(b-1); } else a>>=b; return a; } function shl1(a) { a=a%0x80000000; if (a&0x40000000==0x40000000) { a-=0x40000000; a*=2; a+=0x80000000; } else a*=2; return a; } function shl(a,b) { a=integer(a); b=integer(b); for (var i=0;i<b;i++) a=shl1(a); return a; } function and(a,b) { a=integer(a); b=integer(b); var t1=(a-0x80000000); var t2=(b-0x80000000); if (t1>=0) if (t2>=0) return ((t1&t2)+0x80000000); else return (t1&b); else if (t2>=0) return (a&t2); else

137

return (a&b); } function or(a,b) { a=integer(a); b=integer(b); var t1=(a-0x80000000); var t2=(b-0x80000000); if (t1>=0) if (t2>=0) return ((t1|t2)+0x80000000); else return ((t1|b)+0x80000000); else if (t2>=0) return ((a|t2)+0x80000000); else return (a|b); } function xor(a,b) { a=integer(a); b=integer(b); var t1=(a-0x80000000); var t2=(b-0x80000000); if (t1>=0) if (t2>=0) return (t1^t2); else return ((t1^b)+0x80000000); else if (t2>=0) return ((a^t2)+0x80000000); else return (a^b); } function not(a) { a=integer(a); return (0xffffffff-a); } /* Here begin the real algorithm */ var state = new array(4); var count = new array(2); count[0] = 0; count[1] = 0; var buffer = new array(64); var transformBuffer = new array(16); var digestBits = new array(16); var var var var var var var var var var var var var var var var S11 S12 S13 S14 S21 S22 S23 S24 S31 S32 S33 S34 S41 S42 S43 S44 = = = = = = = = = = = = = = = = 7; 12; 17; 22; 5; 9; 14; 20; 4; 11; 16; 23; 6; 10; 15; 21;

function F(x,y,z) { return or(and(x,y),and(not(x),z)); } function G(x,y,z) { return or(and(x,z),and(y,not(z)));

138

} function H(x,y,z) { return xor(xor(x,y),z); } function I(x,y,z) { return xor(y ,or(x , not(z))); } function rotateLeft(a,n) { return or(shl(a, n),(shr(a,(32 - n)))); } function FF(a,b,c,d,x,s,ac) { a = a+F(b, c, d) + x + ac; a = rotateLeft(a, s); a = a+b; return a; } function GG(a,b,c,d,x,s,ac) { a = a+G(b, c, d) +x + ac; a = rotateLeft(a, s); a = a+b; return a; } function HH(a,b,c,d,x,s,ac) { a = a+H(b, c, d) + x + ac; a = rotateLeft(a, s); a = a+b; return a; } function II(a,b,c,d,x,s,ac) { a = a+I(b, c, d) + x + ac; a = rotateLeft(a, s); a = a+b; return a; } function transform(buf,offset) { var a=0, b=0, c=0, d=0; var x = transformBuffer; a b c d = = = = state[0]; state[1]; state[2]; state[3];

for (i = 0; i < 16; i++) { x[i] = and(buf[i*4+offset],0xff); for (j = 1; j < 4; j++) { x[i]+=shl(and(buf[i*4+j+offset] ,0xff), j * 8); } } /* Round a = FF ( d = FF ( c = FF ( b = FF ( a = FF ( d = FF ( c = FF ( b = FF ( a = FF ( d = FF ( c = FF ( b = FF ( a = FF ( d = FF ( c = FF ( b = FF ( 1 */ a, b, d, a, c, d, b, c, a, b, d, a, c, d, b, c, a, b, d, a, c, d, b, c, a, b, d, a, c, d, b, c,

c, b, a, d, c, b, a, d, c, b, a, d, c, b, a, d,

d, c, b, a, d, c, b, a, d, c, b, a, d, c, b, a,

x[ 0], x[ 1], x[ 2], x[ 3], x[ 4], x[ 5], x[ 6], x[ 7], x[ 8], x[ 9], x[10], x[11], x[12], x[13], x[14], x[15],

S11, S12, S13, S14, S11, S12, S13, S14, S11, S12, S13, S14, S11, S12, S13, S14,

0xd76aa478); 0xe8c7b756); 0x242070db); 0xc1bdceee); 0xf57c0faf); 0x4787c62a); 0xa8304613); 0xfd469501); 0x698098d8); 0x8b44f7af); 0xffff5bb1); 0x895cd7be); 0x6b901122); 0xfd987193); 0xa679438e); 0x49b40821);

/* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /*

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

139

/* Round a = GG ( d = GG ( c = GG ( b = GG ( a = GG ( d = GG ( c = GG ( b = GG ( a = GG ( d = GG ( c = GG ( b = GG ( a = GG ( d = GG ( c = GG ( b = GG ( /* Round a = HH ( d = HH ( c = HH ( b = HH ( a = HH ( d = HH ( c = HH ( b = HH ( a = HH ( d = HH ( c = HH ( b = HH ( a = HH ( d = HH ( c = HH ( b = HH ( /* Round a = II ( d = II ( c = II ( b = II ( a = II ( d = II ( c = II ( b = II ( a = II ( d = II ( c = II ( b = II ( a = II ( d = II ( c = II ( b = II ( state[0] state[1] state[2] state[3] }

2 */ a, b, d, a, c, d, b, c, a, b, d, a, c, d, b, c, a, b, d, a, c, d, b, c, a, b, d, a, c, d, b, c, 3 */ a, b, d, a, c, d, b, c, a, b, d, a, c, d, b, c, a, b, d, a, c, d, b, c, a, b, d, a, c, d, b, c, 4 */ a, b, d, a, c, d, b, c, a, b, d, a, c, d, b, c, a, b, d, a, c, d, b, c, a, b, d, a, c, d, b, c, +=a; +=b; +=c; +=d;

c, b, a, d, c, b, a, d, c, b, a, d, c, b, a, d,

d, c, b, a, d, c, b, a, d, c, b, a, d, c, b, a,

x[ 1], x[ 6], x[11], x[ 0], x[ 5], x[10], x[15], x[ 4], x[ 9], x[14], x[ 3], x[ 8], x[13], x[ 2], x[ 7], x[12],

S21, S22, S23, S24, S21, S22, S23, S24, S21, S22, S23, S24, S21, S22, S23, S24,

0xf61e2562); 0xc040b340); 0x265e5a51); 0xe9b6c7aa); 0xd62f105d); 0x2441453); 0xd8a1e681); 0xe7d3fbc8); 0x21e1cde6); 0xc33707d6); 0xf4d50d87); 0x455a14ed); 0xa9e3e905); 0xfcefa3f8); 0x676f02d9); 0x8d2a4c8a);

/* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /*

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

*/ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */

c, b, a, d, c, b, a, d, c, b, a, d, c, b, a, d,

d, c, b, a, d, c, b, a, d, c, b, a, d, c, b, a,

x[ 5], x[ 8], x[11], x[14], x[ 1], x[ 4], x[ 7], x[10], x[13], x[ 0], x[ 3], x[ 6], x[ 9], x[12], x[15], x[ 2],

S31, S32, S33, S34, S31, S32, S33, S34, S31, S32, S33, S34, S31, S32, S33, S34,

0xfffa3942); 0x8771f681); 0x6d9d6122); 0xfde5380c); 0xa4beea44); 0x4bdecfa9); 0xf6bb4b60); 0xbebfbc70); 0x289b7ec6); 0xeaa127fa); 0xd4ef3085); 0x4881d05); 0xd9d4d039); 0xe6db99e5); 0x1fa27cf8); 0xc4ac5665);

/* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /*

33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48

*/ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */

c, b, a, d, c, b, a, d, c, b, a, d, c, b, a, d,

d, c, b, a, d, c, b, a, d, c, b, a, d, c, b, a,

x[ 0], x[ 7], x[14], x[ 5], x[12], x[ 3], x[10], x[ 1], x[ 8], x[15], x[ 6], x[13], x[ 4], x[11], x[ 2], x[ 9],

S41, S42, S43, S44, S41, S42, S43, S44, S41, S42, S43, S44, S41, S42, S43, S44,

0xf4292244); 0x432aff97); 0xab9423a7); 0xfc93a039); 0x655b59c3); 0x8f0ccc92); 0xffeff47d); 0x85845dd1); 0x6fa87e4f); 0xfe2ce6e0); 0xa3014314); 0x4e0811a1); 0xf7537e82); 0xbd3af235); 0x2ad7d2bb); 0xeb86d391);

/* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /*

49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64

*/ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */

function init() { count[0]=count[1] = 0; state[0] = 0x67452301; state[1] = 0xefcdab89; state[2] = 0x98badcfe; state[3] = 0x10325476; for (i = 0; i < digestBits.length; i++) digestBits[i] = 0; } function update(b) { var index,i;

140

index = and(shr(count[0],3) , 0x3f); if (count[0]<0xffffffff-7) count[0] += 8; else { count[1]++; count[0]-=0xffffffff+1; count[0]+=8; } buffer[index] = and(b,0xff); if (index >= 63) { transform(buffer, 0); } } function finish() { var bits = new array(8); var padding; var i=0, index=0, padLen=0; for (i = 0; i < 4; i++) { bits[i] = and(shr(count[0],(i * 8)), 0xff); } for (i = 0; i < 4; i++) { bits[i+4]=and(shr(count[1],(i * 8)), 0xff); } index = and(shr(count[0], 3) ,0x3f); padLen = (index < 56) ? (56 - index) : (120 - index); padding = new array(64); padding[0] = 0x80; for (i=0;i<padLen;i++) update(padding[i]); for (i=0;i<8;i++) update(bits[i]); for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { digestBits[i*4+j] = and(shr(state[i], (j * 8)) , 0xff); } } } /* End of the MD5 algorithm */ function hexa(n) { var hexa_h = "0123456789abcdef"; var hexa_c=""; var hexa_m=n; for (hexa_i=0;hexa_i<8;hexa_i++) { hexa_c=hexa_h.charAt(Math.abs(hexa_m)%16)+hexa_c; hexa_m=Math.floor(hexa_m/16); } return hexa_c; }

var ascii="01234567890123456789012345678901" + " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ"+ "[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; function MD5(entree) { var l,s,k,ka,kb,kc,kd; init(); for (k=0;k<entree.length;k++) { l=entree.charAt(k); update(ascii.lastIndexOf(l)); } finish(); ka=kb=kc=kd=0; for (i=0;i<4;i++) ka+=shl(digestBits[15-i], (i*8)); for (i=4;i<8;i++) kb+=shl(digestBits[15-i], ((i-4)*8)); for (i=8;i<12;i++) kc+=shl(digestBits[15-i], ((i-8)*8)); for (i=12;i<16;i++) kd+=shl(digestBits[15-i], ((i-12)*8)); s=hexa(kd)+hexa(kc)+hexa(kb)+hexa(ka);

141

return s; }

142

25 Biztonsg, tippek s trkkk


Egy nyilvnos szerveren fut PHP program futtatsnak a biztonsgoss ttele rendkvl fontos dolog, s kt tnyezn, a szerver belltsain s a programoz gondossgn is mlik. Bemen adatok ellenrzse s szrse A bemen adatokat kt oldalon lehet vagy kell ellenrizni. - A user oldalon a formok adatbevitelnek felprogramozsval - A szerver oldalon a mr elkldtt adatok rvnyessgnek vizsglatval Az els vltozat arra val csakis s kizrlag, hogy a felhasznl user hibit kikszbljk illetve minimalizljuk. Az adatbevitel ltalban egy ormon keresztl zajlik, teht a formon val adatbevitelt clsze ellenrizni. Erre a clra ltalban Javascript kdot hasznlhatunk, amely pldul akkor fut le, ha a Form submit gombjt megnyomjuk ekkor a Form onSubmit esemnyre indulhat el a Javascript kd, vagy minden egyes mez rtknek vltozsakor lefuttatunk egy ellenrz rutint ekkor a mez onChange esemnyre indulhat a javascript kd.

Mely mezket kell ellenrizni? Gondos programozssal csak nhnyat. A HTML Formoknl az albbi beviteli mezk vannak: - Input mez Text ellenrizni kell TEXTarea ellenrizni kell Checkbox ellenrizni lehet RadioButton clszer ellenrizni Select men a kivlasztottsgot clszer ellenrizni File mez Igazbl a file ltezst ellene ellenrizni, de nem illik. Csak annyit leet, hogy a file mezben van-e valamifle bejegyzs. A fentiek alapjn lltszik, hogy egyszer esetben csak a text s a textarea ellenrzse igazn fontos. Ott ellenrizhetjk a string hosszt, azt hogy bizonyos karakterek benne vannak-e vagy nincsenek. Mevizsglhatjuk, hogy a bevitt adat numerikus-e, s ha igen, akkor milyen tartomnyba esik. A szerver oldalon mr ellenrztt adatot kapunk, mirt kell a szerver oldalon ismtelten ellenrizni? A a kliens oldali ellenrzs sokkal gyorsabb, tovbb a userek sanda szndkait a szerver oldalon lehet csak elkapni. Itt is minden fenti dolgot ellenrizhetnk, azaz: Egy vltoz rtkt Egy vltoz formjt (milyen hossz, milyen karakterek vannak bene vagy hinyoznak). Itt kell kiszrni az esetlegesen bevitt HTML tag-eket, a s a jeleket, az esetlegesen bevitt SQL utastsneveket (SQL injection). Az adat numerikus-e, s ha igen, akkor megfelel-e az rtke. Ez azt jelenti, hogy itt mr a vltozk ltt, a formtumt, s rtkt kell csak ellenrizni. Itt kell felkszlni esetleges sanda szndk userek datbevitelre is.

File-k elrsnek a kezelse

143

A PHP.INI megfelel (biztonsgos) belltsa Biztonsgos kapcsolatok, kapcsolati mdok hasznlata

144

26 A PHP.INI file paramterezse


A PHP.INI file ltalban a PHP belltasait tartalmaz file. Itt nem sorolhajuk fel az sszes lehetsges paramtert, de nhny ltalunk fontosabbnak tartott paramtert igen. Megjegyzend, hogy a paramtereket a set_ini(vltoznv, rtk) fggvnnyel llthatjuk be futs kzben programbl, s a pillanatnyi rtkeket a get_ini(vltoznv) fggvnnyel lehet lekrni. Az ini_restore(vltoznv) a korbbi rtkeket lltja vissza, az ini_alter(vltoznv, rtk) pedig a vltoz korbbi rtkvel tr vissza, ha a mdosts sikeres volt, ha nem , akkor False rtket ad vissza.

Vltoznv

Default rtk

Hol mdosthat

define_syslog_variables highlight.bg highlight.comment highlight.default highlight.html highlight.keyword highlight.string

"0" HL_BG_COLOR HL_COMMENT_COLOR HL_DEFAULT_COLOR HL_HTML_COLOR HL_KEYWORD_COLOR HL_STRING_COLOR

PHP_INI_ALL PHP_INI_ALL PHP_INI_ALL PHP_INI_ALL PHP_INI_ALL PHP_INI_ALL PHP_INI_ALL PHP_INI_SYSTEM|PHP_INI_PERDIR PHP_INI_SYSTEM|PHP_INI_PERDIR PHP_INI_ALL PHP_INI_ALL PHP_INI_SYSTEM PHP_INI_ALL PHP_INI_ALL PHP_INI_SYSTEM PHP_INI_SYSTEM PHP_INI_ALL PHP_INI_PERDIR|PHP_INI_SYSTEM PHP_INI_ALL PHP_INI_ALL PHP_INI_ALL PHP_INI_ALL PHP_INI_PERDIR|PHP_INI_SYSTEM

allow_call_time_pass_reference "1" asp_tags display_errors display_startup_errors enable_dl error_append_string error_prepend_string expose_php html_errors ignore_user_abort implicit_flush log_errors magic_quotes_gpc magic_quotes_runtime magic_quotes_sybase output_buffering "0" "1" "0" "1"
NULL NULL

"1" "1" "0" "0" "0" "1" "0" "0" "0"

145

Vltoznv

Default rtk
NULL

Hol mdosthat

output_handler register_argc_argv register_globals safe_mode short_open_tag sql.safe_mode track_errors y2k_compliance arg_separator auto_append_file auto_prepend_file doc_root default_charset default_mimetype error_log extension_dir gpc_order include_path max_execution_time open_basedir safe_mode_exec_dir upload_max_filesize file_uploads post_max_size upload_tmp_dir user_dir variables_order SMTP browscap

PHP_INI_PERDIR|PHP_INI_SYSTEM PHP_INI_ALL PHP_INI_PERDIR|PHP_INI_SYSTEM PHP_INI_SYSTEM PHP_INI_SYSTEM|PHP_INI_PERDIR PHP_INI_SYSTEM PHP_INI_ALL PHP_INI_ALL PHP_INI_ALL PHP_INI_ALL PHP_INI_ALL PHP_INI_SYSTEM PHP_INI_ALL

"1" "1" "0" "1" "0" "0" "0" "&"


NULL NULL NULL

SAPI_DEFAULT_CHARSET

SAPI_DEFAULT_MIMETYPE PHP_INI_ALL
NULL

PHP_INI_ALL PHP_INI_SYSTEM PHP_INI_ALL PHP_INI_ALL PHP_INI_ALL PHP_INI_SYSTEM PHP_INI_SYSTEM PHP_INI_ALL PHP_INI_ALL PHP_INI_SYSTEM PHP_INI_SYSTEM PHP_INI_SYSTEM PHP_INI_ALL PHP_INI_ALL PHP_INI_SYSTEM 146

PHP_EXTENSION_DIR "GPC" PHP_INCLUDE_PATH "30"


NULL

"1" "2M" "1" "8M"


NULL NULL NULL

"localhost"
NULL

Vltoznv

Default rtk
NULL

Hol mdosthat

error_reporting memory_limit precision sendmail_from sendmail_path disable_functions allow_url_fopen

PHP_INI_ALL PHP_INI_ALL PHP_INI_ALL PHP_INI_ALL

"8M" "14"
NULL

DEFAULT_SENDMAIL_PATH PHP_INI_SYSTEM "" "1" PHP_INI_SYSTEM PHP_INI_ALL

147

Sablonok Template-ek, LIB-ek


Template vagy ms elregyrtott library-t akkor hasznlunk, ha 1. Gyorstani akarjuk a PHP alkalmazs futtatst 2. Gyorstani akarjuk a programfejlesztst 3. El akarjuk vlasztani a fejleszts design s a logikai rszt 4. Nem akarjuk feltallni a spanyolviaszt, azaz a ms ltal jl megrt kdot hasznlni akarjuk.

26.1 Template-ek, Smarty


A template rendszerek olyan PHP-ban vagy egyb mdon kifejlesztett alkalmazsok, amelyek segtsgvel el tudjuk vlasztani egymstl az zleti logika s a design elemeket. Ezek a gyakorlatban azt jelentik, hogy a design elemek egy HTML-hez hasonl kdolsi rendszerben jnnek ltre, z adatbzis, s egyb prorgramozsi rszek a kifejleszett PHP kd alapjn, s a futs kzben amTemplate rendszer sszeszerkeszti a design template-eket s a PHPkdot, majd az gy ltrejtt kdot futtatja. Felvetdik a krds, hogy mennyire lasstja le az alkalmazst az gy kifejlesztett kd? A tapasztalatok azt mutatjk, hogy egyes template rendszerek hasznlata esetn a kd futsi sebessge n, mivel nem a PHP-nak kell ellltania a teljes HTML tartalmat, hanem azt HTML kdban tartjuk. A PHP programoznak s a Designernek knny elvlasztania a munkjt, hiszen a programoz s a designer egy jl definilt felhasznli interface-en keresztl kapcsoldik egymshoz. A programnak az a feladata, hogy az ltala ellltott PHP kd eredmnyt helyezze el egy tipikusan string tpus vltozba, amit aztn a sablon feldolgoz modulja beszerkeszt a Sablon tartalmba s elkldi a WEB szerveren keresztl a kliensnek. Tekintettel arra, hogy a Web oldalak jelents rsze mg akkor is statikusnak tekinthet, ha PHP-val lltkjuk el, egyes sablon rendszerek arra is kpeske, hogy az sszeszerkesztett oldalakat cache-eljk, azaz az sszeszerkesztett oldallal szolgljanak ki bizonyos krseket. Az albbiakban a Smarty nev npszer alkalmazscsomaggal ismerkednk meg egy kicsit. A teleptse sorn a smarty.inc.php oldalt kell beszerkesztennk az oldalaink elejre, ami egyttal inicializlja a rendszert. A pldban egy program lelltja a kdot, a kimenete egy stringbe kerl, majd a smarty rendszer a tartalmat egy vltozban helyezi el. Azutn a template vltoz tartalmval egytt a smarty megjelenti az erednyt.

26.2 PEAR Csomag

148

27 PHP Cache programok


Zend Cache Turck- MMCache

149

You might also like