Programozás | PHP » Révész György - A PHP nyelv

Alapadatok

Év, oldalszám:2004, 100 oldal

Nyelv:magyar

Letöltések száma:887

Feltöltve:2009. május 31.

Méret:819 KB

Intézmény:
-

Megjegyzés:

Csatolmány:-

Letöltés PDF-ben:Kérlek jelentkezz be!



Értékelések

Nincs még értékelés. Legyél Te az első!


Tartalmi kivonat

A PHP nyelv Készítette: Révész György informatikatanári szak Témavezető: Illés Zoltán ELTE Informatikai Kar Szakmódszertani Csoport Pécs, 2004. december 22 Tartalomjegyzék 1 BEVEZETÉS . 5 1.1 1.2 1.3 1.4 1.5 2 ISMERKEDÉS A PHP-VEL . 9 2.1 2.2 3 A PHP KÓD ÍRÁSA . 11 MEGJEGYZÉSEK A PHP KÓDBAN . 13 ADATOK . 14 3.1 3.2 3.3 3.31 3.4 3.41 3.42 3.43 4 A PHP TÖRTÉNETE . 5 A PHP ELŐNYEI. 6 A PHP TELEPÍTÉSE . 7 ELŐFELTÉTELEK . 8 LEMEZMELLÉKLET . 8 VÁLTOZÓK . 14 KONSTANSOK . 14 TÍPUSOK . 14 A változó típusának vizsgálata és módosítása. 15 MŰVELETEK ADATOKKAL . 15 Kifejezések . 16 Operátorok . 16 Műveleti sorrend . 18 VEZÉRLÉSI SZERKEZETEK . 19 4.1 AZ ELÁGAZÁS . 19 4.11 Az egyágú és a kétágú elágazás . 19 4.12 A többágú elágazás . 20 4.13 A ?: operátor . 22 4.2 A CIKLUS . 22 4.21 A while ciklus . 22 4.22 A do ciklus . 23 4.23 A for ciklus . 23 4.24 A break utasítás. 24 4.25 A continue utasítás . 25 5 FÜGGVÉNYEK .

26 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 5.10 6 FÜGGVÉNYEK LÉTREHOZÁSA, AZ ÉRTÉK SZERINTI PARAMÉTERÁTADÁS. 26 ÉRTÉKEK VISSZAADÁSA . 27 CÍM SZERINTI PARAMÉTERÁTADÁS . 27 VÁLTOZÓ SZÁMÚ PARAMÉTEREK . 28 ELHAGYHATÓ PARAMÉTER . 29 HATÓKÖR . 29 STATIKUS VÁLTOZÓK . 30 MATEMATIKAI FÜGGVÉNYEK . 30 DÁTUM- ÉS IDŐFÜGGVÉNYEK . 31 SZTRINGFÜGGVÉNYEK. 32 TÖMBÖK ÉS OBJEKTUMOK. 36 6.1 TÖMBÖK . 36 6.11 Tömbök létrehozása . 36 6.12 Asszociatív tömbök . 37 6.13 Többdimenziós tömbök. 37 6.14 A tömbmutató . 38 6.15 Tömbök bejárása. 38 6.16 Műveletek tömbökkel . 40 6.17 Tömbök rendezése . 41 6.2 OBJEKTUMOK . 42 6.21 Osztályok és objektumok létrehozása . 43 2 6.22 6.23 6.24 6.25 6.26 6.27 7 ŰRLAPOK . 51 7.1 7.2 7.3 7.4 8 Adattagok (tulajdonságok) . 44 Tagfüggvények (metódusok) . 44 Konstruktor . 45 Öröklés . 46 Sokalakúság . 47 Objektumfüggvények . 49 GLOBÁLIS ÉS KÖRNYEZETI VÁLTOZÓK . 51 ŰRLAP LÉTREHOZÁSA. 52

ŰRLAPELEMEK HASZNÁLATA . 54 ŰRLAP ÉS PHP KÓD EGY OLDALON . 57 FÁJLOK ÉS KÖNYVTÁRAK. 59 8.1 KÖNYVTÁRAK . 59 8.11 Könyvtárak listázása . 59 8.12 Egyéb könyvtárfüggvények . 60 8.2 FÁJLOK . 60 8.21 Fájlok beágyazása . 60 8.22 Fájlok listázása attribútumokkal együtt . 60 8.23 Fájlok létrehozása és törlése. 61 8.24 Fájlok olvasása . 61 8.25 Fájlok írása . 62 8.26 Fájlok feltöltése . 63 9 ADATBÁZISOK: MYSQL . 65 9.1 9.2 9.3 9.4 9.5 9.6 9.7 9.8 9.9 9.10 9.11 9.12 9.13 10 KÉPEK . 76 10.1 10.2 10.3 11 KÉPEK LISTÁZÁSA . 76 KÉPEK LÉTREHOZÁSA . 77 KÉPEK VÁLTOZTATÁSA . 79 SESSION-ÖK . 82 11.1 11.2 11.3 11.4 11.5 11.6 11.7 12 MYSQL ADATTÍPUSOK . 65 KAPCSOLÓDÁS A KISZOLGÁLÓHOZ . 66 ADATBÁZISOK KIVÁLASZTÁSA, LISTÁZÁSA . 66 ADATBÁZISOK TÁBLÁINAK LISTÁZÁSA. 67 TÁBLÁK MEZŐINEK LISTÁZÁSA . 68 TÁBLÁK ADATAINAK MEGJELENÍTÉSE . 68 ADATBÁZIS LÉTREHOZÁSA ÉS TÖRLÉSE . 69 TÁBLA LÉTREHOZÁSA ÉS TÖRLÉSE . 69 ADATOK

BESZÚRÁSA . 70 ADATOK LEKÉRDEZÉSE . 70 ADATOK FRISSÍTÉSE . 71 ADATOK TÖRLÉSE . 72 PÉLDA: A HÍREK MODUL . 72 PHP-SZOLGÁLTATÁSOK . 82 SESSION-FÜGGVÉNYEK . 83 SESSION INDÍTÁSA . 84 VÁLTOZÓK REGISZTRÁLÁSA . 84 A REGISZTRÁLT VÁLTOZÓK ÉS A SESSION MEGSZŰNTETÉSE . 85 SESSION-FÜGGVÉNYEK HASZNÁLATA . 85 PÉLDA: A FÓRUM MODUL . 86 BIZTONSÁG . 94 12.1 12.2 12.3 12.4 12.5 CGI FUTTATHATÓ ÁLLOMÁNYKÉNT TELEPÍTETT PHP . 94 APACHE MODULKÉNT TELEPÍTETT PHP . 95 FÁJLRENDSZER . 96 ADATBÁZIS. 96 FELHASZNÁLÓTÓL ÉRKEZŐ ADATOK . 97 3 12.6 12.7 12.8 12.9 HIBAKEZELÉS . 98 GLOBÁLISAN ELÉRHETŐ VÁLTOZÓK . 98 A PHP ELREJTÉSE. 99 FRISSÍTÉSEK . 99 IRODALOMJEGYZÉK . 100 4 1 Bevezetés A Világháló kezdetben nem volt több egyszerű adatnál, a HTML (HyperText Markup Language) első változata még azt sem tette lehetővé, hogy képeket helyezzünk el weboldalunkon. Mára azonban hatalmas változásokon ment keresztül, rengeteg szolgáltatást

tartalmaz: képeket, hangokat, mozgóképeket, és mindezek mellett szórakoztat, tanít és kapcsolatot tart. A Web fejlődésével párhuzamosan fejlődtek az eszközök is, az egyszerű leírónyelvhez valódi programozási nyelvek csatlakoztak. A statikus weboldalak igen fontos szerepet töltöttek be a WWW szolgáltatásaiban az Internet hőskorában. Ma azonban nagyon sok olyan feladat létezik, melyeket nem lehet, vagy nem célszerű statikus oldallal megoldani. A cégek adataikat többnyire adatbázisokban tárolják. Ezekből az adatbázisokból le lehet ugyan képezni az adatokat különböző eljárásokkal statikus oldalakra, azonban ez több olyan problémát is felvet, mely az információ közzétételének ezen módját kizárja a lehetséges megoldások közül. Vannak olyan feladatok, melyek ugyancsak szükségessé teszik a szerver-oldali programfuttatást, ilyen lehet például egy egyszerű letöltés-számláló az adott oldalon, de lehet például egy Internetes

portál friss hírek rovata, mely igen gyakran frissül. A dinamikus weboldal egyik változata, mely kliens-oldali programok (client-side scripts) segítségével kommunikál a felhasználóval. Ma a feladatok igen széles skáláját tudjuk a kliens oldalon elvégezni, kezdve a legegyszerűbb kérdőív adatainak ellenőrzésétől, a külön csatornán lebonyolított titkosított banki tranzakció kezelésig. A legelterjedtebb kliens-oldali szkript nyelvek a JavaScript és a VBScript. A kliens oldali programozásnak azonban van néhány hátulütője: a lassúság és a böngészőfüggőség. A felhasználók gyors, könnyen átlátható, könnyen kezelhető, stabilan működő oldalakat szeretnek használni. Néhány éve a hangsúly ezért ismét a szerver-oldali megoldásokra terelődött. A CGI (Common Gateway Interface) szabvány lehetővé teszi más programok futtatását és a kimenetek szövegbe, hangba vagy videóba összegezve a kliensre juttatását. Szabványos

felületet biztosítva a CGI lehetővé teszi a programozók számára programozási nyelvek széles spektrumának használatát. CGI programok dolgozhatják fel a kliens által kitöltött űrlapokat, számlálhatják az oldalt látogató felhasználókat, adatokat kezelhetnek adatbázisokban és több száz egyéb feladatot oldhatnak meg. A szerver-oldali programozáshoz sorolható: a Perl (Practical Extraction and Report Language), a Python, a PHP, az ASP (Active Server Pages), a JSP (Java Server Pages). 1.1 A PHP története A PHP első változatát - mely egy makrókészlet volt - Rasmus Lerdorf készítette 1994-ben. Ezeket a segítő eszközöket együttesen a Personal Home Page Tools névvel illette. Később egy friss elem került a csomagba, a Form Interpreter (Űrlapfeldolgozó), így PHP/FI néven vált ismertebbé. A felhasználók szemszögéből a PHP/FI nagyon hasznos segédeszköz volt, több fejlesztő is felfigyelt rá, így 1997-re már számos programozó

dolgozott rajta. Az így elkészült PHP3-as már egy csapat együttműködéséből született A PHP3-as azonban még elég lassú volt ahhoz, hogy mentségül szolgáljon a Perl-höz értő programozóknak, miért nem váltottak. Az 1990-es évek végén a Web-szerver nyelvek nagy fejlődésen mentek át. A Perl-t és az első PHP-t – mivel HTML oldalak voltak – soronként értelmezték. A fejlesztők később olyan rendszereket választottak, amelyek memóriába fordítottak. A nyílt forráskódú fejlesztéseknek köszönhetően megjelent PHP4 és a PHP3 közötti óriási teljesítménykülönbség az értelmezésről a fordításra való áttérésnek köszönhető. A PHP4 egy olyan nyílt forráskódú nyelv az új webfejlesztők számára, amely folyamatosan váltja fel a Perl-höz hasonló régebbi nyelveket. 5 Ma a PHP - hivatalosan a PHP: Hypertext Preprocessor elnevezést használja - egy széles körben használt, nyílt forráskódú, általános célú

programozási nyelv, különösen jó webfejlesztés támogatással és HTML-be ágyazási képességekkel. A szintakszisa a C, Java és Perl nyelvekre épül, könnyen megtanulható. A nyelv fő célja lehetőséget teremteni dinamikusan generált weboldalak gyors készítésére, de a PHP ennél sokkal többre is képes. A PHP főleg szerver-oldali szkriptek írására készült, azaz bármire képes, amire más CGI programok, ilyen funkciók például az űrlap adatok feldolgozása, dinamikus tartalom generálása, vagy sütik küldése és fogadása. 1.2 A PHP előnyei „Egyértelmű, hogy a PHP az egyetlen igazi nyelv, de vannak akiket csak a tények győznek meg, a tények pedig azt mutatják, hogy napjaink weboldalaihoz a PHP a megfelelő szkript nyelv. Tapasztalataim alapján állítom, hogy a PHP-t könnyebb tanítani, mint az olyan keveréknyelveket, mint a Visual Basic vagy az IIS.” (MOULDING, 2002, 5. old) Fejlesztési sebesség Mivel a PHP lehetőséget ad a HTML

elemek és a programkódok elkülönítésére, az alkalmazások fejlesztésekor lehetőség van elválasztani a kódolási, tervezési, és összeállítási szakaszt. Ez jelentősen megkönnyíti a programozók életét azzal, hogy elmozdítja az akadályokat a hatékony és rugalmas alkalmazások kialakításának útjából. Nyílt forráskód A PHP mint nyílt forráskódú termék jó támogatással rendelkezik, ráadásul a PHP az elterjedtebb operációs rendszerek bármelyikén képes futni, a legtöbb kiszolgálóprogrammal együttműködve. Felvehetjük a kapcsolatot a könnyen elérhető és elkötelezett felhasználói közösséggel, ahol számos nagy tapasztalattal rendelkező embert találunk. Nagy az esély rá, hogy bármilyen problémával is kerüljünk szembe, kis keresgélés után választ kapunk rá, ha mégsem, egy levelezőlistára küldött üzenetre általában hamar érkezik a megfelelő válasz. A feldolgozóprogram hibáinak javítása nem sokkal

felfedezésük után megtörténik, és a felmerült új igényeket kielégítő szolgáltatások is hamar beépülnek a nyelvbe. Nem kell várni a következő hivatalos kiadásra, hogy a fejlesztések előnyeit élvezzük. Nincs a PHP működtetéséhez egyedileg kiválasztott kiszolgáló vagy operációs rendszer. Szabadon választhatunk olyan rendszert, amely kielégíti saját vagy ügyfeleink igényeit, kódunk továbbra is futtatható lesz, bármi mellett is döntünk. Teljesítmény A hatékony Zend Engine-nek (a Zend Engine a PHP modulok mögött található, a programokat futtató mag elnevezése) köszönhetően a PHP4-es a mérések szerint messze maga mögött hagyja legtöbb versenytársát. Hordozhatóság A PHP-t alapvetően úgy tervezték, hogy alkalmas legyen számos operációs rendszeren való használatra, együttműködve különböző kiszolgálókkal és adatbázis-kezelőkkel. Fejleszthetünk UNIX rendszerre és áttérhetünk NT alapokra minden probléma

nélkül. A PHP alkalmazásokat kipróbálhatjuk Personal Web Serverrel, és később telepíthetjük azokat egy UNIX rendszerre, ahol a PHP-t Apache modulként használjuk. 6 1.3 A PHP telepítése A PHP nem működik 16 bites környezetben, mint például a Windows 3.1, és a PHPhez Web-szerver szükséges Ha nincs Web-szerver telepítve számítógépünkön, akkor először el kell döntenünk, hogy milyen szervert fogunk telepíteni, vagy van egy egyszerű lehetőség: az AppServ telepítése, amely a PHP mellett minden szükséges programot tartalmaz. Ez az ingyenes programcsomag Windows és UNIX rendszereken is telepíthető, letölthető a http://www.appservnetworkcom címről Jelenlegi verziószáma a 2.51, és a következő modulokat tartalmazza: − − − − − − Apache Web Server 1.331 PHP Script Language 5.01 MySQL Database 4.020 Zend Optimizer 2.53 phpMyAdmin Database Manager 2.60-rc1 Perl 5.84 Gyakorlatilag minden szükséges modult tartalmaz, az Apache-ról

pedig sokan úgy vélekednek, hogy a legjobb Web-szerver. Ha mégsem az AppServ mellett döntenénk, akkor érdemes az alábbi Web-szerverek közül választani: − − − − − − − Personal Web Server (friss verzió javasolt) Apache 1.3x Internet Information Server 5 Omni HTTPd 2.0b1 vagy újabb Oreilly Website Pro Xitami Netscape Enterprise Server, iPlanet Először a választott szervert kell telepíteni, és ellenőrizni, hogy jól működik-e. Számos adatbázis - Adabas D, InterBase, Solid, dBASE, mSQL, Sybase, Empress, Microsoft SQL, MySQL, Velocis, FilePro, Oracle, UNIX dbm, Informix és PostgreSQL közvetlenül csatlakoztatható a PHP-hez (mi a MySQL-lel fogunk dolgozni). A MySQL adatbázisrendszer a http://www.mysqlcom címről tölthető le Számos operációs rendszerre elérhető, beleértve a UNIX, Windows és OS/2 rendszereket. A MySQL magyar tükörkiszolgálója a http://mysql.sotehu A PHP telepítőprogram ingyenesen letölthető a http://www.phpnet címről

Magyarországon a http://hu.phpnet tükörkiszolgálót érdemes látogatni A PHP webhelye kiváló információforrás PHP programozóknak. A http://wwwphpnet/manual címen a teljes kézikönyv elolvasható, kiegészítve más programozók által írt hasznos megjegyzésekkel. Ezen a címen olvasható a magyar PHP kézikönyv is A PHP honlapról a dokumentáció is letölthető különböző formátumokban. A Zend Engine és más Zend termékek honlapja a http://www.zendcom Itt híreket, illetve cikkeket olvashatunk a PHP és a Zend világából. Az InstallShield telepítőprogrammal nagyon könnyű életre kelteni a PHP-t, de ez nagyon sok szempontból korlátozott változat, például a kiterjesztések automatikus telepítését nem végzi el. Telepítő futtatása után kétféle telepítés közül lehet választani - a standard 7 telepítés jól használható alapbeállításokat ad, az advanced kérdéseket tesz fel. A telepítés varázslója elég információt gyűjt

ahhoz, hogy elvégezhesse a php.ini fájl beállítását, és konfigurálja a szervert a PHP számára. IIS esetén, vagy NT Workstation alatt PWS használatakor az összes ponton fellelhető script map beállítást megmutatja, és kiválasztható, hogy mely pontokra kerüljön be a PHP támogatás. Lehetőség van a PHP-t az eredeti forrásból fordítani Windows rendszerben is, ha van Microsoft Visual Studio telepítve a számítógépen. Ha bárhol elakadnánk a telepítésben, vagy további információkra lenne szükségünk, akkor látogassunk el a következő címre: http://php.benscomcom 1.4 Előfeltételek Ez a munka az alapoktól indulva próbálja bemutatni a PHP4-es programozási nyelv azon elemeit, melyek nélkülözhetetlenek egy dinamikus weblap készítésekor. A megértéshez szükséges programozási ismeretek az alapfogalmakon nem mutatnak túl, de ha a C vagy a Perl nyelvekkel már dolgoztunk korábban, egyes fejezeteknél könnyebben, gyorsabban haladhatunk. A

kilencedik fejezet a PHP és a MySQL kapcsolatával foglalkozik, ám az adatbáziskezelés alapjait nem tartalmazza, így annak megértése előismeretek nélkül nehézkes. A PHP webes programozási nyelv, ezért alapvető ismerettel rendelkezni kell a Világhálóval és a HTML-lel kapcsolatban is. 1.5 Lemezmelléklet Ehhez a munkához tartozik egy lemezmelléklet, melyen megtalálható az összes bemutatott PHP-program fejezetenként külön könyvtárakban. A CD-n továbbá megtalálható a PHP, az Apache, a MySQL, és az AppServ jelenleg legfrissebb változata, valamint a teljes PHP dokumentáció különböző formátumokban. 8 2 Ismerkedés a PHP-vel A PHP egy szerver-oldali szkript nyelv. A válaszlap formátumát leíró utasítások egy HTML dokumentumba ágyazva helyezkednek el. A Web-szerver a meghívott dokumentum URL-jéből ismeri fel, hogy a kérést a PHP szervernek kell feldolgoznia. A minta dokumentum HTML utasításai változtatás nélkül átkerülnek a

válaszlapra, a PHP specifikus elemeket a PHP végrehajtja, és a generált válasz kerül be az eredménylapra. Ugyan a PHP leíró nyelve nem adatbázis orientált, hanem a C általános programozási nyelvre épül, mégis tartalmaz adatbázis kapcsolódási kiegészítő modult, amely lehetővé teszi, hogy elérhessük, és a válaszlapon megjeleníthessük a legkülönbözőbb adatbázisokban tárolt adatokat is. A PHP rendszer működési struktúrája az alábbi elemekből épül fel: − Web-szerver − PHP-szerver − Minta dokumentum Browser URL Web-szerver PHP-szerver Adatbázisszerver A fenti struktúra alapján a PHP kérések feldolgozása az alábbi lépésekben fut le: 1. Az olvasott lapon kiadnak egy hiperlink kapcsolódást egy olyan URL-re, mely mögött PHP hívás rejlik. Egy ilyen cím lehet például a következő: http://babits.ptehu/php/indexphp illetve a hivatkozást más esetekben a http://babits.ptehu/indexphp formában is megadhatjuk. A

hivatkozásokban az URL első része jelöli ki, hogy mely gépen található a Webszerver és a PHP szerver. Az első mintában a /php/ rész egy virtuális könyvtár, mely jelzi a Web-szervernek, hogy itt egy PHP dokumentumot kell kezelni, és meg kell majd hívni a PHP szervert. A virtuális útvonal kijelölésének menete Webszerver specifikus, rendszerint a Web-szerver konfigurációs állományát kell módosítani a virtuális útvonal kijelöléshez. A második mintában a nem kellett virtuális könyvtár ahhoz, hogy a Web-szerver tudja, hogy a PHP szervert kel meghívnia. Ebben az esetben ugyanis a dokumentum kiterjesztése utal arra, hogy a dokumentumot a PHP fogja kezelni. A kiterjesztések és a kezelő programok összerendelése is a Web-szerver konfigurációs állományában történik. Az URL utolsó tagja, példánkban az index.php rész a séma dokumentumot jelöli ki, mely megadja a válaszlap előállításának módját. 9 2. A Web-szerver érzékeli, hogy a

meghívott URL a PHP szerverhez kapcsolódik, ezért meghívja a PHP modult végrehajtásra. A PHP szerver kétféle módban is működhet: CGI és API módban. Az első lehetőség esetén minden oldal lekérésekor és feldolgozásakor egy új példány fut le a PHP feldolgozóból. Mivel a szkript futtatása után egy ilyen példány leáll, minden erőforrás, amit lefoglalt, megszűnik. A népszerűbb a második forma, amikor a PHP-t modulként futtatjuk egy több process-es Web-szerveren. Egy több process-es Web-szerver tipikusan rendelkezik egy szülő process-el, ami koordinálja a többi kapcsolódó process (a gyermekek) munkáját, amik valójában a weboldalak kiszolgálását végzik. Ha egy kérés érkezik egy klienstől, egy éppen szabad gyermekprocess kapja meg a kiszolgálásra az utasítást. 3. A PHP modul megkapja a végrehajtási feladatot a feldolgozandó séma dokumentum azonosítójával együtt, átolvassa és elemzi a séma dokumentumot. A PHP specifikus

utasításokat értelmezi és végrehajtja. 4. Ha adatbázis hozzáférési igények is felmerültek a PHP specifikus utasítások között, akkor a PHP szerver kapcsolatba lép az adatbázis-kezelővel, s végrehajtja a kijelölt műveletsort. A PHP specifikus utasítások között megtalálhatok azon elemek is melyekkel leírható, hogyan jelenjenek meg az eredményadatok a válaszdokumentumban. 5. A generált válaszlap a HTML utasítások és a dinamikus elemekből felépülve, átkerül a Web-szerverre, majd onnan eljut az őt igénylő böngészőhöz. A PHP szerver is egy többrétegű, több komponensből álló rendszer. A rendszer elvi felépítési vázát mutatja be a következő ábra: Web-szerver PHP szerver SAPI PHP Core Zend Core Extension API Extension (pl. MySQL) Séma leírás 10 Az SAPI (Szerver Absztrakciós Réteg) a különböző Web-szerverekhez történő kapcsolódást oldja meg egy egységes felületet képezve a felette elhelyezkedő rétegek

számára. Jelenleg támogatott felületek: Apache, Roxen, Java (servlet), ISAPI, AOLserver és CGI. A Zend Core modul nyelvi parser szerepet tölt be a rendszerben Az egyes kiterjesztések (extension) teszik lehetővé a különböző adatbázis források elérését. 2.1 A PHP kód írása A PHP specifikus utasítások a HTML utasítások közé beillesztve, beágyazva foglalnak helyet. A HTML utasításoktól való egyértelmű és könnyen kezelhető szétválasztás érdekében az egyes PHP specifikus utasításokat keretbe foglaljuk. Az elhatárolás az alábbi változatok valamelyikével lehetséges: <?php PHP elemek ?> <script language="php"> PHP elemek </script> <? PHP elemek ?> <% PHP elemek %> - hagyományos - szkript stílusú - rövid - ASP stílusú A fenti kezdő- ill. záróelemek közül az utolsó kettő használatát a phpini fájlban engedélyezni kell a short open tag=on ill. a asp tags=on beállításokkal Éppen emiatt

célszerű az elsőt vagy a másodikat használni. A PHP elemek a C nyelvi kifejezésekhez hasonló formátumot öltenek. Egy tagolt rész több elemi PHP kifejezést, utasítást is tartalmazhat. Ekkor az egyes PHP utasításokat pontosvesszővel határoljuk el egymástól: <?php ?> PHP utasítás1; PHP utasítás2; A fenti példából is látható, hogy a tagolási rész és a PHP elemi utasítás is több forrássoron keresztül is folytatódhat, a sorvégjel nem jelent utasítás határt. Mivel a HTML fájlok egyszerű szöveges fájlok, bármilyen szövegszerkesztő segítségével írhatjuk a PHP kódokat is. A HTML-szerkesztők általában viszont nyújtanak valamilyen különleges támogatást PHP-szerkesztéshez is, ilyenek például a kódszínezés, a kifejezésszerkesztő vagy a tesztelő. Nézzünk is rögtön egy PHP kódot! 01: <?php 02: print("Hello, World!"); 03: ?> Az évek során hagyománnyá vált, hogy a programozási nyelvek

megismerését e program bemutatásával kezdik. A sorok elején található számozás és a kettőspont nem a kód része, ezek csak a kódhoz tartozó magyarázatok megkönnyítése miatt kerültek oda. Ez a kód nem tartalmaz HTML tag-eket, mégis működőképes. Gépeljük be a kódot és mentsük el a fájlt hello.php néven! Most már csak annyi dolgunk van, hogy a szerveren elhelyezzük a fájlt. Ha otthoni számítógépünkön dolgozunk, akkor meg kell keresni azt a könyvtárat, ami a localhost-hoz tartozik, és oda be kell másolni (az AppServ esetében ez 11 a www nevű könyvtár), egyébként pedig FTP segítségével fel kell töltenünk egy másik számítógépre. Ha minden rendben ment, akkor elérhetjük fájlunkat egy böngésző segítségével, és a következő eredményt kapjuk: Ha a PHP-t nem sikerült telepíteni a kiszolgálóra vagy nem a megfelelő kiterjesztést használtuk, feltehetően nem az előző ábrán látható kimenetet kapjuk. Ebben az

esetben általában a PHP program forráskódját látjuk viszont. Elemezzük ki a kódot! Az első és a harmadik sorban található nyitó- ill. záróelemeken kívül egyetlen egy új dolgot találunk. A print() parancs kiírja a böngészőbe a neki átadott adatokat. Az adat jelen esetben egy szöveg (a szöveget vagy más néven a karakterláncot mindig egyes vagy kettős idézőjelek közé kell tenni), mely az utasítás végrehajtásakor a böngészőbe „kiíródik”. A print() igazság szerint egy függvény A függvények olyan parancsok, amelyek valamilyen műveletet végeznek általában a nekik átadott adatokkal. A függvényeknek átadott adatokat majdnem mindig zárójelek közé kell tennünk a függvény neve után. Ebből a szempontból a print() kivételes, mert a zárójelpárja elhagyható. A print() helyett használható az echo() függvény is, melyek segítségével a HTML tag-eket is kiírathatjuk, például a print("<br>"); egyenértékű

a <br> tag HTML kódbeli elhelyezésével. Függvényekről részletesen az ötödik fejezetben lesz szó Készítsük el az előbbi kód HTML tag-eket tartalmazó változatát! 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: <html> <head> <title>Hello</title> </head> <body> <?php print("Hello, World!"); ?> </body> </html> Egy dokumentumban a HTML elemek közé tetszőleges számú PHP kódblokk írható, és ezek együttesen alkotnak egy programot. Bármi, amit egy megelőző blokkban határoztunk meg (változók, függvények vagy osztályok), a dokumentumon belül elérhető lesz a későbbi blokkokban is. PHP blokk nem csak a <body> és </body> tag-ek között helyezhető el (bár ebben a munkában mindig a dokumentum törzsrészében lesz a kód), hanem használhatjuk a PHP-t például dinamikus oldalcím generálására is, ha a <title> és </title> tag-ek közé helyezzük el a kódot. A

következőkben a HTML tag-eket csak a fontos helyeken hagyjuk meg a kód rövidíthetősége érdekében. 12 2.2 Megjegyzések a PHP kódban A PHP utasítások közé elhelyezhető megjegyzéseknek is többféle szintaktikája van: − // szoveg : ekkor a megjegyzés kezdetétől az aktuális sor végéig terjedő rész lesz a megjegyzés rész, a közrefogott szöveg nem kerül értelmezésre a PHP szerver által. − # szoveg : ugyanolyan értelmezésű, mint az előző formátum. − /* szoveg / : ekkor több sorra is kiterjedhet a megjegyzés rész. A későbbiekben rendszeresen megjegyzések találhatók majd a példaprogramokban magyarázat céljából. 13 3 Adatok Az adat a program alapvető alkotóeleme. A PHP-ben az adatokat definiálhatjuk szövegként (karakterlánc vagy sztring), egészként, lebegőpontos számként, logikai értékként, és a típusok összetett keverékeként. 3.1 Változók $a="alma"; A $a egy változó, mely az alma szöveget

tartalmazza, értékét bármikor megváltoztathatjuk. A konstansok értékét és a változók értelmezési tartományát viszont nem lehet megváltoztatni. A változókra a következő feltételek teljesülnek: - A változók azonosítója mindig a $ (dollár) jellel kezdődik, az azonosító pedig betűket, számokat, és az jelet tartalmazhatja, kikötve, hogy számmal nem kezdődhet. A felvett érték szabja meg a változó típusát. A változók meghatározott típusúak lehetnek, például egész vagy sztring, a PHP azonban szükség esetén átkonvertálja a változót más típusúvá. $s="0"; A $s, amely a 0 (nulla) szöveget (karaktert) tartalmazza, automatikusan átkonvertálható üressé vagy hamissá. A változók nagysága/hosszúsága korlátozott, de a sztringek majdnem korlátlan hosszúak lehetnek (csak a memória korlátoz). A hiányzó változókat a PHP automatikusan létrehozza: $szam=4; print($szma); Az elgépelésnek nem hibaüzenet az

eredménye. A PHP ugyanis létrehozza a $szma változót, a print() függvény pedig egy üres vagy tartalom nélküli változót kap, aminek hatására a böngészőben nem jelenik meg semmi. Az isset() függvény ellenőrzi, hogy a változó létezik -e, és logikai értéket szolgáltat vissza, míg az unset() függvény eltávolítja a változót. A későbbi fejezetekben láthatunk majd példát e két függvény használatára 3.2 Konstansok define("a","alma"); A define parancs az első paraméterként megadott névvel létrehozza a konstanst, és a második paraméterként megadott értéket rendeli hozzá. A define parancs bárhol használható, a definiált konstansok pedig globális hatókörűek, azaz mindenhol, így a függvények belsejében is elérhetők. 3.3 Típusok Az előbbiekben már eset szó arról, hogy milyen típusok léteznek a PHP-ben. Most ezek részletesebb leírása következik: 14 Típus Leírás Példa integer double string

egész szám lebegőpontos szám (valós szám) szöveg vagy karakterlánc logikai (értéke igaz/true vagy hamis/false) tömb objektum 12 9.967 "Hello" boolean array object true hatodik fejezet hatodik fejezet 3.31 A változó típusának vizsgálata és módosítása A változó típusának meghatározására a PHP gettype() függvényét használhatjuk. Ha a függvényhívás zárójelei közé változót teszünk, a gettype() egy karakterlánccal tér vissza, amely a változó típusát adja meg. A változó típusának módosítására a PHP a settype() függvényt biztosítja. A settype()-ot úgy kell használnunk, hogy a megváltoztatandó típusú változót, valamint a változó új típusát a zárójelek közé kell tennünk, vesszővel elválasztva. 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: <?php $proba=3.14; print "A(z) $proba típusa: "; print gettype($proba); //kiírja, hogy double print "<br>";

settype($proba,"string"); //karakterlánccá alakítja print "A(z) $proba típusa: "; print gettype($proba); //kiírja, hogy string print "<br>"; settype($proba,"integer"); //egésszé alakítja print "A(z) $proba típusa: "; //kiírja, hogy A(z) 3 típusa: print gettype($proba); //kiírja, hogy integer print "<br>"; settype($proba,"boolean"); //logikai típusúvá alakítja print "A(z) $proba típusa: "; //kiírja, hogy A(z) 1 típusa: print gettype($proba); //kiírja, hogy boolean ?> Azok, akik már használták a C programozási nyelvet, nyugodtan alkalmazhatják e nyelvben megismert típusátalakítást: $proba=(string)$proba; Ez a sor egyenértékű a settype($proba,"string"); sorral. Függvények formájában léteznek olyan típuslekérdező parancsok, melyek paraméterként megadva a változó nevét, logikai értékkel térnek vissza, ilyenek például: is array(), is

bool(), is double(), is numeric(), is string(), is object(). 3.4 Műveletek adatokkal A PHP rengeteg kifejezést, operátort, függvényt, osztályt kínál, továbbá többféle lehetőséget nyújt az adatok kezelésére mind az adatbázisok, mind pedig a HTML felé. 15 3.41 Kifejezések A PHP-ben minden kifejezés. A $kor=29; utasítás három kifejezést tartalmaz Egyszer a $kor változót, a 29-et, és magát az egész utasítást. A kifejezés a függvények, értékek és operátorok (műveletjelek) olyan együttese, amely értéket határoz meg. Általánosságban azt mondhatjuk, hogy ha értékként használhatunk valamit, akkor az kifejezés. 3.42 Operátorok „Az operátor (műveletjel) jel vagy jelsorozat, amelyet ha értékek összekapcsolására használunk, valamilyen műveletet végezhetünk, amely általában új értéket eredményez. Az operandus egy érték, amelyet a műveletjellel kapcsolatban használunk. Egy műveletjelhez általában két operandus

tartozik.” (ZANDSTRA, 2000, 47 old) Hozzárendelő operátor: = A $kor=29; utasítás a baloldali változóhoz a jobb oldal értékét rendeli. Egy utasításban több hozzárendelő operátort is használhatunk: $szam=$kor=29; Összehasonlító operátorok: == != === !== < > <= >= Az összehasonlító operátorok két értéket hasonlítanak össze, és hibákhoz vezethetnek a PHP automatikus típuskonverziója miatt. A hamis logikai érték és a 0 megkülönböztetésére alkalmasak a === vagy a !== operátorok, ugyanis a == ezen értékeknél nem a várt eredményt adja. Operátor Jelentés Igaz Hamis == != === egyenlő érték nem egyenlő érték egyenlő érték és egyező típus nem egyenlő érték vagy nem egyező típus kisebb nagyobb kisebb vagy egyenlő nagyobb vagy egyenlő 4==4 3!=4 0===0 3==4 4!=4 0===false 0!==false 0!==0 3<4 5>4 4<=4 9>=3 6<4 5>7 5<=4 6>=8 !=== < > <= >= Aritmetikai operátorok: + - * / %

A + összeadáshoz, a - kivonáshoz, a * szorzáshoz, a / osztáshoz használható, a % pedig az osztás maradékát adja. A maradékos osztást két lebegőpontos számmal is elvégzi úgy, hogy elhagyja a tizedesjegyeket. A maradékos osztás eredménye mindig egész Az aritmetikai műveleteket az operációs rendszer a számítógép hardverével végezteti el, így ezek pontossága egyrészt a hardvertől függ, másrészt attól, hogy az operációs rendszer hogyan kezeli a hardvertől kapott eredményt. Sztringoperátorok: . = Két sztring összefűzéséhez használható a . operátor, míg egy sztring végéhez egy másikat a .= operátorral lehet csatolni $szin="piros"." ""kék"; $szin.=" lila"; //$szin="piros kék" //$szin="piros kék lila" 16 Növelő/csökkentő operátorok: ++ -A ++ és -- operátorok egyaránt írhatók változók elé és mögé. A különbség az, hogy ha például a $szam változó

értéke 7, és kiadjuk a print(++$szam); parancsot, akkor a $szam változó előbb felveszi a 8 értéket, majd ez megjelenik a böngészőben, ha pedig a print($szam++); parancsot adjuk ki, akkor előbb kiíródik a 7, és utána növelődik meg a változó tartalma eggyel. Ez teljesen hasonlóan működik a -- operátor esetében, csak a változó tartalma eggyel csökkeni fog. Egyéb hozzárendelő operátorok: += -= *= /= %= Ezek szintén az egyszerűbb leírást segítik. Például a $szam+=4 utasítás egyenértékű a $szam=$szam+4 utasítással, a $szam*=4 utasítás pedig a $szam=$szam4 utasítással. Logikai operátorok: ! && || and xor or A logikai operátorok logikai értékeken végeznek műveleteket. A következő táblázat a lehetséges logikai műveleteket mutatja be. Operátor Név || vagy or vagy xor kizáró vagy && és and és ! tagadás Igaz, ha a bal vagy a jobb operandus igaz a bal vagy a jobb operandus igaz vagy a bal, vagy a jobb

operandus igaz, de csak az egyikük a bal és a jobb operandus is igaz a bal és a jobb operandus is igaz az egyetlen operandus hamis Példa Eredmény true || false true true or false true true xor true false true && false false true and false false !true false Arra a kérdésre, hogy miért van kétféle vagy és és logikai művelet, a műveletek sorrendje adja meg a választ. Bináris operátorok: & | ^ ~ << >> A számítógépben minden binárisan van tárolva, azaz minden egy különböző hosszúságú bináris sztring. Ezek kezelésére alkalmasak a bináris operátorok Ha van egy 1-es és egy 2-es számunk, akkor a nekik megfelelő bináris alakok a 01 és az 10 (napjainkban 32 biten szoktak tárolni, így például az 1-es 31 db 0 után egy 1-es). A bitenkénti és (&) eredményében azokon a helyeken lesz 1-es, ahol mindkét operandusban 1-es volt. Így az 1-es és a 2-es bitenkénti és-e 0 A bitenkénti vagy (|) eredményében

azokon a helyeken lesz 1-es, ahol legalább az egyik operandusban 1-es volt, azaz az 1-es és 2-es esetében az eredmény a bináris 11 lesz, ami 3-at ér. A bitenkénti xor (^) eredményében azokon a helyeken lesz 1-es, ahol a két operandus közül az egyikben és csakis az egyikben 1-es volt. Az 1 ^ 2 szintén a 3-at adja A bitenkénti tagadás (~) az összes bitet invertálja, azaz ahol 1-es volt, ott 0 lesz, és fordítva. 17 Már csak két operátor maradt hátra: a jobbra tolás (>>) és a balra tolás (<<). Ezek az operátorok meghatározott értékkel eltolják a biteket a megfelelő irányba. Ha a $szam változó értéke 3, akkor a $szam>>=1; utasítás hatására a $szam értéke 1 lesz (a bináris 11-et 1-gyel jobbra tolva a bináris 01-et kapjuk). Ha pedig a $szam<<=2; utasítást nézzük, akkor a $szam a 12-vel lesz egyenlő (az 11-ből az 1100-át kapjuk). Hivatkozás operátor: & A hivatkozás operátort változónév elé kell tenni.

Ha a $szam változó értéke 4, és kiadjuk a $sz=&$szam; utasítást, akkor a $sz változó ugyanarra a memóriacímre fog mutatni, mint a $szam, szükségképpen az értéke is meg fog egyezni a $szam változó értékével, azaz 4 lesz. Ha későbbiekben bármelyik értékét változtatjuk, változik a másik is, hiszen ugyanarra a memóriacímre mutatnak. Hibaellenőrző operátor: @ A @ operátor elrejti a függvények és különböző kifejezések hibáit, ami néhány weboldalon hasznos lehet, hiszen a hibaüzenetek általában a felhasználóknak nem mondanak semmit. A hibaellenőrző operátort a függvénynév elé kell tenni 3.43 Műveleti sorrend A következő lista az operátorokat a prioritásuk alapján állítja sorba, kezdve a legmagasabb prioritásúval. Az ugyanolyan prioritású operátorok jobbról balra hajtódnak végre.                     new [ ! ~ ++ -- (int) (double) (string) (array) (object)

@ * / % + - . << >> < <= > >= == != === !== & ^ | && || ?: = += -= *= /= .= %= &= |= ^= ~= <<= >>= print and xor or , 18 4 Vezérlési szerkezetek Az idáig bemutatott kódokban az utasítások mindig sorban egymás után végrehajtódtak, és a program mindig ugyanazt az eredményt adta. Ez a szekvenciális végrehajtás nem biztosít túl nagy teret a rugalmasságnak. A bonyolultabb programokban lehetőség van feltételek kiértékelésére, és a program ennek megfelelően változtatja viselkedését. 4.1 Az elágazás Az elágazás teszi lehetővé, hogy a programunk egy adott ponton egy kifejezés logikai értékének megfelelően haladjon tovább. Az elágazásoknak általában három típusa szokott megjelenni a programozási nyelvekben: az egyágú (egyirányú), a kétágú (kétirányú), és a többágú (többirányú). 4.11 Az egyágú és a kétágú elágazás if (kifejezés) { utasítás; } Ha a kifejezés

logikai értéke igaz, akkor a zárójelpárok által meghatározott blokk végrehajtódik. A két zárójel elhagyható, ha a blokk egyetlen utasításból ál Az elhagyás azonban sokszor rontja az átláthatóságot, valamint ha később más utasítást is felveszünk a blokkba, esetleg megfeledkezhetünk a zárójelekről. 01: 02: 03: 04: 05: 06: 07: 08: <?php $szam=2; if ($szam==2) { print "A szám értéke 2"; } //kiírja, hogy A szám értéke 2 ?> A fenti kódban a $szam változó tartalmát vizsgáljuk. Ha a változó tartalma 2, akkor az if utáni blokkban található utasítás végrehajtódik, egyébként nem tesz semmit a program. Jelen esetben a böngészőben megjelenik ’A szám értéke 2’ szöveg. Fontos megjegyezni, bár már volt róla szó, hogy a kifejezés vizsgálatakor a dupla = jelet használjuk a szimpla helyett. Ezek összekeverése súlyos hiba! Ha azt írtuk volna, hogy if ($szam=2), akkor ez mindig az igaz logikai értéket

szolgáltatja, ugyanis ilyenkor a $szam változónak értékül adjuk a 2-t (mivel ez mindig sikeres, igaz logikai értéket adunk az if számára). A kétágú elágazás lehetőséget ad arra, hogy a kifejezés hamis logikai értéke esetén is utasításokat hajtsunk végre. if (kifejezés) { utasítás; } else { 19 } utasítás; Ilyenkor a két blokk közül valamelyik fog végrehajtódni. A következő példaprogramban egy szám reciprokát szeretnénk előállítani majd megjeleníteni, de figyelembe kell vennünk, hogy a nullának nincs reciproka. 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: <?php $szam=2; print "A szám: $szam<br>"; if ($szam!=0) { print "A szám reciproka: "; print 1/$szam; } else { print "Nincs reciproka!"; } //kiírja, hogy 0.5 ?> 4.12 A többágú elágazás Többágú elágazást létrehozhatunk az előbbi kétágú elágazások egymásba ágyazásával, vagy az elseif kulcsszó használatával,

és később látni fogjuk, hogy létezik egy külön utasítás is ehhez. Az if-elseif-else szerkezet alakja: if (kifejezés) { utasítás; } elseif (kifejezés) { utasítás; } else { utasítás; } Ha az első kifejezés logikai értéke hamis volt, akkor program az elseif ágra ugrik, ahol megvizsgálja a második kifejezést, ha ez a logikai igaz, akkor végrehajtja az elseif által meghatározott blokkot, ha a logikai hamis, akkor az else ágra ugorva végrehajtja az else blokkját. Természetesen annyi elseif kulcsszót írhatunk ebbe a szerkezetbe, amennyit csak akarunk. A következő egyszerű példa az if-elseif-else használatát mutatja be. 01: 02: 03: 04: 05: 06: <?php $hom=120; print "A víz hőmérséklete: $hom °C<br>Halmazállapota: "; if ($hom<0) { print "szilárd"; 20 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: } elseif ($hom<100) { print "folyékony"; } else { print "gáz"; } //kiírja, hogy gáz ?> A

switch utasítás is egy lehetséges módja annak, hogy egy kódrészletet egy kifejezés értékétől függően hajtsunk végre. Van azonban néhány különbség az if és a switch között Az if-et az elseif-el használva több kifejezés értékétől tehetjük függővé, míg a switch esetében a program csak egy kifejezést vizsgál meg, és annak értékétől függően különböző utasításokat hajt végre. A kifejezésnek valamilyen típusnak kell lennie (szám, karakterlánc vagy logikai érték). switch (kifejezés) { case érték1: utasítás1; break; case érték2: utasítás1; break; default: utasítás; } A case alapszavak után tűntetjük fel az egyes értékeket, és az összes többi lehetséges értéket lefedhetjük a default-tal. A switch úgy működik, hogy ha egy case utáni érték azonos a kifejezés értékével, akkor végrehajtja az összes ez utáni utasítást az ágakon. Emiatt használjuk a break kulcsszót, amely segítségével

„kiugorhatunk” a switch-ből. A következő példaprogram a switch használatát mutatja be: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: <?php $szam=4; print "A szám: $szam<br>"; switch($szam) { case "1": print "1-est dobott!"; break; case "2": print "2-est dobott!"; break; case "3": print "3-ast dobott!"; break; case "4": print "4-est dobott!"; break; case "5": print "5-öst dobott!"; break; default: print "6-ost dobott!"; } //kiírja, hogy 4-est dobott! 21 25: ?> 4.13 A ?: operátor A ?: ternális (háromoperandusú) műveletjel egy olyan if utasításhoz hasonlít, amely értéket is képes visszaadni. A visszaadott értéket a vizsgált feltétel határozza meg: (feltétel) ? érték ha a feltétel igaz : érték ha a feltétel hamis; Ha a vizsgált feltétel igaz, a ? és a : közti

kifejezés értékét adja, ha hamis, akkor a : utánit. Ehhez kapcsolódó egyszerű példa egy szám abszolútértékét adja meg: 01: 02: 03: 04: 05: 06: <?php $szam=-3; print "A szám: $szam<br>"; $abs=($szam>=0) ? $szam : -$szam; print "Az abszolútértéke: $abs"; //kiírja, hogy 3 ?> 4.2 A ciklus A ciklusok segítségével arra is képesek vagyunk, hogy bizonyos programrészeket többször lefutassunk. Általában meg szoktunk különböztetni feltételes és nem feltételes ciklusokat. Nem feltételes ciklus a számláló ciklus, míg a feltételes ciklusokhoz tartozik ez elöl- ill. a hátultesztelő ciklus 4.21 A while ciklus A while ciklus az elöltesztelő ciklus megfelelője a PHP nyelvben. Az elöltesztelő ciklus a kifejezés logikai értékét az ismétlendő rész előtt vizsgálja. A while szerkezete nagyon hasonló az if szerkezetéhez: while (kifejezés) { utasítás; } Amíg a kifejezés igaz logikai értékű, addig a program

folytatja a blokk ismétlését. Ebből következik, hogy kell lennie egy olyan utasításnak az ismétlendő részben (vagy maga a kifejezés tartalmazza az utasítást), ami egyszer hamissá teszi a kifejezést, különben végtelen ciklust kapnánk. 01: 02: 03: 04: 05: 06: 07: 08: <?php $szam=1; while ($szam<=10) { print "A szam változó értéke: $szam<br>"; $szam++; } ?> Ez az egyszerű program 1-től 10-ig kiírja az egész számokat a böngészőbe. A fontos utasítás, amely segítségével majd kilépünk a ciklusból, a 6. sorban található A következő kód 10-től kettesével visszafele 1-ig kiírja a számokat és a négyzetüket (az 1et nem). 22 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: <?php $szam=10; while ($szam>0) { print "A szam változó értéke: $szam, négyzete: "; print $szam*$szam; print "<br>"; $szam-=2; } ?> 4.22 A do ciklus A do ciklus hasonló a while ciklushoz, csupán egyetlen lényegi

különbség van: a kifejezés vizsgálata a blokk után történik, ezért is hívják hátultesztelő ciklusnak. Ebből következik, hogy egyszer mindenképpen végrehajtódnak a blokkban található utsítások, még ha hamis is kezdetben a kifejezés logikai értéke. do { utasítás; } while (kifejezés); Példák a do ciklus használatára: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: <?php $szam=1; do { print "A szam változó értéke: $szam, négyzete: "; print $szam*$szam; print "<br>"; $szam+=2; } while ($szam<=10); ?> 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: <?php $szam=14; do { print "A szam változó értéke: $szam, négyzete: "; print $szam*$szam; print "<br>"; $szam+=2; } while ($szam<=10); ?> A 14 és a négyzete megjelenik a böngészőben, holott a feltételben a kisebb vagy egyenlő, mint 10 szerepel. A do ciklust nem ilyen esetekben használjuk, ennek a ciklusnak is megvan az alkalmazási

területe. A későbbi fejezetekben látunk majd erre példát 4.23 A for ciklus A for ciklust szokták számláló ciklusnak hívni, ám ez a szerkezet a PHP-ben sokkal általánosabb, mint például a Pascal vagy a Basic nyelvekben. A for a while-hoz képest rövidebb leírást és biztonságosabb használatot eredményez. A for ciklus általános alakja: 23 for (kifejezés1;kifejezés2;kifejezés3) { utasítás; } A for ciklust könnyen while ciklussá írhatjuk át, így az előbbivel egyenértékű while ciklus: kifejezés1; while (kifejezés2) { utasítás; kifejezés3; } A kifejezések közül bármelyik elhagyható, így végtelen ciklust a legkönnyebben az összes elhagyásával csinálhatunk: for (;;) Egy korábbi példa megvalósítása a for ciklus segítségével: 01: 02: 03: 04: 05: 06: 07: 08: <?php for ($szam=1;$szam<=10;$szam+=2) { print "A szam változó értéke: $szam, négyzete: "; print $szam*$szam; print "<br>"; } ?> A

2. sorban először kezdőértéket adunk a $szam változónak (ciklusváltozó), majd megadjuk a ciklusban maradás feltételét, végül megadunk egy utasítást, ami később majd a ciklus befejeződését váltja ki. For ciklusok egymásba ágyazása: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: <?php for ($i=1;$i<5;$i++) { for ($j=1;$j<4;$j++) { print "Az i változó értéke: $i"; print ", a j változó értéke: $j<br>"; } } ?> Ennél a példánál két ciklusunk van, két ciklusváltozóval ($i és $j). A futtatás után jól látszik, hogy az ilyen egymásba ágyazott ciklusoknál a külső ciklus ciklusváltozója egy értékénél a belső ciklus ciklusváltozója fölveszi az összes lehetséges értéket. 4.24 A break utasítás A break utasítással elhagyható (befejezhető) a while, do, for ciklus. Példa: 24 01: 02: 03: 04: 05: 06: 07: 08: 09: <?php for ($szam=1;$szam<=10;$szam+=2) { if ($szam*$szam>50) break; print

"A szam változó értéke: $szam, négyzete: "; print $szam*$szam; print "<br>"; } ?> A 4. sorban meghatározzuk, hogy ha az adott szám négyzete nagyobb lenne, mint 50, akkor fejezzük be a ciklust. 4.25 A continue utasítás A continue utasítás segítségével a vezérlő kifejezések kiértékelésére kényszeríthetjük a while, do, for ciklust (a következő ismétlés azonnali elkezdésére kényszerítjük a ciklust). Példa: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: <?php for ($i=1;$i<6;$i++) { for ($j=1;$j<5;$j++) { if ($j==2) continue; print "Az i változó értéke: $i"; print ", a j változó értéke: $j<br>"; } } ?> Mivel a continue a belső ciklusban található, így arra érvényes. Amikor a $j változó értéke 2, nem hajtódnak végre a continue után található print utasítások, hanem a következő ismétlésre ugrunk (azaz a $j 2 értéke sosem jelenik meg a böngészőben). 25 5

Függvények Előfordulhat, hogy egy probléma megoldására célszerű a feladatot önállóan is értelmes részekre bontani, majd ezeket tovább elemezve újabb, egyre elemibb egységekbe tagolni, amelyek megoldása már korábbról ismert, azaz ismert programozási szabályok vagy hozzá hasonló algoritmusok segítségével megvalósítható. Az is többször előfordul, hogy a feladat többször is felhasznál ilyen elemi részt. Ha minden esetben ezt le kellene írnunk, akkor a programunk rendkívül terjengőssé válna, ezért kézenfekvő megoldás lenne, ha az ilyen részek nevet kaphatnának, ekkor csak a nevükre kellene hivatkozni. Az önállóan értelmes részfeladat megoldását végző algoritmust eljárásnak nevezzük. Sokszor előfordul, hogy az eljárással egyetlen értéket határozunk meg, amelyet célszerű lenne a matematikai függvények mintájára kezelni. Ez azt jelenti, hogy olyan speciális eljárásokat kell létrehoznunk, amelyek a meghívást

követően egyetlen, jól meghatározott típussal rendelkező értéket szolgáltatnak, olyan módon, hogy ezt az értéket az eljárás azonosítója hordozza. A közönséges eljárásoktól való megkülönböztetés céljából az előbbi tulajdonsággal rendelkező, önállóan értelmes algoritmusrészeket nevezzük függvénynek. Ha a függvény nevére hivatkozunk, a függvényt meghívjuk, azaz a függvény törzse lefut. A függvénynek feldolgozás céljából értékeket adhatunk át, amikor pedig a függvény véget ér, a hívónak egy értéket ad vissza. Az előző fejezetekben már láttunk példákat a függvényekre, a függvényhívásra. Ilyen volt például a print("Hello, World!");. A függvényhívásnál a függvény neve után zárójelek között (a print ebből a szempontból kivételes, zárójelei elhagyhatók) a függvény bemenő paramétereit soroljuk föl vesszővel elválasztva (azokat az adatokat, amiket átadunk a függvénynek). A

függvényeknek általában van visszatérési értéke is, melyet a hívónak visszaad, például a print() visszatérési értéke logikai érték, azaz arról informál minket, hogy sikeres volt –e a függvény végrehajtása. 5.1 Függvények létrehozása, az érték szerinti paraméterátadás A függvények létrehozásához a function kulcsszót kell használnunk: function fuggvenynev(formális paraméterek) { utasítás; } A fuggvenynev azonosító szerepet tölt be, így két egyforma nevű függvény nem lehet egy PHP programban, valamint betűt, számot, és az jelet tartalmazhat, de számmal nem kezdődhet. A formális paraméterek azok a paraméterek, melyekkel a függvény le van írva, a hívás során ezek helyére az aktuális paraméterek kerülnek. Nézzünk egy példát a paraméter nélküli függvényre: 01: 02: 03: 04: 05: 06: 07: <?php function koszon() //a koszon függvény definiálása { print "Üdvözlöm!"; } koszon(); //a koszon

függvény meghívása ?> Nézzünk most egy példát a paraméterrel rendelkező függvényre: 26 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: <?php function koszont($kit) //függvény definiálása egy paraméterrel { print "Üdvözlöm, $kit!<br>"; } koszont("István"); //a koszont függvény meghívása $ki="Géza"; koszont($ki); //a koszont függvény meghívása $ki="Ferenc"; koszont($ki); //a koszont függvény meghívása ?> A fenti példában a függvényt meghívtuk konstans értékkel, és úgy, hogy a PHP a változó tartalmát helyettesítette be. 5.2 Értékek visszaadása A függvényeknek visszatérési értéke is lehet (az olyan függvényt, amelynek nincs visszatérési értéke, eljárásnak szoktunk nevezni), ehhez a return utasítást fogjuk használni. A return befejezi a függvény futtatását, és az utána írt kifejezést küldi vissza a hívónak. A következő példaprogram két szám

átlagával tér vissza: 01: <?php 02: function atlag($egyik,$masik) 03: { 04: $atlag=($egyik+$masik)/2; 05: return $atlag; 06: } 07: $szam1=2; 08: print "Az első szám: $szam1<br>"; 09: $szam2=5; 10: print "A második szám: $szam2<br>"; 11: print "A két szám átlaga: "; 12: print atlag($szam1,$szam2); 13: //az atlag függvény meghívása (az atlag által visszaadott érték kiíratása) 14: print "<br>"; 15: print "A 6 és a 8 átlaga: "; 16: print atlag(6,8); 17: //az atlag függvény meghívása konstans paraméterekkel: kiírja, hogy 7 18: ?> 5.3 Cím szerinti paraméterátadás Az eddigi programjainkban paramétereket csak érték szerint adtunk át, ami azt jeleni, hogy a paraméterek értékeit felhasználni tudja csak a függvény, megváltoztatni nem. Mit tehetünk akkor, ha azt szeretnénk, hogy a bemenő paraméterek értékei is megváltozhassanak? Ehhez használnunk kell az & (hivatkozó)

operátort. A lenti program feladata, hogy felcserélje a paraméterként megadott két változó tartalmát. 01: <?php 02: function csere(&$egyik,&$masik) 03: { 04: $seged=$masik; 05: $masik=$egyik; 27 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: $egyik=$seged; } $szam1=2; print "Az első szám: $szam1<br>"; $szam2=6; print "A második szám: $szam2<br>"; csere($szam1,$szam2); print "Csere után:"; print "<br>"; print "Az első szám: $szam1<br>"; //kiírja, hogy 6 print "A második szám: $szam2"; //kiírja, hogy 2 ?> Az egyetlen dolog, amit tennünk kellett, hogy a két formális paraméter elé beszúrtuk a & jelet (2. sor) 5.4 Változó számú paraméterek Előfordulhat, hogy nem tudjuk hány paraméter kerülhet egy függvénybe. A PHP lehetővé teszi, hogy megállapítsuk, hány paramétere van a függvénynek, és ennek megfelelően használjuk. A függvényben a

paraméterek kezelésére a func num args(), a func get arg(), és a func get args() függvényeket használhatjuk. Az első megadja a paraméterek számát, a második az adott sorszámú paramétert (0-tól sorszámozva), a harmadik pedig egy tömbbe rendezi az összes paramétert. Nézzünk erre egy kicsit bonyolultabb példát: 01: <?php 02: function voros() 03: { 04: $szoveg=""; 05: $paramszam=func num args(); //a paraméterek számának letárolása 06: for ($i=0;$i<$paramszam;$i++) 07: { 08: $szoveg.=func get arg($i)"<br>"; //a paraméterek összefűzése 09: } 10: return print "<font color="red">$szoveg</font>"; 11: //a kapott sztring megjelenítése vörös színnel 12: } 13: voros("Ez egy vörös színű sor","Ez is","Meg ez is"); //a függvény meghívása 14: ?> Ebben a példában már felhasználtuk a korábban megismert . és = operátorokat A $szoveg változó kezdetben az

üres sztringet tartalmazza (4. sor), majd miután letároltuk a paraméterek számát a $paramszam változóba (5. sor), hozzáfűzzük a soron következő paraméter tartalmát az előzőekhez és közéjük az új sor tag-et (8. sor) egy for ciklus segítségével. Ami még magyarázatra szolgál, hogy a 10 sorban miért került a red ”-ei elé egy jel. Erre azért van szükség, mert a PHP úgy venné, hogy ott kezdődik egy sztring vagy ott van vége. A jel és utána leírt karaktereket vezérlőkaraktereknek hívjuk A $ jelet például csak úgy írathatjuk ki, hogy $-t írunk a print-be, ellenkező esetben a PHP egy változót keresne a kiíráshoz. Akkor is működőképes programot kapunk, ha a tagekben a " jeleket egyszerűen elhagyjuk 28 5.5 Elhagyható paraméter Megtehetjük azt is, hogy egy formális paraméternek értéket adunk a függvény paraméterlistájában, és ekkor a paraméter a függvény hívásánál elhagyható lesz, a PHP azzal értékkel

fog dolgozni, amit a paraméterlistában megadtunk. Ha viszont a hívásnál értéket adunk, akkor lecserélődik a listában megadott arra, amivel hívunk. Ezt mutatja be a következő kód: 01: <?php 02: function kiir($mit,$meret,$szin="red") 03: { 04: return print "<font size="$meret" color="$szin">$mit</font><br>"; 05: } 06: kiir("Ez egy 4-es méretű, kék színű szöveg.",4,"blue"); //a függvény meghívása 07: kiir("Ez egy 3-as méretű, vörös színű szöveg.",3); //a függvény meghívása 08: ?> 5.6 Hatókör Amikor a hatókör kifejezést függvényekkel és változókkal kapcsolatban használjuk, arra gondolunk, hogy a kód mely részében látjuk ezeket az elemeket, és mely részében lehet használni őket. A PHP-ben a hatókör szabályai: − − − − − A függvény paraméterlistájával bevitt változók lokális változók, kivéve, ha & jel van előttük.

A függvényen belül definiált változók lokális változók, kivéve, ha a global kulcsszót eléjük írtuk a definiáláskor. A függvényen kívül definiált változók nem érhetők el a függvényen belül, kivéve, ha paraméterként vittük be őket a függvénybe, vagy ha a global utasítással definiáltuk őket. A define() utasítással definiált konstansok mindig globálisak, függetlenül attól, hogy a függvényen belül vagy kívül definiáltuk őket. A függvények mindig globálisak, így egy másik függvény belsejében definiált függvény mindenhol elérhető. A global kulcsszó használata: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: <?php function csere($egyik,$masik) { global $seged; $seged=$masik; $masik=$egyik; $egyik=$seged; } csere(6,2); print "A segédváltozó tartalma: "; print $seged; //kiírja, hogy 2 ?> A global alapszót itt arra használtuk, hogy a függvény belsejében definiált változót a függvényen kívül is

elérjük. Ha a függvényen kívül definiálunk egy változót, amit a függvényen belül szeretnénk használni, akkor a változó definiálásakor szintén ki kell tennünk a global kulcsszót. 29 5.7 Statikus változók Lehet a kódunkban egy olyan függvény, amelyet többször használunk, és minden használatnál továbbítania kell egy értéket a következőnek. Ezt meg lehetne oldani egy globális változó segítségével, de ennél egyszerűbb és logikusabb megoldás, ha statikus változót használunk. Nézzünk egy példát, amely egyszerűen kiírja a függvényhívások számát: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: <?php function kiir() { static $szam=0; $szam++; print "Függvényhívások száma: $szam<br>"; } kiir(); //kiírja, hogy a Függvényhívások száma: 1 kiir(); //kiírja, hogy a Függvényhívások száma: 2 ?> Ez egy nagyon egyszerű példa a static használatára, nézzük, hogy a static nélkül mit kellett volna

tennünk: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: <?php $szam=0; function kiir() { global $szam; $szam++; print "Függvényhívások száma: $szam<br>"; } kiir(); //kiírja, hogy a Függvényhívások száma: 1 kiir(); //kiírja, hogy a Függvényhívások száma: 2 ?> A következő három részben a PHP függvényei közül a fontosabbak kerülnek megemlítésre egy kis magyarázat mellett. A PHP összes függvényének leírása egyrészt nagyon terjedelmes lenne, másrészt nem is cél, a PHP dokumentáció folyamatos böngészése ajánlott. 5.8 Matematikai függvények A következő táblázat a PHP matematikai átváltásainak gyors áttekintését tartalmazza: Eredmény Függvény $integer or float = $float = abs($int or float) acos($float) $float = asin($float) $float = atan($float) $float = atan2($float l, $float 2) Leírás Abszolútértékét adja. A szög arkusz koszinuszát adja radiánban. A szög arkusz szinuszát adja radiánban. A

szög arkusz tangensét adja radiánban. A két változó arkusz tangensét adja. 30 $float = $float = $float = $float = $float= $value = $value = $value = $value = $string = $float = $float = $float = $float = $float = cos($float) A radiánban meghatározott szög koszinuszát adja. exp($float) Az e-t a $float hatványára emeli. lcg value() Kombinált lineáris kongruencia generátor. log($float) A $float természetes logaritmusát adja. log10($float) A $float 10-es alapú logaritmusát adja. max($array) A tömbben levő maximális értéket adja. max($value l, $value 2 . A paraméterlistában levő $value n) maximális értéket adja. min($array) A tömbben levő minimális értéket adja. min($value l, $value 2 . A paraméterlistában levő $value n) minimális értéket adja. number format($float, A tizedesjel és az ezreseket $decimal places, elválasztó karakter használatával $decimal point, megformáz egy számot. $decimal separator) pi() A pi értékét adja 13

tizedes pontossággal. pow($floatx, $floaty) A $floatx-et a $floaty-dik hatványra emeli. sin($float) A radiánban meghatározott szög szinuszát adja. sqrt($float) A $float négyzetgyökét adja. tan($float) A radiánban meghatározott szög tangensét adja. A PHP-ben az egész és lebegőpontos matematikán kívül létezik a tetszőleges pontosságú matematika is. Ez egy olyan matematika, ahol mi határozhatjuk meg a szükséges pontosságot. A szoftver, jelen esetben a BCMath, valamilyen módon mindig megbirkózik a nagy számokkal, legfeljebb bizonyos műveletek tovább tartanak. A dokumentációban a függvény referencia címszó alatt megtalálhatók ezek a függvények (mindegyik neve bcvel kezdődik). A PHP ezen kívül támogatja a korlátlan hosszúságú egészekkel való számolást is. A GMP, vagy GNU MP egy nyílt forráskódú matematikai csomag, amely beillesztésével szintén tetszőleges pontosságú aritmetikai függvényekhez juthatunk, amelyekkel előjeles

egész, racionális és lebegőpontos számokon lehet műveleteket végrehajtani. A csomag letölthető a http://wwwswoxcom/gmp címről 5.9 Dátum- és időfüggvények A PHP több dátum- és időfüggvényt tartalmaz, mint a legújabb csúcstechnológiájú karóra. A lenti táblázat a dátum és idő kiszámításához szükséges függvényeket tartalmazza, a többi számítást ezekből a függvényekből kapott eredményekkel, illetve ezen eredmények átalakításával lehet elvégezni. 31 Függvény checkdate() date() getdate() gettimeofday() gmdate() gmmktime() gmstrftime() localtime() microtime() mktime() strftime() time() strtotime() Leírás Ellenőrzi, hogy a Gergely-naptár szerinti dátum helyes –e. A helyi dátumot és időt formázva adja vissza. A helyi dátumot és időt tömbként adja vissza. Az aktuális időt tömbként adja vissza. Ugyanaz, mint a date(), de a helyi idő helyett a GMT-t haszanálja A dátumot Unix-időjelzésre konvertálja. A GMT

dátumot és időt formázza. A helyi időt tömb elemeiként adja. A Unix-időjelzést a másodperc törtrészével adja vissza. A Unix-időjelzést adja vissza egy dátumból. Ugyanaz, mint a gmstrftime(), csak a helyi időt használja. Unix-időjelzést ad vissza. A szöveges dátumot/időt Unix-időjelzésre konvertál. 5.10 Sztringfüggvények A sztringfüggvényekkel dolgozni a PHP-ban egyrészt szórakoztató dolog, másrészt az adatkezelésnek egy hasznos módja. A legtöbb sztringfüggvény bináris adatokat kezel, a PHP azonban elvégzi a szükséges konverziókat. A fontosabb sztringfüggvények leírását láthatjuk a lenti táblázatban: Eredmény Függvény $string = $addslashes($string) $string = bin2hex($string) $string = chop($string) $string = chr($integer) $array = count chars($string, $mode) $string = crc32($string) Leírás Visszaper jeleket ad az idézőjelekhez, kétszeres idézőjelekhez, visszaper jelekhez és az üres karakterekhez, így a

sztringet SQL-ekkel be lehet szúrni adatbázisba. Az input sztring bináris adatának hexadecimális megjelenítését adja vissza. Eltávolítja a szóvégén álló szóközöket, így a szóközöket, , , és chr(13) karaktereket. A szám ASCII karakterkészletbeli megfelelőjét adja (az ord() ellentétje). Egy tömböt ad vissza, mely a sztring egyes karaktereinek gyakoriságát tartalmazza. A $mode opcionális és ellenőrzi, hogy mi van számolva. A sztring CRC32 értékét számolja ki. 32 $string = crypt($string, $key) Egy opcionális kulcs használatával DES eljárással rejtjelez egy sztringet. echo($string) Egy vagy több sztringet írat ki, hasonló a print()-hez. $array = explode($separator, Tömböt hoz létre a sztringből a $separator $string) egyes előfordulásainál szétvágva azt. $array = get meta tags A megnevezett fájl meta tag tartalmát adja ($file name) tömbben vissza. $string = htmlentities($string) A<, >, , ^, & és a nehezen

megjeleníthető karaktereket HTML-elemekre konvertálja. $string = htmlspecialchars($string) A <, >, , ", és & karaktereket HTMLelemekre konvertálja. $string = implode($separator, A tömb elemeket egyesítve sztringet hoz $array) létre. Az explode() ellentétje $string = levenstein($string 1, A két sztring közötti Levenstein-távolságot $string 2) számítja ki, ami az egyezőség mértéke. $string = ltrim($string) Levágja a szóközöket, , , , v és karaktereket a sztring elejéről. $string = md5() A sztring MD5-típusú digitális kivonatát adja vissza. $string = nl2br($string) A sztringben az összes newline ( ) elé HTML sortörést (<br>) szúr be. $integer = ord($string) A karakter ASCII értékét adja vissza (a karakter karakterkészleten belüli ordinális számát adja vissza), $boolean = print($string) Egy sztringet írat ki, siker esetén igazat, hiba esetén hamisat ad vissza. $boolean = printf($format, $variables) A $format

sztringgel formázott változókat írja ki. $array = sscanf($string, $format) Egy tömböt ad vissza, melynek az értékei a $format használatával kerültek be a sztringből. $integer = strcasecmp($string l, Bináris-biztos, a kis-és nagybetűket nem $string 2) megkülönböztető sztring összehasonulást végez el. 0-t ad vissza, ha $string l == $string 2, -1-et, ha $string l < $string 2, vagy 1-et, ha $string l > $string 2. $integer = strncasecmp($string l, A strcasecmp() változata, mely a sztringeket $string 2, $length) a $length által megadott hosszúságig hasonlítja össze. $integer = strcmp($string l, A strcasecmp() kis és nagybetűket $string 2) megkülönböztető változata. $string = strip tags($string, $tags) Eltávolítja a sztringből a HTML tag-eket a $tags-ben felsoroltak kivételével. $string = stripcslashes() Az addcslashes()-sel hozzáadott visszaper jeleket távolítja el. $string = stripslashes() Az addslashes()-sel hozzáadott visszaper jeleket

távolítja el. Ha addslashes()-t használunk, majd ezt követően MySQL- 33 $integer = stristr($search, $string) $integer = strlen($string) $string = str pad($string, $length, $pad, $mode) ben tároljuk az adatokat, a MySQL eltávolítja a visszaperjeleket és használatra kész adatokat ad vissza. A strstr() kis- és nagybetűket megkülönböztető változata. A sztring hosszát adja vissza. A szóközökkel a $length mértékben jobbra igazított sztringet adja vissza. Ha az opcionális $pad sztring meg van adva, akkor azt használja a szóközök helyett. Az opcionális $mode-dal választhatunk az igazítások közül. $integer = strpos($string l, $string 2) A $string l-el adja vissza a $string 2 pozícióját. $string = strrchr($string, $char) A $string-ből az utolsó $char utáni sztringet adja vissza. $string = str repeat($string, Olyan sztringet ad vissza, amely a bemeneti $integer) sztringet $integer alkalommal tartalmazza. $string= strrev($string) A sztringet

fordított karaktersorban adja vissza. $integer = strrpos($string, $char) A $string-ben levő utolsó $char pozícióját adja vissza. $string = strspn($string, $char) A $string első részét adja vissza, amely csak a $char-ban levő karaktereket tartalmazza. $integer = strstr($search, $string) A $search-nek a $string-en belüli első előfordulásának pozícióját adja vissza. $string = strtok($string, $separator) A $separator-nál elválasztja a sztringet és egyszerre egy szakaszt ad vissza. $string = strtolower($string) Kisbetűsre konvertálja a sztringet. $string = strtoupper($string) Nagybetűsre konvertálja a sztringet. $string = str replace($find, A $string-ben a $find összes előfordulását $replace, $string) $replace-re cseréli. $string = strtr($string, $from, $to) A sztringben a karaktereket $from-ról $to-ra fordítja. $string = substr($string, $start, A sztring $start-tól kezdődő $length $length) hosszúságú részét adja vissza. Ha a $length nincs

meghatározva, akkor a $start-tól sztring végéig halad. $integer = substr count($string, A $string-ben levő $char előfordulásának $char) számát adja vissza. $string = substr replace($string, Egy sztringet ad vissza, amelyben a $start$replace, $start, $length) tól kezdődő szöveg a $length hosszúságban a $replace-re van cserélve. Ha a $length nincs megadva, a sztring végéig cseréli. $string = trim($string) Levágja a szóközöket, , , , v és karaktereket a sztring elejéről és végéről. $string = ucfirst($string) A sztring első karakterét nagybetűssé 34 $string = $string = változtatja. Különösen mondatok formázásánál hasznos. ucwords($string) Minden szó első karakterét nagybetűssé változtatja. Fejezetcímek formázásánál hasznos (bár magyar nyelvben ez nem szokás). wordwrap($string, $length, Newline-okat szúr be a sztringbe úgy, hogy a $char) szöveget a $length-nek megfelelő hosszúságú sorokra töri. Ha a $length nincs

megadva, akkor alapbeállításban soronként 72 karakter. Ha a $char meg van határozva, akkor azt szúrja be a newline helyett. Láthatjuk, hogy a PHP millió lehetőséget nyújt számunkra akár számokkal, dátumokkal vagy szöveggel dolgozunk. Az következő fejezetekben jónéhány függvény alkalmazása megtalálható lesz majd a példaprogramokban. 35 6 Tömbök és objektumok 6.1 Tömbök Programjaink rugalmasságát a tömbök használata nagymértékben növeli, de vigyáznunk kell, mert néhány csapdát is rejtenek magukban. A PHP-tömböket úgy használhatjuk, mintha a memóriában tárolt mini adatbázisok lennének, hiszen rengeteg függvény áll rendelkezésünkre. Legyenek az adatok szöveges dokumentumokban, nyomtatható fájlokban, XML fájlokban vagy adatbázisokban, betölthetők tömbbe, és feldolgozhatók anélkül, hogy az eredeti fájlba belenyúlnánk. „A tömb változók listája. Több változót tartalmaz, amelyeket számok vagy

karakterláncok segítségével azonosíthatunk, így a különböző értékeket egyetlen névvel tárolhatjuk, rendezhetjük és érhetjük el.” (ZANDSTRA, 2000, 98 old) 6.11 Tömbök létrehozása Tömböket sokféleképpen létrehozhatunk: függvények és a tömbazonosító segítségével is. Az array() listából hoz létre tömböt, az explode() határolt sztringből (megtalálható az előző fejezet sztringfüggvényei között), és használhatjuk a szögletes zárójelek között a tömbazonosítót is a tömbelemek értékeinek meghatározására. Az array() függvény és a [ ] használata: Az array() függvény akkor hasznos, ha egyszerre több értéket szeretnénk egy tömbhöz rendelni: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: <?php $nevek=array("István",32,"Péter"); print $nevek[0]; //kiírja, hogy István print ": ".gettype($nevek[0])"<br>"; //kiírja, hogy string print

$nevek[1]; //kiírja, hogy 32 print ": ".gettype($nevek[1])"<br>"; //kiírja, hogy integer print $nevek[2]; //kiírja, hogy Péter print ": ".gettype($nevek[2])"<br>"; //kiírja, hogy string print $nevek[3]; //nem ír ki semmit, mert nincs 4. elem $szamok[]=3.14; //első elem a 314 $szamok[]="négy"; //második elem a négy $szamok[]=true; //harmadik elem a true, azaz a logikai igaz print $szamok[0]; //kiírja, hogy 3.14 print ": ".gettype($szamok[0])"<br>"; //kiírja, hogy double print $szamok[1]; //kiírja, hogy négy print ": ".gettype($szamok[1])"<br>"; //kiírja, hogy string print $szamok[2]; //kiírja, hogy 1 print ": ".gettype($szamok[2]); //kiírja, hogy boolean ?> A PHP-ben a tömb sokkal rugalmasabb, mint néhány programozási nyelvben. A tömböknek bármennyi eleme lehet, bármikor hozzáadhatunk újakat, és az is megengedett, hogy különböző

típusú adatok kerülhessenek bele. A fenti példa jól illusztrálja, hogy bármilyen típusú értéket adhatunk a tömb elemeinek (összetett típust is), majd az indexek (sorszámok) segítségével megjeleníthetjük a tömb tartalmát (a sorszámozás 0-val kezdődik). Egy tömb feltöltéséhez, vagy újabb elemek hozzáadásához ugyanúgy használhatjuk a szögletes zárójeleket (10. sor) A rugalmasság kedvéért még a sorszámot sem kell megadni, a PHP tudja, hogy melyik a soron következő (létezik ugyanis egy ún. tömbmutató). 36 6.12 Asszociatív tömbök Ha a tömbelemeket sorszámozás helyett elnevezzük, asszociatív tömböt kapunk. Tulajdonképpen a PHP-ben minden tömb asszociatív tömb, a számozott adatok is asszociatív adatokként viselkednek. Az elnevezés során csak egy dologra kell ügyelnünk: két egyforma nevet nem adhatunk, mert ekkor nem tudnánk egyértelműen azonosítani őket, ezért ezt a nevet kulcsnak hívjuk. Az asszociatív tömbök

létrehozásához ugyanúgy használhatjuk az array() függvényt és a szögletes zárójeleket is: 01: <?php 02: $szemely=array("nev"=>"István","szulido"=>"1956.1003","szulhely"=>"Kes zthely"); 03: print $szemely["szulido"]; //kiírja, hogy 1956.1003 04: print "<br>"; 05: $egyen["nev"]="István"; 06: $egyen["szulido"]="1956.1003"; 07: $egyen["szulhely"]="Keszthely"; 08: print $egyen["szulido"]; //kiírja, hogy 1956.1003 09: ?> 6.13 Többdimenziós tömbök Ebben a fejezetben már volt szó arról, hogy összetett típus is lehet egy tömb eleme, így lehet tömb és objektum is. Ez a lehetőség kifinomultabb adatszerkezeteket biztosít számunkra. A többdimenziós tömb azt jelenti, hogy a tömb elemei tömbök A PHPtömbök bármennyi dimenziót elfogadnak, és az egyes dimenziók bármennyi elemet

tartalmazhatnak. Valójában az a helyzet, hogy előbb futunk ki a memóriából, mint elérnénk a PHP korlátjait. Persze más probléma is lehet, ha túl sok dimenzióval dolgozunk: egy idő után nem fogjuk már átlátni az egészet. Ezért erősen javasolt, hogy három dimenzió fölött ne próbálkozzunk, és abban is biztosak lehetünk, hogy kevesebb dimenziószámmal is meg lehet oldani a feladatot. A többdimenziós tömbök létrehozása: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: <?php $tablazat=array ( array(2,3,4), array(6,5,1) ); print $tablazat[0][2]; //kiírja, hogy 4 print "<br>"; print $tablazat[1][1]; //kiírja, hogy 5 print "<br>"; $szemelyek=array //asszociatív tömbök tömbje ( array ( "nev"=>"István", "szulido"=>"1956.1003", "szulhely"=>"Keszthely" ), array ( "nev"=>"Béla",

"szulido"=>"1963.0213", "szulhely"=>"Zalaegerszeg" 37 24: 25: 26: 27: 28: 29: ) ); print $szemelyek[0]["nev"]; //kiírja, hogy István print "<br>"; print $szemelyek[1]["szulhely"]; //kiírja, hogy Zalaegerszeg ?> Ha végiggondoljuk, csak a szerkezeteket kell egymásba ágyazni, és elő is áll a többdimenziós tömb (2. sortól a 6 sorig, 11 sortól a 25 sorig) A 7, 9, 26, és a 28 sor figyelmeztet minket arra, hogy egy tömbelem eléréséhez több indexet/azonosítót kell használnunk. 6.14 A tömbmutató A tömbmutató csak néhány nyelvben áll rendelkezésre, és a PHP-ben található az egyik legjobb megvalósítása. A tömbmutató segít meghatározni, hogy hol vagyunk, amikor egy tömbben mozgunk. Több függvény is támogatja a tömbmutatót, hogy segítse a tömbben való mozgást. A reset() a tömb elejére állítja vissza a tömbmutatót. Ezt akkor célszerű használni,

amikor egy ismeretlen állapotú tömbön kell végigmenni (azaz nem tudjuk, hogy hol áll benne a mutató). Amikor egy tömböt adunk át egy függvénynek, az alapértelmezésben értékként történik, így egy másolatot kap a tömbről, aminek az elején áll a tömbmutató. Ha viszont hivatkozással adjuk át, akkor a tömb az eredeti mutatót tartja meg, ami lehet, hogy ismeretlen pozícióban van. A mutató aktuális helyzetét a current() függvénnyel kérdezhetjük le, a next() a következőre léptet, a prev() az előzőre, míg az end() a tömb utolsó elemére állítja a tömbmutatót. Az each() függvény megadja az aktuális elem kulcsát és értékét, és átviszi a mutatót a következő adatra. Ennek segítségével bejárhatjuk a tömböt felhasználva egy while ciklust (a bejárás előtt azonban meg kell győződni arról, hogy a tömb elején van a mutató). 6.15 Tömbök bejárása Egydimenziós tömbök bejárása A tömbök bejárása történhet az

előbb említett each() függvény segítségével, de a PHPben nemrég bevezettek erre egy külön ciklustípust is. A következőkben ezek használata látható: 01: 02: 03: 04: 05: 06: 07: 08: <?php $felhasznalok=array ("István", "Géza", "Béla"); $felhasznalok[5]="Kismalac"; foreach ($felhasznalok as $egyen) { print"$egyen<br>"; } ?> A ciklus a foreach() (4. sor) Később látni fogjuk, hogy ezt lehet többdimenziós tömböknél is használni. Ennél a példánál megadtuk a $felhasznalok tömböt paraméterként a ciklusnak, majd az as kulcsszóval jelöltük, hogy a tömbelemek értékeit rendre a $ertek változóba szeretnénk megkapni. Ezután a ciklusmagban már csak a $ertek változó tartalmát kell kiíratni. Van itt még egy érdekes dolog: A tömbünk először három elemet tartalmaz (0,1,2 sorszámokkal), később hozzáadunk egy újat, aminek a sorszámát 5-re állítunk be. Ez azt jelenti, hogy ez a 6

elem, így nincs 4 és 5 38 elem. A PHP nem fog üres helyet hagyni, azaz a nem létező elemekre nem pazarol üres helyet (ebből látszik, hogy valójában a sorszámozott tömb is asszociatív tömb). Pontosan emiatt létezik a foreach() és az each() utasítás, mivel ezek a tömbmutatót használják fel, így nem lehet probléma a bejárással, a ’Kismalac’ is megjelenik a böngészőben (ha for ciklust használtunk volna, mint ahogy sok nyelvben ezzel járjuk be a tömböket, indexproblémák merültek volna fel). Az asszociatív tömbök bejárása: 01: <?php 02: $szemely=array("nev"=>"István","szulido"=>"1956.1003","szulhely"=>"Kes zthely"); 03: foreach ($szemely as $kulcs=>$ertek) 04: { 05: print "$kulcs=$ertek<br>"; 06: } 07: reset($szemely); 08: while (list($kulcs,$ertek)=each($szemely)) 09: { 10: print $kulcs.": "$ertek"<br>"; 11: } 12: ?> A 3.

sorban a ciklusnál módosítanunk kellett, itt a kulcs alapján jelenítjük meg az értéket Ebben a példában a list() függvény minden egyes értéket külön változóban ment el (8. sor, a kulcs és az érték is változókba kerülnek), így megkönnyíti az eredmények feldolgozását. Az each()-et a nem asszociatív tömbökön alkalmazva a kulcsok megfelelnek az elemek sorszámainak. Ha a tömb többdimenziós, akkor a $ertek változó egy tömb lesz, amit teljesen hasonlóan fogunk bejárni. Többdimenziós tömbök bejárása Mindent ismerünk már ahhoz, hogy a többdimenziós tömböket be tudjuk járni: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: <?php $tablazat=array ( array(2,3,4), array(6,5,1) ); foreach ($tablazat as $sor) { foreach ($sor as $ertek) { print "$ertek<br>"; } } $szemelyek=array ( array ( "nev"=>"István", "szulido"=>"1956.1003",

"szulhely"=>"Keszthely" ), array ( "nev"=>"Béla", "szulido"=>"1963.0213", 39 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: "szulhely"=>"Zalaegerszeg" ) ); foreach ($szemelyek as $szemely) { foreach ($szemely as $kulcs=>$ertek) { print "$kulcs=$ertek<br>"; } } reset($szemelyek); while (list($kulcs,$ertek)=each($szemelyek)) { while(list($kulcs2,$ertek2)=each($ertek)) { print $kulcs2.": "$ertek2"<br>"; } } ?> 6.16 Műveletek tömbökkel A táblázat a gyakran használatos tömbkezelő-függvényeket foglalja össze: Eredmény $array = $array = $array = Függvény array flip($array) array merge($array 1, $array 2) array pad($array, $integer, $value) $value = array pop($array) $integer = $integer = array push($array, $value 1, $value 2, $value n) array rand($array) $value = array shift($array) $array =

array slice($array, $index 1, $index 2) $integer = count($array) $array = file($file name) $boolean = is array($variable) Leírás Átvált az értékek és a kulcsok között. A két megadott tömböt egyesíti. A tömböt feltölti annyi darab $valuevel, hogy a tömb elemszáma $integer legyen. A tömb utolsó elemét törli, majd az elem értékével tér vissza. A tömbhöz hozzáfűzi a megadott értékeket, és a tömb elemszámával tér vissza. A tömb egy elemét véletlenszerűen kiválasztja, majd az indexével tér vissza. Eltávolítja a tömb első elemét, és annak értékével tér vissza. Tömböt hoz létre az első indextől kezdve a másodikig a megadott tömb elemeinek értékéből. Ha a második indexet nem adjuk meg, akkor a végéig nézi. A tömbben lévő elemek számát adja meg. A $file name-mel megadott fájl tömbbe olvasása. Egy változóról megmondja, hogy tömb –e. 40 $array = range($index 1, $index 2) $array = shuffle($array)

Tömböt hoz létre az első indextől kezdve a másodikig a kulcsokból (kulcstartomány kijelölése). A tömb elemeinek véletlen sorrendbe rendezése. 6.17 Tömbök rendezése A PHP-tömböket az alábbi lehetőségek szerint rendezhetjük függvények segítségével: − − − − érték szerint kulcs szerint abc-sorrendbe számos természetes és speciális sorrendbe A megfelelő függvényeket tartalmazó táblázat: Függvény sort($array) asort($array) rsort($array) arsort($array) ksort($array) natsort($array) usort($array) Leírás Tömb rendezése érték szerint. Asszociatív tömb rendezése érték szerint. Tömb érték szerinti fordított sorrendbe rendezése. Asszociatív tömb érték szerinti fordított sorrendbe rendezése. Asszociatív tömb kulcs szerinti rendezése. Tömb érték szerinti természetes rendezése. Tömb nem természetes rendezése. A következő példaprogramban néhány tömbművelet és rendezés alkalmazását láthatjuk: 01: 02: 03:

04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: <?php function kiir($tomb) { foreach ($tomb as $ertek) { print "$ertek "; } print "<br>"; } function akiir($tomb) { foreach ($tomb as $kulcs=>$ertek) { print "$kulcs=$ertek "; } print "<br>"; } $elso=array("a","b","c"); print "Az első tömb elemei: "; 41 20: kiir($elso); 21: $masodik=array(3,1,2); 22: print "A második tömb elemei: "; 23: kiir($masodik); 24: $harmadik=array merge($elso,$masodik); //két tömb összefűzése 25: print "A két tömb összefűzése: "; 26: kiir($harmadik); 27: array push($harmadik,5,4,6); //az 5,4,6 hozzáfűzése a tömbhöz 28: print "Az 5,4,6 hozzáfűzése: "; 29: kiir($harmadik); 30: $elso elem=array shift($harmadik); //az első elem eltávolítása 31: print "Az első elem eltávolítása: "; 32: kiir($harmadik); 33: print "A tömb első

eleme volt: $elso elem<br>"; 34: $harmadik=array slice($harmadik,2,4); //a 3. elemtől 4 db elem kivétele 35: print "A 3. elemtől 4 db elem kivétele: "; 36: kiir($harmadik); 37: sort($harmadik); 38: print "A rendezett tömb elemei: "; 39: kiir($harmadik); 40: $szemely=array("nev"=>"István","szulido"=>"1956.1003","szulhely"=>"Kes zthely"); 41: print "Az asszociatív tömb elemei: "; 42: akiir($szemely); 43: asort($szemely); //érték szerinti rendezés 44: print "Érték szerint rendezve: "; 45: akiir($szemely); 46: ksort($szemely); //kulcs szerinti rendezés 47: print "Kulcs szerint rendezve: "; 48: akiir($szemely); 49: ?> 6.2 Objektumok Az objektumok a változókhoz hasonlóan adatokat tárolhatnak, ezeket az adatokat az objektumok adattagjaikban (tulajdonságaikban) tárolhatjuk. Képzeljünk el egy objektumot, amely egy személy adatait

tartalmazza, az objektum adattagjai ebben az esetben a személy neve, lakcíme és telefonszáma lehetnek. Ezzel semmi újat nem mondtunk még, hiszen erre a feladatra egy asszociatív tömb is tökéletesen megfelel. Az objektumok viszont tagfüggvényeket (metódusokat) is tartalmazhatnak. Ezek olyan függvények, amelyek az objektum adataival dolgoznak. Az előbbi példánál maradva, az objektum tartalmazhat egy megjelenit() metódust, amely a személy adatait jeleníti meg. Az objektum-orientált (objektumközpontú) programozás (OOP) a természetes gondolkodást, cselekvést közelítő programozási mód, amely a programozási nyelvek tervezésének következetes fejlődése következtében alakult ki. Az így létrejött nyelvek sokkal strukturáltabbak, sokkal modulárisabbak és absztraktabbak, mint egy hagyományos programozási nyelv. Az objektum-orientált nyelveket három fontos dolog jellemez: − Egységbezárás (encapsulation): az adatstruktúrákat (adattagokat)

és az adott struktúrájú adatokat kezelő függvényeket (tagfüggvényeket) kombináljuk, azokat egységként kezeljük, és elzárjuk őket a külvilágtól. Az így kapott egységeket objektumoknak nevezzük. Az objektumok megfelelő tárolási egysége az osztály (class). Például, készítünk egy kör objektumot, amely maga képes elvégezni mindent, amit egy körrel megtehetünk, akkor ebbe beletartozik a kör adatainak 42 sugár és középpont - nyilvántartása, de ki kell tudnia számítani például más adatokból a sugarat, vagy éppen kirajzolni a kört. Tehát egy „csomagot” készítünk, amelybe mindent beleteszünk, ami szükséges. − Öröklés (inheritance): az adott, létező osztályokból újabb osztályok származtathatók, az öröklés során pedig az osztályok öröklik a szülő-osztály adatstruktúráit és függvényeit, ugyanakkor új tulajdonságokat és metódusokat definiálhatnak, vagy újraértelmezhetnek, így egy

osztályhierarchiához jutunk. Például, a körből gömböt készíthetünk, hiszen a gömb rendelkezik a kör minden jellemzőével, csak eggyel több dimenziója van. − Sokalakúság (polymorphism): egy adott metódus azonosítója (neve) ugyanaz lehet egy osztályhierarchián belül, ugyanakkor a hierarchia minden egyes osztályában a tevékenységet megvalósító függvény az osztályra nézve specifikus. Például, tegyük fel, hogy különböző alakzataink vannak, háromszögek, négyzetek és körök. Ekkor a sokalakúság segítségével általában minden alakzattal képesek leszünk dolgozni. A terulet() tagfüggvény az alakzathoz alkalmazkodva ki tudja majd számítani annak területét. − Újrahasznosíthatóság: miután készítettünk egy osztályt, újra és újra felhasználva több objektumot gyárthatunk belőle. Az öröklés és a sokalakúság segítségével olyan eljárásokat készíthetünk, melyeket többször, többféleképpen is

használhatunk, nem kell újra és újra ellenőrizni a működés részleteit. Az osztály tehát egy később készítendő elem meghatározása, a szóban forgó elem pedig az objektum. Gyakori példa ezek megkülönböztetéséhez a süteményforma és a sütemény A süteményforma meghatározza a süti alakját, de önmaga nem sütemény (még csak nem is ehető), csak egy eszköz, amellyel süteményeket készíthetünk. Használatakor biztosak lehetünk abban, hogy a sütik egyformák lesznek, és nem fog elkopni, akármennyi süteményt is készítünk. A süteményformához hasonlóan az osztállyal is több objektumot készíthetünk, így ha van például egy kör osztályunk, akkor ezzel számos kört létrehozhatunk. „Az objektum az osztály egy példánya, vagyis egy objektum nem más, mint az osztályban rögzített működési szabályok megtestesülése. Egy adott típusú objektum a new kulcsszó után írt objektumtípus nevének segítségével testesíthető

meg. Amikor egy objektumpéldány létrejön, összes tulajdonsága és tagfüggvénye elérhetővé válik.” (ZANDSTRA, 2000, 120. old) A PHP4-et nem igazán az objektum-orientált programozásra tervezték. Ugyan rengeteg dolgot tartalmaz, amiről szó volt idáig, mégis vannak olyan részek, melyek megvalósítása még nem megfelelő vagy hiányzik. A PHP 5-ös változata teljesen új OOP lehetőségeket tartalmaz, amelyek sokkal inkább közelebb viszik a PHP-t az objektumorientált nyelvekhez. 6.21 Osztályok és objektumok létrehozása Ahhoz, hogy létre tudjunk hozni egy objektumot, először létre kell hoznunk egy sablont (ez az osztály), ami megmondja pontosan, hogy az objektum milyen tulajdonságokkal fog rendelkezni, valamint hogy mit tehetünk majd az objektummal a tulajdonságait felhasználva. Az osztály létrehozásához a class kulcsszót kell használnunk: class legegyszerubb { } 43 Ennél egyszerűbb osztályt nem lehet készíteni, gyakorlatilag semmit

sem tartalmaz. Most már van egy legegyszerubb nevű osztályunk, hogyan készítjük el az osztály példányait? $obj1=new legegyszerubb(); $obj2=new legegyszerubb(); A $obj1 és a $obj2 is tehát egy példánya az osztálynak. A példányosításnál a new kulcsszó után az osztály nevét (azonosítóját) tüntettük fel, valamint tettünk utána zárójeleket. Úgy tűnik, mintha az osztály neve is egy függvény lenne Erre majd később kapjuk meg a választ a konstruktor részben. Az objektumok típusa az object a PHP-ben, így ha a gettype() függvényt használjuk a $obj1 vagy a $obj2 változókkal, ezt kapjuk. 6.22 Adattagok (tulajdonságok) Az előbbi példában bemutatott osztálynak példányai nem rendelkeztek sem tulajdonságokkal, sem függvényekkel. Hozzunk létre egy olyan osztályt, ami majd hozzárendel tulajdonságokat a példányához: 01: <?php 02: class szemely 03: { 04: var $nev="Péter"; //nev adattag létrehozása (string típusú) 05: var

$eletkor=30; //eletkor adattag létrehozása (integer típusú) 06: } 07: $obj=new szemely(); //$obj objektum létrehozása (példányosítás) 08: print "$obj->nev, $obj->eletkor<br>"; //adattagok tartalmának kiíratása 09: $obj=new szemely(); 10: $obj->nev="László"; 11: $obj->eletkor=26; 12: print "$obj->nev, $obj->eletkor"; 13: ?> A szemely osztályt a 2. sorban definiáltuk, mely két adattagot határoz meg az objektumok számára: nev és eletkor. Az adattagok deklarálásához a var kulcsszót használtuk, majd kezdeti értéket rendeltünk hozzájuk, mint ahogy ez látszik a program 4. és 5 sorában, így a létrehozott objektumok adattagjai felveszik ezeket az értékeket a példányosításkor. Az objektum adattagjait a -> operátor segítségével érhetjük el (8. sor), és ennek segítségével értéket is adhatunk nekik (10. és 11 sor) 6.23 Tagfüggvények (metódusok) A metódusok függvények egy

osztályban, amelyek műveleteket hajtanak végre egy objektumban. Ezeket a függvényeket tehát az összes példányban elérhetjük és meghívhatjuk. A következő példa a szemely osztályunkat egy tagfüggvénnyel bővíti, melynek segítségével a személy neve megjeleníthető lesz: 01: <?php 02: class szemely 03: { 04: var $nev="Péter"; 05: var $eletkor=30; 06: function nev() //nev tagfüggvény (metódus) létrehozása 07: { 44 08: print $this->nev; //a leendő objektum nev adattagának tartalmát írja ki 09: } 10: } 11: $obj=new szemely(); //példányosítás 12: $obj->nev(); //tagfüggvény meghívása: kiírja, hogy Péter 13: $obj->nev="László"; 14: print "<br>"; 15: $obj->nev(); //tagfüggvény meghívása: kiírja, hogy László 16: ?> A tagfüggvényt a 6. sorban definiáltuk, és a 8 sorban a $this-szel a későbbi példányra hivatkoztunk. A $this-> segítségével gyakorlatilag az objektumból

elérhetjük az objektum bármely részét, így módosíthatjuk az adattagok értékeit, meghívhatunk metódusokat. Egy objektumnak lehet ugyanolyan nevű adattagja, mint tagfüggvénye, a zárójelek segítségével meg tudjuk különböztetni őket. 6.24 Konstruktor A konstruktor fogalma már nem teljesen új, hiszen egy említést már tettünk róla az osztályok és objektumok létrehozása részben. Igen, létrehozható egy olyan függvény, aminek ugyanaz a neve, mint az osztálynak, ezt hívják konstruktornak (constructor). A példányosításnál a konstruktort hívjuk meg (ha nem hoztunk létre az osztályban, a PHP generál egy üreset), azaz ennek a feladata, hogy létrehozza (construct ~ felépít) a példányt. A konstruktornak lehetnek paraméterei, néhány nyelvben az is megengedett, hogy több konstruktort definiáljunk, melyek a bemenő paraméterek számában vagy típusaiban különböznek. A PHP-ben nem lehet két egyforma azonosítójú (nevű) függvényt

definiálni, így nem lehet két konstruktort sem, viszont a függvények fejezetben megtanultuk, hogyan kezelhetjük a változó számú paramétereket. A példában ezt használjuk fel: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: <?php class szemely { var $nev="Anonymous"; var $eletkor=0; var $cim=""; function szemely() //konstruktor { $paramszam=func num args(); if ($paramszam>0) $this->nev=func get arg(0); if ($paramszam>1) $this->eletkor=func get arg(1); if ($paramszam>2) $this->cim=func get arg(2); } function nev() { print "$this->nev<br>"; } function eletkor() { print "$this->eletkor<br>"; } function cim() { print "$this->cim<br>"; } } 45 27: $obj=new szemely(); //konstruktor meghívása paraméter nélkül (példányosítás) 28: $obj->nev(); //kiírja, hogy Anonymous 29: $obj->eletkor(); //kiirja, hogy 0 30:

$obj->cim(); //nem ír ki semmit 31: $obj=new szemely("Kiss László",25,"7624 Pécs, Petőfi u. 14"); 32: //konstruktor meghívása paraméterekkel 33: $obj->nev(); //kiírja, hogy Kiss László 34: $obj->eletkor(); //kiírja, hogy 25 35: $obj->cim(); //kiírja, hogy 7624 Pécs, Petőfi u. 14 36: ?> Az adattagok definiálása a 2. sortól kezdődik, ahol beállítottuk a megfelelő kezdőértékeket, azért, hogy a konstruktor paraméter nélküli hívásánál is mondjon valamit az objektum számunkra. A konstruktor leírása a 7 sortól kezdődik, a paraméterek kezeléséhez felhasználtuk a func num args() és a func get arg() függvényeket. A komolyabb objektum-orientált nyelvekben az adattagok és tagfüggvények hozzáférési jogait is megadhatjuk. Azokhoz az adattagokhoz, amelyeket privátnak definiálunk, kívülről nem férünk hozzá (csak az objektumból). Ilyenkor minden privát adattaghoz készíthetünk publikus (bárhonnan

hozzáférhető) tagfüggvényeket, amelyek segítségével beállíthatjuk és lekérdezhetjük az adattagok tartalmát (általában a beállító metódusok neve a set szóval, míg a lekérdező metódusok neve a get szóval kezdődik). A PHP-ben nincs ehhez hasonló hozzáférési jogosultság, azaz az adattagok és tagfüggvények bárhonnan elérhetők, de célszerű írni olyan tagfüggvényeket, amelyek segítségével kezelni tudjuk az adattagokat. Az előbbi példában ezért írhattunk volna a nev, eletkor és cim adattagokhoz olyan metódusokat, amelyek segítségével értéküket beállíthatjuk. A konstruktor párja a destruktor (megsemmisítő) az objektum-orientált nyelvekben, feladata az objektum megszűntetése. A PHP-ben nincs destruktor, így ha meg akarunk szűntetni egy objektumot, meg kell írnunk hozzá a kódot (felhasználva a környezeti változókat és az unset() függvényt). 6.25 Öröklés Az objektumközpontú szemlélet egyik nagyon fontos

jellemzője, hogy ún. osztályhierarchiát építhetünk fel az öröklés segítségével. Az öröklés során a gyermekobjektumok örökölnek minden tulajdonságot és metódust szülőjüktől, de definiálhatnak újakat is. Nézzünk egy egyszerű példát az öröklésre: 01: <?php 02: class szemely 03: { 04: var $nev; 05: function szemely($neve="Anonymous") //konstruktor 06: { 07: $this->nev=$neve; 08: } 09: function nev() 10: { 11: print "$this->nev<br>"; 12: } 13: } 14: class dolgozo extends szemely //a dolgozo osztály a szemely osztály leszármazottja 15: { 46 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: var $fizetes; function fizetes() { print "$this->fizetes<br>"; } } $obj=new szemely(); $obj->nev(); //Kiírja, hogy Anonymous $obj=new dolgozo("István"); $obj->fizetes=126500; $obj->nev(); //Kiírja, hogy István $obj->fizetes(); //Kiírja, hogy 126500 ?> A dolgozo osztályt a

szemely osztály leszármazottjaként vezettük be az extends kulcsszóval a 14. sorban, majd egy új tulajdonsággal (fizetes) bővítettük a 16 sorban Így minden személynek csak neve van, míg minden dolgozónak fizetése is. A fizetés lekérdezéséhez írtunk egy fizetes() tagfüggvényt is (17. sor) A 24 sorban létrehoztunk egy dolgozót István névvel. A dolgozo származtatott osztálynak nem írtunk konstruktort, így a szülő osztály (szemely) konstruktora hívódik meg. Ha valamely függvény (beleértve a konstruktort is) nincs újradefiniálva a gyermekosztályban, akkor a híváskor a szülőosztályban található hívódik meg. Megtehettük volna, hogy új konstruktort, és új nev tagfüggvényt írunk. 6.26 Sokalakúság Most pedig megnézzük, hogy hogyan lehet felülírni a szülő tagfüggvényeit, és ezután mégis elérni, valamint hogy hogyan lehet objektumokból tömböt képezni: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18:

19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: <?php class szemely { var $nev; var $fizetes; function szemely($neve="Anonymous") { $this->nev=$neve; } function setnev($neve) { $this->nev=$neve; } function getnev() { print "Személy: $this->nev<br>"; } function setfizetes($fiz) { $this->fizetes=$fiz; } function getfizetes() { print "Fizetése: $this->fizetes<br>"; } } class munkaltato extends szemely //a munkaltato osztály a szemely osztály leszármazottja { var $erkezes; 47 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: meg 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: function getnev() { print "Munkáltató: $this->nev<br>"; } function seterkezes($erk) { $this->erkezes=$erk; } function geterkezes() { print "Érkezési év: $this->erkezes<br>"; } } class alkalmazott extends szemely //az

alkalmazott osztály a szemely osztály leszármazottja { function getnev() { print "Alkalmazott: $this->nev<br>"; } function getszemelynev() { parent::getnev(); //a szülőosztály nev tagfüggvényét hívja } } $obj[0]=new szemely("László"); $obj[0]->setfizetes(137500); $obj[1]=new munkaltato("Péter"); $obj[1]->setfizetes(250000); $obj[1]->seterkezes(1992); $obj[2]=new alkalmazott("Géza"); $obj[2]->setfizetes(85000); foreach ($obj as $egyen) { $egyen->getnev(); if (get class($egyen)==alkalmazott) $egyen->getszemelynev(); /*ha az egyen objektum az alkalmazott osztály példánya, akkor meghívjuk az enev tagfüggvényt*/ $egyen->getfizetes(); if (get class($egyen)==munkaltato) $egyen->geterkezes(); /*ha az egyen objektum a munkaltato osztály példánya, akkor meghívjuk az erkezes tagfüggvényt*/ print "------------------<br>"; } ?> Ebben a példában minden osztályhoz megírtuk az

adattagok beállításához és lekérdezéséhez szükséges metódusokat. A szemely osztályból két osztályt is származtattunk, a munkaltato (27. sor) osztályt, és az alkalmazott (44 sor) osztályt A getnev() metódust újradefiniáltuk a származtatott osztályokban (31, 47. sorok), és definiáltunk újakat is (35, 39, 51. sorok) Az alkalmazott osztályban elkészítettünk egy olyan tagfüggvényt (getszemelynev()), amellyel meghívtuk a szülő getnev() tagfüggvényét. Az 53 sorban a parent:: gondoskodik arról, hogy elérjük a szülő adott metódusát. A parent a szülő osztályt nevezi meg, így nem kell leírni annak a nevét A 56. sortól kezdődően három objektumot hoztunk létre, és ezeket a $obj tömbbe helyeztük. A tömböt a későbbiekben bejártuk, és a tömbelem osztálytípusa szerint hívtuk meg az objektumok tagfüggvényeit. Az objektum osztályának meghatározásához a get class() függvényt használtuk. 48 6.27 Objektumfüggvények A

táblázatban a fontosabb objektumfüggvényeket foglaltuk össze: Eredmény Függvény Leírás call user method(string 1, string 2, , string n, $object) $boolean = $string = $array = $array = $array = $array = $string = $boolean = $boolean = A $object objektum metódusait hívja meg. A sztringek a metódusok nevei. call user method array(string 1, Ha az objektumok egy tömbben string 2, , string n, $array) vannak ($array-ben), akkor meghívhatjuk mindegyik (a sztringekkel meghatározott) ugyanazon metódusait. class exist($string) Logikai választ ad arról, hogy $string nevű osztály létezik –e. get class($object) Megadja a $object osztályát. get class methods($string) Egy tömbbe tölti a $string nevű osztály metódusait. get class vars($string) Egy tömbbe tölti a $string nevű osztály adattagjait. get declared classes() Egy tömbbe tölti a deklarált osztályokat. get object vars($object) Egy tömbbe tölti a $object objektum adattagjait. get parent class($string)

A $string nevű osztály szülőosztályát adja meg. is subclass of($object, $string) Logikai választ ad arról, hogy a $object szülőosztálya –e a $string nevű osztály. method exist($object, $string) Logikai választ ad arra, hogy létezik –e a $object objektumnak $string nevű metódusa. Ezeknek a függvényeknek a használatát is egy példán keresztül mutatjuk be: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: <?php class szemely { var $nev="Anonymous"; function szemely($neve) { $this->nev=$neve; } function nev() { print "Személy: $this->nev<br>"; } } class dolgozo extends szemely /*a munkaltato osztály a szemely osztály leszármazottja*/ 49 17: { 18: var $fizetes; 19: function nev() 20: { 21: print "Dolgozó: $this->nev<br>"; 22: } 23: function fiz($fiz) 24: { 25: $this->fizetes=$fiz; 26: } 27: function fizetes() 28: { 29: print "Fizetése: $this->fizetes<br>"; 30: }

31: } 32: $obj=new szemely("László"); 33: call user method("nev",$obj); //ua, mint a $obj->nev(); 34: if (class exists(dolgozo)) print "Van dolgozo nevű osztály.<br>"; 35: print "Az obj objektum osztálya: ".get class($obj)"<br>"; 36: 37: function kiir($lista) 38: { 39: foreach($lista as $kulcs=>$ertek) 40: { 41: print $kulcs.": "$ertek"<br>"; 42: } 43: } 44: 45: $lista=get class vars(szemely); //list tömbbe tölti a létező adattagok neveit 46: print "A szemely osztály adattagjai: <br>"; 47: kiir($lista); 48: $lista=get class methods(dolgozo); //list tömbbe tölti a létező metódusok neveit 49: print "A dolgozo osztály metódusai: <br>"; 50: kiir($lista); //kiírja a szemely és a dolgozo metódusokat (konstruktorokat) is 51: $lista=get declared classes(); 52: print "A deklarált osztályok: <br>"; 53: kiir($lista); //a PHP-ben

létező osztályok is megjelennek 54: $lista=get object vars($obj); 55: print "Az obj objektum adattagjai: <br>"; 56: kiir($lista); 57: print "A dolgozo osztály szülőosztálya: ".get parent class(dolgozo)"<br>"; 58: $obj=new dolgozo("Péter"); 59: if (is subclass of($obj,"szemely")) 60: print "Az obj objektum elődosztálya a szemely osztály.<br>"; 61: if (method exists($obj,"dolgozo")) 62: print "Az obj objektum tartalmaz dolgozo metódust."; 63: ?> 50 7 Űrlapok Eddigi programjainkból egy fontos dolog hiányzott: nem tettük lehetővé, hogy a felhasználó által megadott adatokkal dolgozzon a program, vagy hogy a felhasználó módosíthassa az adatokat. Ahhoz, hogy ezt a felhasználó megtehesse, egy felületet kell számára biztosítani. A Világhálón alapvetően a HTML űrlapokon keresztül áramlik az információ a felhasználó és a kiszolgáló között. A

PHP-t úgy tervezték, hogy a kitöltött HTML űrlapokat könnyen fel tudja dolgozni. Mielőtt azonban rátérnénk az űrlapok használatára, meg kell ismerkednünk néhány lehetőséggel, ugyanis információt a felhasználóról nem csak űrlapok segítségével kaphatunk. 7.1 Globális és környezeti változók A globális változókat a program legfelső szintjén találjuk, és a függvényeken belül is használhatjuk őket. A PHP rendelkezik egy $GLOBALS tömbbel, ami tartalmazza például a programban definiált változókat, és az ún. környezeti változókat is A példaprogram a $GLOBALS tömb elemeit listázza ki: 01: 02: 03: 04: 05: 06: 07: <?php $nev="Péter"; foreach ($GLOBALS as $kulcs=>$ertek) { print $kulcs." = "$ertek"<br>"; } ?> A listában megtalálhatjuk az általunk bevezetett $nev változót a ’Péter’ értékével, a tömb kilistázásához felhasznált $kulcs és $ertek változókat értékükkel, és

láthatunk sok, elsőre ijesztőnek tűnő nevet is. A PHP néhány környezeti változója: Változó $HTTP GET VARS $HTTP POST VARS $HTTP REFERER $HTTP USER AGENT $PHP SELF $QUERY STRING $REMOTE ADDR $REQUEST METHOD Leírás Az űrlap mezőinek neve és értéke a GET kérelemnél (asszociatív tömb). Az űrlap mezőinek neve és értéke a POST kérelemnél (asszociatív tömb). Az oldal címe, amelyről a kérés érkezett. Az ügyfél böngészőjének neve és verziószáma. Példa nev=peter kor=32 nev=peter kor=32 http://www.probahu/index html Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; NET CLR 114322) /proba.php Az éppen futó program elérési útja és neve. A GET kérelmeknél az URL- nev=peter&kor=32 hez kapcsolt adat. Az ügyfél IP címe. 195.19926252 A kérelem módja: GET vagy GET POST. 51 $REQUEST URI A kérelem teljes címe. /proba/urlap.php? nev=peter&kor=32 A táblázatban szereplő változók elég információt tudnak adni egy

felhasználóról, vagy nagy mértékben tudják a mi munkánkat segítni. A PHP létrehoz még egyéb környezeti változókat is, melyeknek szintén meg van a szerepük. 7.2 Űrlap létrehozása Készítsünk el egy olyan egyszerű űrlapot, amely egy beviteli mező segítségével bekéri a felhasználó nevét, majd egy gombra kattintva később megjeleníti. Az űrlap-fájl (nev.htm): 01: <html> 02: <head> 03: <title>Egyszerű űrlap</title> 04: <meta http-equiv="Content-Type" content="text/html; charset=iso8859-2"> 05: </head> 06: <body> 07: <form action="nevf.php" method="POST"> 08: <p>Adja meg a nevét: <input type="text" name="nev"></p> 09: <input type="submit" value="Mehet"> 10: </form> 11: </body> 12: </html> Mint látható, az űrlapot a HTML kódban a <form> és a </form> határolja. E két

tag közé kell elhelyeznünk az űrlapelemeket, amelyek lehetnek szöveges beviteli mezők, listák, rádiógombok, elküld (submit) gombok, stb. A 8 sorban egy beviteli mezőt láthatunk, melynek azonosítója nev, a 9. sorban pedig egy elküld gombot, melynek értéke a Mehet (ez a gomb felirata), és feladata az űrlap továbbítása a megadott helyre. A 7. sorban látható, hogy az űrlap az értékeket POST–módszerrel továbbítja a célfájlnak (nevf.php), melyet az action-nel határoztuk meg A POST mind nagy értékekkel, mind az értékek hosszú listájával működik. Ha egy űrlapot a GET-módszerrel küldünk el, akkor annak mezői és azok értékei (URL kódolásban) hozzáfűződnek ahhoz a címhez (URLhez), ahová az űrlapot küldjük. Az értékek ekkor elérhetők lesznek a kiszolgáló, illetve az általa futtatott programok számára. A kérés például a következőképpen nézne ki, ha a fenti példában a POST helyett GET szerepelne:

http://localhost/nevf.php?nev=Kiss+Pista Minden mező nevét egy = jel választja el annak értékétől, a név-érték párokat pedig & jelek határolják. A PHP visszafejti a jeleket, a talált adatokat a $HTTP GET VARS asszociatív tömbben teszi elérhetővé a program számára, valamint az űrlapelemek nevével azonos nevű globális változókat létrehoz a megfelelő tartalommal, függetlenül a kérelem típusától. A nev nevű GET változóhoz az alábbi két módon férhetünk hozzá: $HTTP GET VARS["nev"]; $nev; A GET lekérések szerencsére nem csak űrlapokkal kapcsolatban használhatók, könnyen készíthetünk mi is ilyen karakterláncokat, így a fontos adatokat könnyedén továbbíthatjuk lapról lapra. 52 Az adatok feldolgozásának vagy tárolásának megvalósítása a célfájl, ebben az esetben a nevf.php feladata lesz A feldolgozáshoz már szükséges a PHP, míg magát az űrlapot leíró fájl tisztán HTML-kódot tartalmaz. Nézzük

a nevf.php fájlt, aminek a feladata, hogy a beírt nevet megjelenítse: 01: <?php 02: print "Az Ön neve: $nev"; 03: ?> Az űrlapelemek neveiből PHP változók lesznek, így a nev name-paraméterével megadott beviteli mező tartalma egy $nev változóba került. Semmi más dolgunk nem volt, mint kiíratni a böngészőbe a $nev változó tartalmát (2. sor) Nézzünk egy másik példát: Adjuk meg a másodfokú egyenlet megoldásait a felhasználó által megadott együtthatók segítségével! Az űrlap-fájl (masod.htm): 01: <html> 02: <head> 03: <title>A másodfokú egyenlet megoldásai</title> 04: <meta http-equiv="Content-Type" content="text/html; charset=iso8859-2"> 05: </head> 06: <body> 07: <form action="masodf.php" method="POST"> 08: Adja meg az együtthatókat: <br><br> 09: <input type="text" name="a"> *xx + 10: <input

type="text" name="b"> *x + 11: <input type="text" name="c"> = 0<br><br> 12: <input type="submit" value="Megoldás"> 13: </form> 14: </body> 15: </html> A feldolgozást végző fájl (masodf.php): 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: <?php $d=$b*$b-4$a$c; if ($a==0) if ($b==0) print "Nincs megoldás"; else { $x=-$c/$b; print "Megoldás:<br>x = "; printf("%.3f",$x); } else { if ($d<0) { $d=$d*(-1); $e=-$b/(2*$a); $f=sqrt($d)/(2*$a); print "Megoldások:<br>x1 = "; printf("%.3f",$e);print " + "; printf("%.3f",$f); print " * i<br>x2 = "; printf("%.3f",$e);print " - "; printf("%.3f",$f);print " * i"; } else 53 26: { 27: 28: 29: 30: 31: 32: 33: } 34: } 35: ?>

$x1=(-$b+sqrt($d))/(2*$a); $x2=(-$b-sqrt($d))/(2*$a); print "Megoldások:<br>x1 = "; printf("%.3f",$x1); print "<br>x2 = "; printf("%.3f",$x2); Itt a feldolgozás már bonyolultabb volt, mint az előző esetben, de jól látszik, hogy a három változó – a $a, a $b, és a $c – a beviteli mezők neveiből keletkeztek. A printf() függvénnyel a kapott lebegőpontos számokat fixpontosan íratjuk ki 3 tizedesjegyet megjelenítve. 7.3 Űrlapelemek használata Itt az ideje, hogy elkészítsünk egy komplett űrlapot, amely felhasználja valamennyi űrlapelemet. Az űrlap szintén a felhasználó adatait próbálja megtudni, de a szöveges beviteli mező mellett a rádiógombok, listák, és egyéb elemek is előfordulnak rajta. Az űrlap-fájl (urlap.htm): 01: <html> 02: <head> 03: <title>Űrlapelemek használata</title> 04: <meta http-equiv="Content-Type" content="text/html;

charset=iso8859-2"> 05: </head> 06: <body> 07: <form action="urlapf.php" method="POST" target=" blank"> 08: <p>Adja meg a nevét: <input type="text" name="nev"></p> 09: <p>Adja meg a nemét: <br> 10: <label> 11: <input name="nemcsop" type="radio" value="Nő" checked> 12: Nő 13: </label> 14: <label> 15: <input name="nemcsop" type="radio" value="Férfi"> 16: Férfi 17: </label> 18: </p> 19: <p>Adja meg az életkorát: 20: <select name="eletkor"> 21: <option>0-12</option> 22: <option>13-17</option> 23: <option selected>18-24</option> 24: <option>25-29</option> 25: <option>30-39</option> 26: <option>40-49</option> 27: <option>50-59</option> 28: <option>60-</option> 29:

</select></p> 30: <p>Adja meg a kontinenst: <br> 31: <label> 32: <input name="kontcsop" type="radio" value="Európa" checked> 33: Európa 34: </label> 35: <br> 54 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: <label> <input name="kontcsop" type="radio" value="Észak-Amerika"> Észak-Amerika </label> <br> <label> <input name="kontcsop" type="radio" value="Dél-Amerika"> Dél-Amerika </label> <br> <label> <input name="kontcsop" type="radio" value="Ázsia"> Ázsia </label> <br> <label> <input name="kontcsop" type="radio" value="Afrika"> Afrika </label> <br>

<label> <input name="kontcsop" type="radio" value="Ausztrália"> Ausztrália </label> </p> <p>Adja meg az érdeklődési körét:<br> (többet is választhat a CTRL lenyomásával)<br> <select name="erdeklodes[]" multiple> <option>Befektetések</option> <option>Sportok</option> <option>Művészetek</option> <option>Gyógyászat</option> <option>Jog</option> <option>Oktatás</option> <option>Járművek</option> <option>Számítógépek</option> <option>Mobiltelefonok</option> </select></p> <p>Az adataim megfelenek a valóságnak: <input type="checkbox" name="megfelel" value="igen"></p> <input type="submit" value="Mehet"> </form> </body> </html> A nem és a kontinens kiválasztásához

rádiógombokat használtunk. Ezek rádiógombok általában egy csoportot alkotnak, és a csoportból mindig csak egy választható ki (a checked tulajdonság jelzi azt, hogy kezdetben melyik van kiválasztva). A name tulajdonság értéke (nemcsop és kontcsop) lesz a változó neve, ami tartalmazza a kiválasztott értéket (a value tulajdonság értékét). Az életkor kiválasztásához egy listát használtunk (20. sor), a később létrejövő $eletkor változó valamelyik <option> és </option> közötti részt fogja tartalmazni. Az érdeklődési kör egy olyan lista (63 sor), amelyből több elem kiválasztható (multiple), neve az erdelkodes[], jelezve, hogy ebből egy tömb keletkezik. Ennek tartalmát később egy foreach segítségével íratjuk ki Végül az űrlap alján a válaszok megerősítésére szolgáló jelölőt (checkbox) láthatunk, melynek később az állapotát vizsgáljuk meg (kipipáltuk vagy sem). A kód megjelenítése a böngészőben:

55 A PHP-fájl (urlapf.php): 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: <?php if ($nev=="") print "<h3>Nem adta meg a nevét!</h3>"; elseif (!isset($erdeklodes)) print "<h3>Nem adta meg az érdeklődési körét!</h3>"; elseif (!isset($megfelel)) print "<h3>Nem hitelesítette adatait!</h3>"; else { print "<h3>Ön a következő adatokat adta meg:</h3>" ."<b>Név: </b>"$nev"<br>" ."<b>Neme: </b>"$nemcsop"<br>" ."<b>Életkora: </b>"$eletkor"<br>" ."<b>Kontinens: </b>"$kontcsop"<br>" ."<b>Érdeklődési köre:</b><br>"; foreach ($erdeklodes as $kor) { print $kor."<br>"; } } 56 21: ?> A programunk már tartalmaz némi ellenőrző részt is: az

űrlap kitöltöttségét ellenőriztük le (2-7. sor) A későbbi fejezetekben láthatunk példát egyéb űrlapelemekre, és az adatok fájlban ill. adatbázisban tárolására is A PHP kód eredménye: 7.4 Űrlap és PHP kód egy oldalon A célunk az, hogy egy olyan oldalt készítsünk, amely tartalmazza egyrészt az űrlapot, másrészt a feldolgozását is megvalósítja. Ez csak úgy lehetséges, hogy az űrlap-fájl tartalmazza a PHP kódot, és önmagát hívja meg. A példaprogram egy számkitalálós játék, 1 és 100 közötti egész számot kell kitalálni maximum 10 lépésből. 01: <html> 02: <head> 03: <title>Számkitalálós játék</title> 04: <meta http-equiv="Content-Type" content="text/html; charset=iso8859-2"> 05: </head> 06: <body> 07: <?php 08: if (isset($szam)) 09: { 10: if ($db==10 || $szam==$aszam) 11: { 12: print "<h3>"; 13: if ($szam!=$aszam) 14: print "Sajnos Ön nem

tudta kitalálni a számot 15: 10 próbálkozással!"; 16: else 17: print "Ön kitalálta a számot $db próbálkozással!"; 18: print "</h3>"; 57 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: } else { unset($szam); print "<a href=$PHP SELF>Új játék</a>"; die(); print "<h3>"; if ($szam<$aszam) print "Próbálkozzon nagyobbal!"; else print "Próbálkozzon kisebbel!"; print "</h3>"."<p>Próbálkozások száma: $db</p>"; $db++; } } else { $aszam=rand(1,100); print "<h3>Adja meg a számot:</h3>"; $db=1; } ?> <form action="<?php print $PHP SELF."?db="$db ?>" method="POST"> <p><input type="text" name="szam"></p> <input type="submit" value="Mehet"> <input

type="hidden" name="aszam" value="<?php print $aszam ?>"> </form> </body> </html> Az elgondolásunk az, hogy ha nincs a beviteli mezőnek értéke, azaz nincs kitöltve (8. sorban vizsgáljuk), akkor az azt jelenti, hogy most indul a játék. Ekkor generálunk egy véletlen számot ($aszam), és a számlálót ($db) 1-re állítjuk (34. és 36 sorok) Az elküld gombra kattintva a fájl önmagára hivatkozik a $PHP SELF változó segítségével. Kapcsolt adat formájában küldjük tovább a próbálkozások számát tartalmazó számlálót (39. sor), és a kitalálandó számot egy rejtett mező segítségével küldjük tovább a későbbi vizsgálatok elvégzéséhez (42. sor) A számlálót minden új kitöltésnél növeljük eggyel (29. sor), és megjelenítjük a felhasználó számára, hogy az általa megadott szám nagyobb vagy kisebb –e a kitalálandónál (26. és 27 sorok) Ha eltaláltuk a számot, akkor

kiírjuk, hogy hány próbálkozással sikerült (17. sor), majd a beviteli mező nevéből keletkezett változót ($szam) megszűntetjük (19. sor), és a program futását megállítjuk a die() függvénnyel (21. sor) A változó megszűntetése a játék újraindításához szükséges Ugyan ezt az utat járjuk végig, ha 10 lépésből nem sikerült kitalálni a számot, csak akkor a Sajnos Ön nem tudta kitalálni a számot 10 lépésből! szöveg kiíratása után szűntetjük meg a változót, és állítjuk meg a programot. 58 8 Fájlok és könyvtárak A fájlok számtalan formátumban és funkcióban fordulnak elő a különböző operációs rendszerekben, azonban elmondható, hogy mindenhol az adattárolás alapegysége. Szerencsére számos programozási nyelv mellett a PHP is biztosít számunkra lehetőséget a fájl- ill. könyvtárkezelésre 8.1 Könyvtárak A PHP az opendir() – könyvtár megnyitása, readdir() – könyvtár olvasása, closedir() –

megnyitott könyvtár bezárása, és az is dir() – eldönti valamiről, hogy könyvtár –e, függvényeket nyújtja a könyvtárak tartalmának megjelenítéséhez, míg az mkdir() új könyvtárat hoz létre, az rmdir() pedig létező könyvtárat töröl. 8.11 Könyvtárak listázása Két lehetőséget mutatunk be a sok közül erre a célra. Az első úgy listázza a könyvtár tartalmát, hogy megjeleníti a fájlok és könyvtárak nevét, és a könyvtárakhoz a [Dir] jelzést hozzáteszi. A másik leszámolja, hogy hány darab fájl ill könyvtár található az aktuális könyvtárban. Nézzük az elsőt: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: <?php $kvtnev="C:"; $kvt=opendir($kvtnev); while ($fajl=readdir($kvt)) { print "$fajl"; if (is dir("$kvtnev/$fajl")) print " [Dir]"; print "<br>"; } closedir($kvt); ?> Az egyetlen magyarázatra szoruló sor a 4. sor A while feltételében egy értékadás

szerepel, ami azt jelenti, hogy a ciklus addig ismétel, amíg sikeres az értékadás. A readdir() így addig olvas a könyvtárból a $fajl változóba, amíg van fájl a könyvtárban. A $fajl változóról pedig később eldöntjük az is dir() függvény segítségével (függvényparaméterének abszolút elérési útnak kell lennie), hogy könyvtár volt –e (7. sor). A második megoldás: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: <?php $kvtnev="C:"; $kvt=opendir($kvtnev); while ($fajl=readdir($kvt)) { $tipus=filetype("$kvtnev/$fajl"); if (isset($melyik[$tipus])) $melyik[$tipus]++; else $melyik[$tipus]=0; } closedir($kvt); foreach ($melyik as $kulcs=>$ertek) { print $kulcs.": "$ertek"<br>"; } 59 15: ?> A 6. sorban található filetype() függvény sztringként a fájl típusát adja vissza, ami a dir, file vagy link közül valamelyik lehet. A különböző típusok számát $melyik asszociatív

tömbben tároljuk (7. sor) 8.12 Egyéb könyvtárfüggvények A dirname() függvénybe a fájl elérési útját írva az elérési út könyvtárrészét kapjuk, míg a basename() a maradékot, a fájlnevet eredményezi. A pathinfo() ugyanazt az információt adja, mint a dirname() és a basename() összekapcsolva. A realpath() a relatív útvonalat abszolút elérési úttá konvertálja. 8.2 Fájlok A következőkben megtudhatjuk, hogy hogyan kell egy létező PHP fájlt beágyazni egy másik PHP fájlba, hogyan lehet fájltulajdonságokat megjeleníteni, hogyan lehet fájlokat létrehozni, olvasni, írni és törölni, valamint a fájlfeltöltésről is lesz szó. 8.21 Fájlok beágyazása Az include() függvény lehetőséget ad arra, hogy fájlt ágyazzunk be a PHP dokumentumokba. A fájlban szereplő PHP kód úgy hajtódik végre, mintha a fődokumentum része lenne, ami hasznos, ha egy többoldalas programban külső kódokat szeretnénk beágyazni. Másrészről a

többször felhasználandó részeket célszerű külön fájlokba elhelyezni, így azokat bármikor, bármelyik fájlba könnyedén beilleszthetjük. Pl.: include("probaphp"); 8.22 Fájlok listázása attribútumokkal együtt Ez a lehetőség azt mutatja meg, hogy hogyan fussunk végig egy könyvtáron belül a fájlokon a fájltulajdonságok kiíratásával: 01: <?php 02: $kvtnev="C:/"; 03: $kvt=opendir($kvtnev); 04: while ($fajl=readdir($kvt)) 05: { 06: fileinformaciok($kvtnev.$fajl); 07: } 08: closedir($kvt); 09: function fileinformaciok($f) 10: { 11: print "$f ".(is file($f)?"":"nem")" fájl<br>"; 12: print "$f ".(is dir($f)?"":"nem")" könyvtár<br>"; 13: print "$f ".(is readable($f)?"":"nem")" olvasható<br>"; 14: print "$f ".(is writable($f)?"":"nem")" írható<br>"; 15:

print "$f ".(is executable($f)?"":"nem")" futtatható<br>"; 16: print "$f ".(filesize($f))" bájt méretű<br>"; 17: print "$f utolsó megnyitásának dátuma: ".date("Ymd H:i",fileatime($f))."<br>"; 18: print "$f utolsó módosításának dátuma: ".date("Ymd H:i",filemtime($f))."<br>"; 19: print "$f utolsó változásának dátuma: ".date("Ymd H:i",filectime($f))."<br>"; 20: } 21: ?> 60 8.23 Fájlok létrehozása és törlése Ha egy üres fájlt szeretnénk létrehozni, a touch() függvényt kell használnunk. A paraméterként megadott fájlnév elé az elérési útvonalat is meg kell adnunk, ha nem az aktuális könyvtárban szeretnénk a fájlt létrehozni. Ha a fájl már létezik, akkor az utolsó módosítás dátuma módosul az utasítás végrehajtási idejére. Pl.:

touch("probatxt"); Létező fájlt törölni az unlink() függvénnyel lehet. Az unlink() paramétere a fájl elérési útja: Pl.: unlink("probatxt"); A létrehozás, törlés, írás, olvasás, módosítás csak akkor lehetséges egy fájlon, ha a megfelelő jogosultságokkal rendelkezünk. 8.24 Fájlok olvasása A fájlokat szekvenciálisan tudjuk olvasni és írni. A szekvenciális input fájt háromféleképpen lehet a PHP-ben olvasni: bájtonként, karakterenként, soronként. A következő példa a fájl megnyitása után ezek mindegyikét bemutatja: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: <?php $fajl="proba.txt"; if (!file exists($fajl)) { die("$fajl nem létezik"); } else { kar($fajl); sor($fajl); bajt($fajl); } function kar($fa) { $f=fopen($fa,"r") or die("$fa nem nyitható meg"); print "A $fa fájl

olvasása karakterenként<br>"; while (!feof($f)) { $karakter=fgetc($f); print "$karakter"; } print "<br><br>"; fclose($f); } function sor($fa) { $f=fopen($fa,"r") or die("$fa nem nyitható meg"); print "A $fa fájl olvasása soronként<br>"; while (!feof($f)) { $sor=fgets($f,1024); print "$sor<br>"; } print "<br>"; fclose($f); } function bajt($fa) 61 38: { 39: $f=fopen($fa,"r") or die("$fa nem nyitható meg"); 40: print "A $fa fájl olvasása 16 bájtonként<br>"; 41: while (!feof($f)) 42: { 43: $reszlet=fread($f,16); 44: print "$reszlet<br>"; 45: } 46: print "<br>"; 47: fclose($f); 48: } 49: ?> A 3. sorban a file exists() függvénnyel a fájl létezését döntjük el A karakterenkénti olvasást a 13. sortól kezdve láthatjuk A 15 sorban a fájlt megnyitjuk olvasásra (r - read) az fopen()

függvénnyel, melynek eredménye a $f fájlváltozó (a továbbiakban ezzel dolgozunk). Ezek után egy karaktert olvasunk a fájlból az fgetc() függvénnyel, amíg a fájl végére nem érünk (feof() – logikai értékű függvény, igaz értéket ad, ha a fájl végére értünk). A 25 sortól a soronkénti olvasást láthatjuk, melyben újdonság az fgets() függvény. Jelen esetben ez egy sort vagy 1024 bájtot olvas a fájlból Végül a 43 sorban a bájtonkénti olvasáshoz szükséges fread() függvény látható, melynek paramétere a fájlváltozó és a bájtok száma. 8.25 Fájlok írása Fájlok írásánál ugyanúgy az fopen() függvényt használjuk, de a második paraméterét "w"-re (write-ra) állítjuk, míg a hozzáfűzésnél "a"-ra (append-re). Abból nem lehet probléma, ha több felhasználó is ugyanazt a fájlt olvassa, de azt nem engedélyezhetjük, hogy valaki írjon egy fájlt, míg más olvassa, vagy többen ugyanazt a fájlt

írják. Ha egy fájlt írásra vagy hozzáfűzésre meg tudunk nyitni, akkor zároljuk, hogy más felhasználó ne tudja addig írni, amíg mi írjuk. A példa az írást és a hozzáfűzést mutatja be: 01: <?php 02: $fajlnev="proba.txt"; 03: print "$fajlnev fájlba írás<br>"; 04: if (!file exists($fajlnev)) touch($fajlnev); 05: $fa=fopen($fajlnev,"w") or die("$fajlnev nem nyitható meg"); 06: flock($fa,2); //más folyamatok nem olvashatják és írhatják ebben az időben 07: fwrite($fa, "Helló, világ! "); 08: flock($fa,3); //zárolás feloldása 09: fclose($fa); 10: print "$fajlnev fájlhoz hozzáfűzés"; 11: $fa=fopen($fajlnev,"a") or die("$fajlnev nem nyitható meg"); 12: flock($fa,2); 13: fputs($fa,"Helló, Web!"); 14: flock($fa,3); 15: fclose($fa); 16: ?> Egy proba.txt nevű fájllal dolgozunk a példaprogramban A 4 sorban döntjük el, hogy létezik –e a fájl, ha nem

akkor létrehozzuk. Ha a fájl létezett, akkor az írásnál elveszik korábbi tartalma. Az 5 sorban a fájlt megnyitjuk olvasásra, majd a 6 sorban zároljuk az flock() utasítással. Az flock() második paramétere lehet 1, 2 és 3 Az 1-es jelentése, hogy más folyamatok olvashatják, de nem írhatják. Ezt akkor használjuk, ha olvassuk a fájlt A 2-es jelentése, hogy más folyamatok nem olvashatják és nem írhatják. Ezt akkor 62 használjuk, amikor írunk a fájlba. A 3-as feloldja a zárolást A fájlba íráshoz az fwrite() függvényt használjuk, melynek első paramétere a fájlváltozó, második paramétere jelen esetben egy string. A példaprogram további részében hozzáfűzzük a fájlhoz a ’Helló, Web!’ szöveget az fputs() utasítással. Az fwrite() és az fputs() eredménye ugyanaz, az fputs() az fwrite() aliasa. 8.26 Fájlok feltöltése Fájl feltöltéséhez szükségünk lesz egy egyszerű űrlapra, és egy nem sokkal bonyolultabb PHP kódra: 01:

<html> 02: <head> 03: <title>Fájl feltöltése</title> 04: <meta http-equiv="Content-Type" content="text/html; charset=iso8859-2"> 05: </head> 06: <body> 07: <?php 08: $konyvtar="C:/munka/kepek"; 09: if(isset($uploadfile)) 10: /*ha kiválasztottuk a fájlt, akkor kiírjuk az adatait/ 11: { 12: print "Fájl: " . $uploadfile; 13: print "<br>Fájl neve: " . $uploadfile name; 14: print "<br>Fájl mérete: " . $uploadfile size; 15: print "<br>Fájl típusa: " . $uploadfile type; 16: } 17: else 18: { 19: print "<br>Adja meg a fájlt: "; 20: print "<form enctype="multipart/form-data"" 21: ." action=$PHP SELF method="post">" 22: ."<input type="hidden" name="MAX FILE SIZE"" 23: ." value="200000">" 24: ."<input type="file"

name="uploadfile" size="40">" 25: ."<br><input type="submit" value="Feltöltés"></form>"; 26: } 27: if(is uploaded file($uploadfile)) 28: /*ha a Feltöltés gombra rákattintottunk, akkor átmozgatjuk az ideiglenes könyvtárból a fájlt a célkönyvtárba*/ 29: { 30: if(move uploaded file($uploadfile,”$konyvtar/$uploadfile name”)) 31: { 32: print "<br><br>Fájl feltöltése sikerült."; 33: } 34: else 35: { 36: print "<br><br>Fájl feltöltése sikertelen."; 37: } 38: } 39: ?> 40: </body> 41: </html> Az űrlap megjelenítése hasonló elven történik, mint a számkitalálós játékban: ha nincs még kiválasztva a fájl, akkor meg kell jeleníteni az űrlapot (9. sor) Az űrlap a 20 sortól a 25. sorig tart, ahol láthatjuk, hogy a fájlátvitelhez a form enctype="multipart/form-data" sor szerepel a HTML részben, és a fájl

önmagára fog hivatkozni a $PHP SELF 63 változóval. A fájl feltöltéséhez szükséges űrlapelemet a 24 sorban találjuk, melynek neve uploadfile, így ebből a $uploadfile változó fog keletkezni. A maximális fájlméretet (MAX FILE SIZE) beállítjuk 200000 bájtra, és egy rejtett mező segítségével küldjük tovább (22-23. sor) Ha kiválasztottuk a fájlt, akkor a fájl jellemzőit megjelenítő rész fut le (12-15. sor) A 27 sortól már a záró lépések láthatók: a fájl a célszerver ideiglenes fájlokat tartalmazó könyvtárába került, és onnan el kell mozgatnunk a célkönyvtárba (30. sor). Ha ez sikerül, akkor készen vagyunk a feltöltéssel, ellenkező esetben valami hiba folytán vagy nem került a fájl az ideiglenes fájlokat tartalmazó könyvtárba (pl. túl nagy a fájl), vagy nem lehet onnan elmozgatni. 64 9 Adatbázisok: MySQL A PHP előnyei közé soroltuk, hogy rengeteg adatbázissal képes dolgozni. Az adatbázisokhoz való

csatlakozás, illetve azok kezelése a PHP-ben nagyon hasonló. A MySQL fejlesztői azt a célt tűzték ki, hogy egy praktikus, mindennapi használatra alkalmas adatbázist fejlesszenek, amely biztosítja a MySQL további sikerességét. Több érv is a MySQL adatbázis mellett szól:      Egyszerű és gyors. Nyílt forráskódú. A kicsi és közepes méretű honlapokhoz ideális. A legtöbb szolgáltató a PHP-MySQL párost szokta nyújtani. A phpMyAdmin Database Manager egy olyan felületet nyújt, amely segítségével könnyen kezelhetjük a MySQL adatbázisainkat. Természetesen nem azt állítjuk, hogy a MySQL a legjobb adatbázis. Az adott feladat dönti el, hogy milyen adatbázist célszerű választani. Csupán megjegyeztük, hogy egy közepes méretű honlaphoz tökéletes az egyszerűsége és gyorsasága miatt. 9.1 MySQL adattípusok Ha adatbázisokban akarunk adatokat tárolni, ugyanúgy figyelembe kell vennünk, hogy milyen adattípusokat

használhatunk. A következő táblázatok a különféle típusokat tartalmazzák: a) Egész számok Típus tinyint smallint mediumint int bigint decimal Hossz (bájt) 1 2 3 4 8 változó Értéktartomány -128.+127 -32768.+32767 -8388608.+8388607 -2147483648.+2147483647 17-től 18 számjegyig nincs korlátozva b) Lebegőpontos számok Típus float double Hossz (bájt) 4 8 Értéktartomány 6 tízes helyiérték 15 tízes helyiérték c) Sztringek Típus char varchar tinytext text longtext mediumtext Hossz (bájt) 1 1 1 2 3 4 Értéktartomány 1.255 1.255 1.255 1.65536 1.16777216 1.4294967295 65 d) Dátum is idő Típus date datetime timestamp time year Hossz (bájt) 3 8 4 3 1 Formátum éééé-hh-nn éééé-hh-nn óó:pp:mm ééééhhnnóóppmm óó:pp:mm éééé (1901-től 2125-ig) Egyéb típusok is találhatók a MySQL-ben, mint például az enum és a set, melyekről most nem esik szó. 9.2 Kapcsolódás a kiszolgálóhoz Miután telepítettük a MySQL-t

számítógépünkre, távoli vagy helyi gépek felhasználói bármikor csatlakozhatnak hozzá. A csatlakozáshoz természetesen felhasználónévre és jelszóra van szükség, és miután sikerült a csatlakozás sem biztos, hogy minden adatbázishoz hozzáférhetünk. A MySQL telepítés közben kér egy rendszergazda felhasználónevet és jelszót. A látogatókat azonban a későbbiekben nem célszerű a rendszergazda felhasználónévvel és jelszóval csatlakoztatni a MySQL-hez, mert a rendszergazdának teljes jogosultsága van. A MySQL sikeres telepítése után javasolt létrehozni egy olyan felhasználót, akinek csak a feltétlenül szükséges jogai vannak meg, majd ezzel csatlakoztatni az összes látogatót. A kapcsolódáshoz a mysql connect() függvényt használjuk, ami 3 paramétert vár: szervernév, felhasználónév, jelszó. Ha nem adunk meg szervernevet, úgy alapértelmezetten a localhost-ot használja. Az üresen hagyott felhasználónév helyére a

Web-szerverfolyamat tulajdonosának neve kerül, az üresen hagyott jelszó helyére pedig üres sztring. Ily módon el is lehet hagyni mindent, ha a MySQL a gépünkön fut, és a honlap az egyedüli honlap a gépen. Mi az összes példában megadjuk a paramétereket $kapcsolat=mysql connect("localhost","felhasznalo","jelszo"); if (!$kapcsolat) die("Nem lehet csatlakozni a MySQL kiszolgálóhoz!"); A $kapcsolat változóba mentjük a függvény által visszaadott azonosítót, hogy később folytathassuk munkánkat. Ha kapcsolat bontására a mysql close() függvény szolgál 9.3 Adatbázisok kiválasztása, listázása Az adatbázis kiválasztásához a mysql select db() utasítást használjuk: mysql select db("filmek",$kapcsolat) or die("Nem lehet megnyitni a filmek adatbázist: ".mysql error()); A függvény logikai értéket ad vissza, hamis logikai érték esetén ellenőriznünk kell, hogy létezik –e az

adatbázis, illetve, hogy van –e jogunk hozzá. A mysql error() függvény segítségével jeleníthetjük meg a hiba okát (a MySQL által legutoljára jelentett hibát adja vissza). A $kapcsolat paraméter elhagyható a legtöbb függvény esetében, az aktuális kapcsolat automatikusan behelyettesítődik. Az létező adatbázisok listázásához a mysql list dbs() függvényt használjuk, ami egy eredményazonosítóval tér vissza, melyet a mysql db name() függvénynek kell átadnunk, hogy az adatbázisok neveit megkapjuk. Az utóbbi függvény vár egy sorszámot is, ami az adatbázis sorszámát jelöli. A példa a létező adatbázisok neveit jeleníti meg: 66 01: <?php 02: $felhasznalo="latogato"; 03: $jelszo="valami"; 04: $kapcsolat=mysql connect("localhost",$felhasznalo,$jelszo); 05: if (!$kapcsolat) die("Nem lehet kapcsolódni a MySQL kiszolgálóhoz!"); 06: $adatbazisok=mysql list dbs(); 07: $adatbazisok szama=mysql num

rows($adatbazisok); 08: for ($i=0;$i<$adatbazisok szama;$i++) 09: print mysql db name($adatbazisok,$i)."<br>"; 10: mysql close(); 11: ?> A 7. sorban található mysql num rows() függvény adja meg az adatbázisok számát az eredményazonosító segítségével. Ez a függvény egy tábla sorainak számát adja meg, így a későbbiekben még használni fogjuk. Az előbbi feladatot megoldhattuk volna máshogy is. Ha ismerjük az adatbázisok kiíratásához szükséges SQL parancsot (SHOW DATABASES;), akkor ezt sztringként átadva a mysql query() függvénynek (az SQL utasítások végéről el kell hagynunk a pontosvesszőt), megkapjuk az adatbázisok neveit. A mysql query() függvény továbbítja az SQL-ben leírt utasításokat a kiszolgálóhoz. 01: <?php 02: $felhasznalo="latogato"; 03: $jelszo="valami"; 04: $kapcsolat=mysql connect("localhost",$felhasznalo,$jelszo); 05: if (!$kapcsolat) die("Nem lehet kapcsolódni a

MySQL kiszolgálóhoz!"); 06: $eredmeny=mysql query("SHOW DATABASES"); 07: while ($sor=mysql fetch row($eredmeny)) 08: print $sor[0]."<br>"; 09: mysql close(); 10: ?> A 6. sorban kiadtuk a parancsot a MySQL kiszolgálónak, a kapott eredmény egy tábla formájában a $eredmeny változóba került. A táblát soronként tudjuk olvasni az első sortól kezdődően. Egy sor kiolvasásához a mysql fetch row() függvény szükséges, amely a $sor tömbbe tölti a sorban található adatokat. Mivel minden sor csak egy adatot tartalmaz (az aktuális adatbázis nevét), így azt a $sor[0]-ban érjük el. A while ciklus addig fut, amíg a mysql fetch row() tud új sort olvasni, azaz amíg van sora a táblának. 9.4 Adatbázisok tábláinak listázása A táblanevek megjelenítéséhez használhatjuk a mysql list tables() PHP utasítást, vagy adhatunk ki SQL parancsot (SHOW TABLES FROM adatbazisnev;), mint ahogy azt az előbb tettük. A példaprogram

szerkezete nagyon hasonlít az előzőre: 01: <?php 02: $felhasznalo="latogato"; 03: $jelszo="valami"; 04: $kapcsolat=mysql connect("localhost",$felhasznalo,$jelszo); 05: if (!$kapcsolat) die("Nem lehet kapcsolódni a MySQL kiszolgálóhoz!"); 06: $adatbazis="stone"; 07: mysql select db($adatbazis,$kapcsolat) or 08: die("Nem lehet megnyitni a(z) $adatbazis adatbázist: ".mysql error()); 67 09: 10: 11: 13: 14: $tablak=mysql list tables($adatbazis,$kapcsolat); while ($sor=mysql fetch row($tablak)) print $sor[0]."<br>"; mysql close(); ?> 9.5 Táblák mezőinek listázása Az előbb eljutottunk odáig, hogy egy adatbázis tábláinak nevét meg tudtuk jeleníteni, most a táblák mezőinek nevére, és egyéb tulajdonságára vagyunk kíváncsiak. 01: <?php 02: $felhasznalo="latogato"; 03: $jelszo="valami"; 04: $kapcsolat=mysql connect("localhost",$felhasznalo,$jelszo);

05: if (!$kapcsolat) die("Nem lehet kapcsolódni a MySQL kiszolgálóhoz!"); 06: $adatbazis="stone"; 07: mysql select db($adatbazis,$kapcsolat) or 08: die("Nem lehet megnyitni a(z) $adatbazis adatbázist: ".mysql error()); 09: $tabla="hir"; 10: $mezok=mysql list fields($adatbazis,$tabla); 11: $mezok szama=mysql num fields($mezok); 12: print "<table border=1><tr><td>Mező</td><td>Típus</td> 13: <td>Hossz</td><td>Flag-ek</td></tr>"; 14: for ($i=0;$i<$mezok szama;$i++) 15: print "<tr><td>".mysql field name($mezok,$i)"</td> 16: <td>".mysql field type($mezok,$i)"</td> 17: <td>".mysql field len($mezok,$i)"</td> 18: <td>".mysql field flags($mezok,$i)"</td></tr>"; 19: print "<table>"; 20: mysql close(); 21: ?> A példa egy tábla mezőinek nevét,

típusát, hosszát, és flag-eit egy táblázatban jelenítette meg. A szükséges függvények nagyon hasonlítottak az előzőekre, csak a függvénynevekben a fields (mezők) szó szerepelt. 9.6 Táblák adatainak megjelenítése Az adatok lekérdezéséhez a SELECT * FROM tablanev; SQL parancsot használjuk a mysql query() függvényben: 01: <?php 02: $felhasznalo="latogato"; 03: $jelszo="valami"; 04: $kapcsolat=mysql connect("localhost",$felhasznalo,$jelszo); 05: if (!$kapcsolat) die("Nem lehet kapcsolódni a MySQL kiszolgálóhoz!"); 06: $adatbazis="stone"; 07: mysql select db($adatbazis,$kapcsolat) or 08: die("Nem lehet megnyitni a(z) $adatbazis adatbázist: ".mysql error());; 09: $tabla="hir"; 10: $mezok=mysql list fields($adatbazis,$tabla); 11: $mezok szama=mysql num fields($mezok); 12: $parancs="SELECT * FROM ".$tabla; 13: $eredmeny=mysql query($parancs); 14: print "<table

border=1><tr>"; 68 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: for ($i=0;$i<$mezok szama;$i++) print "<td>".mysql field name($mezok,$i)"</td>"; print "</tr>"; while ($sor=mysql fetch row($eredmeny)) { print "<tr>"; for ($i=0;$i<$mezok szama;$i++) print "<td>".$sor[$i]"</td>"; print "</tr>"; } print "<table>"; mysql close(); ?> 9.7 Adatbázis létrehozása és törlése Adatbázis létrehozásához használhatjuk a PHP mysql create db() utasítását, vagy kiadhatjuk a CREATE DATABASE parancsot a kiszolgálónak: 01: <?php 02: $felhasznalo="latogato"; 03: $jelszo="valami"; 04: $kapcsolat=mysql connect("localhost",$felhasznalo,$jelszo); 05: if (!$kapcsolat) die("Nem lehet kapcsolódni a MySQL kiszolgálóhoz!"); 06: $adatbazis="forum"; 07: if (mysql create db($adatbazis))

08: print "A(z) $adatbazis adatbázis sikeresen létrehozva."; 09: else 10: print "A(z) $adatbazis adatbázist nem sikerült létrehozni: ".mysql error(); 11: mysql close(); 12: ?> Adatbázis törléséhez a mysql drop db() függvényt használhatjuk a fentiekhez hasonló módon, vagy a DROP DATABASE parancsot adhatjuk ki. 9.8 Tábla létrehozása és törlése A táblák létrehozásához nincs külön PHP-függvény, itt mindenképpen az CREATE TABLE parancsot kell használnunk, miután kiválasztottuk a megfelelő adatbázist. 01: <?php 02: $felhasznalo="latogato"; 03: $jelszo="valami"; 04: $kapcsolat=mysql connect("localhost",$felhasznalo,$jelszo); 05: if (!$kapcsolat) die("Nem lehet kapcsolódni a MySQL kiszolgálóhoz!"); 06: $adatbazis="forum"; 07: mysql select db($adatbazis,$kapcsolat) or 08: die("Nem lehet megnyitni a(z) $adatbazis adatbázist: ".mysql error()); 09:

$tabla="forumuser"; 10: $parancs="CREATE TABLE ".$tabla"(nev VARCHAR (30),fnev VARCHAR (30) 11: NOT NULL PRIMARY KEY,jszo VARCHAR(50),email VARCHAR (40))"; 12: if (mysql query($parancs)) 13: print "A(z) $table tábla sikeresen létrehozva."; 14: else 69 15: print "A(z) $table táblát nem sikerült létrehozni: ".mysql error(); 16: mysql close(); 17: ?> A 10. sorban hoztunk létre egy forumuser nevű táblát 4 mezővel: nev, fnev, jszo, email Mindegyik mező változó hosszúságú szöveget tárolhat (rendre maximum 30, 30, 50, 40 karakterből állót), az fnev az elsődleges kulcs. Táblák törléséhez a DROP TABLE utasítást használjuk: $tabla="forumuser"; $parancs="DROP TABLE ".$tabla; if (mysql query($parancs)) print "A(z) $table tábla sikeresen törölve. "; else print "A(z) $table táblát nem sikerült törölni: ".mysql error(); 9.9 Adatok beszúrása Ha már sikerült

létrehoznunk egy adatbázist egy táblával, akkor adatokat helyezhetünk el a táblában. Ahhoz, hogy az adatokat felvegyük, egy újabb SQL parancsra lesz szükségünk, az INSERT-re. A példa az előbb létrehozott forum adatbázis forumuser táblájába szúr be egy sort, azaz egy felhasználó adatait rögzíti: 01: <?php 02: $felhasznalo="latogato"; 03: $jelszo="valami"; 04: $kapcsolat=mysql connect("localhost",$felhasznalo,$jelszo); 05: if (!$kapcsolat) die("Nem lehet kapcsolódni a MySQL kiszolgálóhoz!"); 06: mysql select db("forum",$kapcsolat) or 07: die("Nem lehet megnyitni a forum adatbázist: ".mysql error()); 08: $parancs="INSERT INTO forumuser(nev,fnev,jszo,email) 09: VALUES(Kiss Béla,bela,csigabiga,kissb@freemail.hu)"; 10: if (mysql query($parancs)) 11: print "Az adatok sikeresen be lettek szúrva az adatbázisba."; 12: else 13: print "Az adatokat nem lehet beszúrni: ".mysql

error(); 14: mysql close(); 15: ?> Egy honlap esetében az adatokat természetesen majd egy űrlap segítségével fogjuk bekérni a felhasználótól. Amikor azonban a felhasználó adja meg az adatokat, elkerülhetetlen az adatok ellenőrzése. 9.10 Adatok lekérdezése Miután rögzítettünk adatokat az adatbázisban, később vissza szeretnénk nyerni őket valamilyen formában. Egy tábla összes sorát már sikerült megjelenítenünk egy táblázatban, most egy olyan példa következik, amely eldönti, hogy van –e bela nevű felhasználó a forum adatbázis forumuser táblájában: 01: 02: 03: 04: <?php $felhasznalo="latogato"; $jelszo="valami"; $kapcsolat=mysql connect("localhost",$felhasznalo,$jelszo); 70 05: if (!$kapcsolat) die("Nem lehet kapcsolódni a MySQL kiszolgálóhoz!"); 06: mysql select db("forum",$kapcsolat) or 07: die("Nem lehet megnyitni a forum adatbázist: ".mysql error()); 08:

$parancs="SELECT * FROM forumuser WHERE fnev=bela"; 09: $eredmeny=mysql query($parancs) or 10: die("A parancsot nem lehet végrehajtani: ".mysql error()); 11: $sor=mysql fetch row($eredmeny); 12: if (isset($sor[0])) 13: print "Van bela nevű felhasználó."; 14: else 15: print "Nincs bela nevű felhasználó."; 16: mysql close(); 17: ?> A 9. sorban kiadtuk, azt az SQL parancsot, amely egy bela nevű felhasználó összes adatát (a SELECT-ben a *-ot használtuk) egy eredménytáblába tölti. A táblának egy sora van, ha létezik bela nevű felhasználó (mert az fnev elsődleges kulcs), és a táblának nincs egyetlen sora sem, ha nem létezik bela nevű felhasználó. Ezután a 11 sorban beolvastuk a $sor változóba a tábla első sorát. A 12 sorban azt döntöttük el, hogy került –e valami a $sor tömbbe. Az eredménytábla sorait a mysql fetch object() függvénnyel is olvashatjuk, ami egy objektumot ad vissza, így a mezőket csak

a nevük alapján lehet elérni (pl.: $sor->nev) Ha a mezőket indexük és nevük alapján is el szeretnénk érni, akkor a mysql fetch assoc() utasítást használjuk, ami egy asszociatív tömbbel tér vissza (ilyenkor írhatjuk: $sor[0] vagy $sor["nev"]). 9.11 Adatok frissítése Az adatok frissítéséhez az UPDATE parancsot kell átadnunk a mysql query() függvény segítségével a kiszolgálónak. A példában módosítjuk bela felhasználó jelszavát és e-mail címét: 01: <?php 02: $felhasznalo="latogato"; 03: $jelszo="valami"; 04: $kapcsolat=mysql connect("localhost",$felhasznalo,$jelszo); 05: if (!$kapcsolat) die("Nem lehet kapcsolódni a MySQL kiszolgálóhoz!"); 06: mysql select db("forum",$kapcsolat) or 07: die("Nem lehet megnyitni a forum adatbázist: ".mysql error()); 08: $parancs="UPDATE forumuser SET jszo=kisbeka, 09: email=kissb@hotmail.com WHERE fnev=bela"; 10: if (mysql

query($parancs)) 11: print "Az adatok sikeresen módosítva lettek."; 12: else 13: print "A parancsot nem lehet végrehajtani: ".mysql error(); 14: mysql close(); 15: ?> Ha elhagyjuk az UPDATE parancs WHERE záradékát, akkor a módosítás a tábla összes során végrehajtódik (jelen esetben az összes felhasználó jelszavát és e-mail címét módosítja), ha pedig a feltételt több sor is kielégíti, akkor azokon mind végrehajtódik. 71 9.12 Adatok törlése Gyakran előfordul, hogy az adatbázisban szereplő adatokat meg szeretnénk szűnteti. Ehhez is egy SQL utasítás szükséges: a DELETE. A következő példa törli a bela nevű felhasználót, azaz a forumuser tábla egy sorát: 01: <?php 02: $felhasznalo="latogato"; 03: $jelszo="valami"; 04: $kapcsolat=mysql connect("localhost",$felhasznalo,$jelszo); 05: if (!$kapcsolat) die("Nem lehet kapcsolódni a MySQL kiszolgálóhoz!"); 06: mysql select

db("forum",$kapcsolat) or 07: die("Nem lehet megnyitni a forum adatbázist: ".mysql error()); 08: $parancs="DELETE FROM forumuser WHERE fnev=bela"; 09: if (mysql query($parancs)) 10: print "Az adatok sikeresen törölve lettek."; 11: else 12: print "A parancsot nem lehet végrehajtani: ".mysql error(); 13: mysql close(); 14: ?> Erre a parancsra is igaz az, hogy ha elhagyjuk a WHERE záradékot, akkor minden sorra érvényes, azaz a tábla teljes tartalmát törli, egyébként csak azokat a sorokat, amelyek a WHERE utáni feltételt kielégítik. 9.13 Példa: a hírek modul Most egy olyan példát mutatunk be, amely segítségével egy honlapon mindig friss hírek jelennek meg. A regisztrált felhasználóknak biztosítunk egy űrlapot, amely segítségével elküldhetik a híreket, melyeket adatbázisban tárolunk. A híreket feladási idő szerint csökkenő sorrendbe rendezve kiolvassuk az adatbázisból, majd megjelenítjük az

oldalon. Így az oldal mindig friss lesz anélkül, hogy a honlap készítőjének hozzá kellene nyúlnia. A megoldáshoz szükség lesz egy adatbázisra és két táblára. Az egyik táblában a híreket tároljuk aszerint, hogy melyik felhasználó adta fel, milyen témában, milyen időpontban, és mi a hír szövege. A másik táblában tároljuk azokat a felhasználókat a nevükkel és jelszavukkal, akik hírt adhatnak fel. Nézzük meg először az adatbázist és a két táblát létrehozó kódot (abcreate.php): 01: <?php 02: $felhasznalo="latogato"; 03: $jelszo="valami"; 04: $kapcsolat=mysql connect("localhost",$felhasznalo,$jelszo); 05: if (!$kapcsolat) die("Nem lehet kapcsolódni a MySQL kiszolgálóhoz!"); 06: $parancs="CREATE DATABASE hir"; 07: if (!mysql query($parancs,$kapcsolat)) 08: print "Nem sikerült létrehozni a hir adatbázist: " 09: .mysql error()"<br>"; 10: else 11: print "A

hir adatbázis sikeresen létrehozva!<br>"; 12: mysql select db("hir",$kapcsolat) or die("Nem lehet megnyitni a(z) 13: $adatbazis adatbázist: ".mysql error()); 14: $parancs="CREATE TABLE hir(azon INT AUTO INCREMENT PRIMARY KEY, 15: felado VARCHAR(30),tema VARCHAR(40),datum DATETIME,szoveg TEXT)"; 16: if (!mysql query($parancs,$kapcsolat)) 72 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: print "Nem sikerült létrehozni a hir táblát: " .mysql error()"<br>"; else print "A hir tábla sikeresen létrehozva!<br>"; $parancs="CREATE TABLE hiruser(fnev VARCHAR(30) PRIMARY KEY, jszo VARCHAR(32))"; if (!mysql query($parancs,$kapcsolat)) print "Nem sikerült létrehozni a hiruser táblát: " .mysql error(); else print "A hiruser tábla sikeresen létrehozva!"; mysql close($kapcsolat); ?> Az adatbázis-szerverhez való csatlakozást és az adatbázis kiválasztását

egy külön fájlba tettük (adatbazis.php): 01: <?php 02: $felhasznalo="latogato"; 03: $jelszo="valami"; 04: $adatbazis="hir"; 05: $kapcsolat=mysql connect("localhost",$felhasznalo,$jelszo); 06: if (!$kapcsolat) die("Nem lehet kapcsolódni a MySQL kiszolgálóhoz!"); 07: mysql select db($adatbazis,$kapcsolat) or die("Nem lehet megnyitni 08: a(z) $adatbazis adatbázist: ".mysql error()); 09: ?> Az hirek.php fájl feladata, hogy kiolvassa az adatbázisból az öt legfrissebb hírt, majd megjelenítse a feladót, a témát, és a hír szövegét, valamint ezen az oldalon található link a hírfeladáshoz, illetve a korábbi hírek megtekintéséhez: 01: <?php 02: print "<center><h2>Hírek</h3>"; 03: include("adatbazis.php"); 04: $eredmeny=mysql query("SELECT felado,tema,datum,szoveg FROM hir 05: ORDER BY datum DESC"); 06: $i=0; 07: while ($i<5 && $hir=mysql

fetch row($eredmeny)) 08: { 09: $hir[3]=nl2br($hir[3]); //a sortörés-jeleket <br> tag-ekre cseréljük 10: print "<table border=1 width=400><tr><td><b>Feladó: </b>".$hir[0] 11: ."<br><b>Téma: </b>"$hir[1]"</td><td width=150 align=right>" 12: .$hir[2]"</td></tr></table><table border=1 width=400><tr><td>" 13: .$hir[3]"</td></tr></table><br>"; 14: $i++; 15: } 16: mysql close($kapcsolat); 17: print "<a href=khirek.php>Korábbi hírek</a><br> 18: <br><a href=login.htm>Hírfeladás</a></center>"; 19: ?> A korábbi hírek megjelenítése (khirek.php): 01: 02: 03: 04: 05: 06: 07: 08: <?php print "<center><h2>Korábbi hírek</h3>"; include("adatbazis.php"); $eredmeny=mysql query("SELECT felado,tema,datum,szoveg FROM

hir ORDER BY datum DESC"); $i=0; while ($i<5 && $hir=mysql fetch row($eredmeny)) $i++; while ($hir=mysql fetch row($eredmeny)) 73 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: { $hir[3]=nl2br($hir[3]); print "<table border=1 width=400><tr><td><b>Feladó: </b>".$hir[0] ."<br><b>Téma: </b>"$hir[1]"</td><td width=150 align=right>" .$hir[2]"</td></tr></table><table border=1 width=400><tr><td>" .$hir[3]"</td></tr></table><br>"; $i++; } mysql close($kapcsolat); print "<a href=login.htm>Hírfeladás</a><br> <br><a href=hirek.php>Vissza</a></center>"; ?> A bejelentkezéshez szükséges űrlap (login.htm): 01: <html> 02: <head> 03: <title>Bejelentkezés</title> 04: <meta http-equiv="Content-Type"

content="text/html; charset=iso8859-2"> 05: </head> 06: <body> 07: <form action="hurlap.php" method="post"> 08: <table> 09: <tr><td>Felhasználónév:</td><td> 10: <input name="fh" type="text"></td></tr> 11: <tr><td>Jelszó:</td><td> 12: <input name="jsz" type="password"></td></tr> 13: </table> 14: <input type="submit" name="Submit" value="Belépés"> 15: </form> 16: </body> 17: </html> A hírfeladáshoz szükséges űrlap (hurlap.php): 01: <html> 02: <head> 03: <title>Hír feltöltése</title> 04: <meta http-equiv="Content-Type" content="text/html; charset=iso8859-2"> 05: <form action="hfeld.php?felado=<?php print $fh ?>" method="post"> 06: <?php 07:

include("adatbazis.php"); 08: include("login.php"); 09: mysql close($kapcsolat); 10: print "Feladó: $fh<br>"; 11: ?> 12: Téma: <input name="tema" type="text"><br> 13: Hír:<br><textarea name="hir" cols="60" rows="10"></textarea><br> 14: <input type="submit" name="Submit" value="Feladás"> 15: </form> 16: </body> 17: </html> A későbbiekben szükségünk lesz a felhasználó nevére, mert az adatbázisba mentjük, így a következő oldalra továbbítjuk a $fh változó tartalmát, ahol majd felado néven érjük el (5. sor) A felhasználónév és a jelszó helyességét a loginphp fájl ellenőrzi (8 sor): 01: 02: 03: 04: <?php $eredmeny=mysql query("SELECT jszo FROM hiruser WHERE fnev=$fh"); $user=mysql fetch row($eredmeny); if ($user[0]!=md5($jsz)) 74 05: { 06: print "Nem

megfelelő felhasználónév/jelszó! 07: <br><a href=javascript:history.back()>Vissza</a>"; 08: die(); 09: } 10: ?> A hír feltöltését végző fájl (hfeld.php): 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: <?php if ($hir=="" || $tema=="") { print "Nem töltötte ki a szükséges mezőket! <br><a href=javascript:history.back()>Vissza</a>"; die(); } $datum=date("Y.md H:i:s"time()); include("adatbazis.php"); $parancs="INSERT INTO hir(felado,tema,datum,szoveg) VALUES($felado,$tema,$datum,$hir)"; if (!mysql query($parancs,$kapcsolat)) { print "Nem lehet az adatbázisba írni! <br><a href=javascript:history.back()>Vissza</a>"; } else { print "A hírfeladás sikeresen megtörtént! <br><a href=hirek.php>Hírek megtekintése</a>"; } mysql close($kapcsolat); ?> A hírek

feladására jogosult felhasználókat a honlap tulajdonosa hozza létre. Készíthetünk egy ilyen egyszerű kódot, amely létrehozza például a bela nevű felhasználót a csigabiga jelszóval (user.php): 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: <?php include("adatbazis.php"); $fnev="bela"; $jszo=md5("csigabiga"); //MD5 kódolást használunk $parancs="INSERT INTO hiruser(fnev,jszo) VALUES ($fnev,$jszo)"; if (!mysql query($parancs,$kapcsolat)) print "Nem sikerült létrehozni a felhasználót!"; else print "A felhasználó sikeresen létrehozva!"; mysql close($kapcsolat); ?> 75 10 Képek A honlapok sokszínűségét a képek nagyban biztosítják, így elvárjuk, hogy egy nyelv különböző formátumú képeket tudjon létrehozni és manipulálni. A PHP képes GIF, JPEG, PNG, WBMP, PDF és SWF kimenetet produkálni. Mindenképpen ajánlott, hogy a PHP dokumentációt tanulmányozzuk a képmanipuláló

függvények címszó alatt, mert néhány függvény eléréséhez tudnunk kell a PHP fordítási és egyéb beállításait. A következőkben a képek megjelenítéséről, majd a különböző formátumú képek létrehozásáról, manipulálásáról lesz szó. 10.1 Képek listázása Az első példaprogram megjeleníti egy könyvtárban található összes képet: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: <?php $kvtnev="C:/munka/kepek"; $kvt=opendir($kvtnev); while ($fajl=readdir($kvt)) { if (is file("$kvtnev/$fajl") && exif imagetype("$kvtnev/$fajl")) print "<p><img src=$kvtnev/$fajl border=0></p>"; } closedir($kvt); ?> A könyvtárat a $kvtnev változóba mentettük el (2. sor), majd a könyvtár tartalmát kilistáztuk egy while ciklus segítségével (4-8. sor) Ha a könyvtárból kiolvasott (és a $fajl változóba mentett) sztring egy fájlt jelent (6. sor), ami kép formátumú, akkor azt

megjelenítettük a böngészőben (7. sor) Az exif imagetype() függvény kiolvassa egy fájl fejlécét, és ez alapján eldönti, hogy kép formátumú –e (ha a fejléc egy lehetséges képformátumot jelent, a függvény az igaz logikai értékkel tér vissza). A második példaprogram egy könyvtárban található képek tulajdonságait (fájlnév, fájlméret, valamint szélesség, magasság képpontokban megadva) írja ki a böngészőbe: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: <?php $kvtnev="C:/munka/kepek"; $kvt=opendir($kvtnev); while ($fajl=readdir($kvt)) { if (is file("$kvtnev/$fajl") && exif imagetype("$kvtnev/$fajl")) { $file[]["Név"]=$fajl; $file[]["Fájlméret"]=filesize("$kvtnev/$fajl"); $size=getimagesize("$kvtnev/$fajl"); $file[]["Szélesség"]=$size[0]; $file[]["Magasság"]=$size[1]; } } closedir($kvt); foreach

($file as $info) { foreach ($info as $kulcs=>$ertek) { print $kulcs.": "$ertek"<br>"; } print "<br>"; 76 23: } 24: ?> A 8. sortól kezdődően látható, hogy egy kétdimenziós tömbben tároltuk képfájlokból nyert információkat. A kép méretét a már ismert filesize() függvénnyel kérdeztük le, míg a szélességét illetve magasságát a getimagesize() függvény segítségével tudtuk meg. A getimagesize() egy tömböt ad vissza, ahol a 0. indexnél a szélesség, az 1 indexnél pedig a magasság található. Végül bejártuk a kétdimenziós tömböt az ismert módon (16-23 sor). 10.2 Képek létrehozása A JPEG, GIF, PNG, WBMP formátumú képek létrehozásához és manipulálásához tartozó függvények mind az image szóval kezdődnek, míg a például ClibPDF és SWFhez tartozók cpdf és swf kezdetűek. A következőkben a fontosabb image-függvényekről lesz szó: Függvény imagearc() imagefilledarc()

imageellipse() imagefilledellipse() imagechar() imagecharup() imagestring() imagestringup() imagecolorallocate() imagecolordeallocate() imagecolorat() imagecolorclosest() imagecolorexact() imagegammacorrect() imagecolorset() imagecolortransparent() imagecolosforindex() imagecolorstotal() imagecopy() imagecopymerge() Leírás Ellipszis mentén vonalat rajzol. Ha a két paraméter, a magasság és a szélesség egyenlő, akkor körívet kapunk. Eredménye az előző függvényével megegyezik, majd az ív elejét a végével összekötve kitölthetjük a területet egy meghatározott színnel. Ellipszist rajzol, amennyiben a magasság egyenlő a szélességgel, kört kapunk. Ellipszist rajzol, és maghatározott színnel kitölti. Vízszintesen ír egy karaktert. Függőlegesen ír egy karaktert. Vízszintesen ír egy sztringet. Függőlegesen ír egy sztringet. Színt rendel egy képhez. Az első hozzárendelt színt a háttérre alkalmazza. Törli a színhozzárendelést, így újat

adhatunk meg. Adott pixelben levő szín kódját adja meg. RGB színkódot fogad el, és a legközelebb álló szín kódját adja vissza. RGB színt fogad el, és az adott szín kódját adja vissza, vagy -1-et, ha nem találja a színt. Gamma-korrekciót hajt végre egy képen. Színt állít be a skálán. Átlátszónak állít be egy színt (a GIF támogatja). A megadott szín piros, zöld és kék összetevőit egy tömbben adja vissza. A színskála színeinek számát adja vissza. Egy kép téglalap alakú részét egy célterületre másolja. Az előző függvényhez képest még megadható, hogy a másolt rész a célterületet milyen mértékben fedje. 77 imagecopyresized() imagecopyresampled() imagecreate() imagecreatetruecolor() imagetruecolortopalette() imagecreatefromgif() imagecreatefromjpeg() imagecreatefrompng() imagecreatefromwbmp() imagegif() imagejpeg() imagepng() imagewbmp() imagedestroy() imagecreatefromstring() imagesetpixel() imageline() imagedashedline()

imagerectangle() imagefilledrectangle() imagepolygon() imagefilledpolygon() imagesetbrush() imagesetthickness() imagefontheight() imagesfontwidth() imagettftext() imagettfbbox() imagefill() imagefilltoborder() imageinterlace() imagesx() imagesy() Működése hasonló az imagecopy()-hoz, de átméretezi a képet, ha a célterület és a másolt rész nem azonos méretű. Működése hasonló az imagecopyresized()-hoz, de újra-mintavételezi a képet. Színskála alapú képet (palettaképet) hoz létre (8 bites szín). True color színmélységű képet hoz létre (24 bites). True color képet palettaképre konvertál. GIF fájlból vagy URL-ből hoz létre képet. JPEG fájlból vagy URL-ből hoz létre képet. PNG fájlból vagy URL-ből hoz létre képet. WBMP (Windows Bitmap) fájlból vagy URL-ből hoz létre képet. Elküldi a képet a böngészőnek, vagy GIF formátumban fájlba menti. Elküldi a képet a böngészőnek, vagy JPEG formátumban fájlba menti. Elküldi a képet

a böngészőnek, vagy PNG formátumban fájlba menti. Elküldi a képet a böngészőnek, vagy WBMP formátumban fájlba menti. Eltávolítja a képet a memóriából. Képet hoz létre egy sztringben tárolt képről. Pontot rajzol. Egyenest rajzol két pont között. Szaggatott vonalat rajzol. Télalapot rajzol két sarokpont közé (bal felső és jobb alsó). Kitöltött télalapot rajzol. Sokszöget rajzol egy tömbben meghatározott pontok alapján. Kitöltött sokszöget rajzol. Ecset választása a vonalakhoz. Vonalvastagság meghatározása. Egy betűtípus magasságát adja vissza. Egy betűtípus szélességét adja vissza. TrueType betűtípussal ír szöveget. Az imagettftext()-tel írt szöveget határoló téglalap méretét adja vissza. Az egész képet egy színnel tölti ki. Meghatározott színnel tölt ki egy képet a szín által meghatározott keretig. Megadja, hogy az interlace-opció be van –e kapcsolva a képen, illetve segítségével be- vagy

kikapcsolhatjuk. A kép szélességét adja vissza. A kép magasságát adja vissza. 78 imagetypes() A PHP által támogatott képformátumok listáját adja vissza. Most pedig nézzünk meg egy példát néhány image-függvény használatára: 01: <?php 02: $image["Nev"]="celtabla.png"; 03: $image["Utvonal"]=$image["Nev"]; 04: $image["Kep"]=imagecreate(400,400); //a képváltozó létrehozása 05: $feher=imagecolorallocate($image["Kep"],0xff,0xff,0xff); 06: $fekete=imagecolorallocate($image["Kep"],0,0,0); 07: $voros=imagecolorallocate($image["Kep"],0xff,0,0); 08: imagerectangle($image["Kep"],0,0,399,399,$fekete); 09: imagerectangle($image["Kep"],1,1,398,398,$fekete); 10: imagerectangle($image["Kep"],2,2,397,397,$fekete); 11: imagerectangle($image["Kep"],3,3,396,396,$fekete); 12: imagerectangle($image["Kep"],4,4,395,395,$fekete); 13:

imagefilledellipse($image["Kep"],200,200,300,300,$fekete); 14: imagefilledellipse($image["Kep"],200,200,200,200,$feher); 15: imagefilledellipse($image["Kep"],200,200,100,100,$fekete); 16: $nyil=array(202,200,268,144,268,171,379,171,379,229,268,229,268,256); 17: imagefilledpolygon($image["Kep"],$nyil,7,$voros); 18: $betutipus="C:/Windows/Fonts/arial.ttf"; 19: $betumeret=20; 20: $szoveg="Ide célozzon!"; 21: $doboz=imagettfbbox($betumeret,0,$betutipus,$szoveg); 22: $hely=(400-$doboz[2])/2; //középre igazítjuk a szöveget 23: imagettftext($image["Kep"],20,0,$hely,35,$voros,$betutipus,$szoveg); 24: imagepng($image["Kep"],$image["Utvonal"]); //létrehozzuk a png fájlt 25: imagedestroy($image["Kep"]); 26: print "<img src=$image[Nev]>"; //megjelenítjük a fájlt a böngészőben 27: ?> 10.3 Képek változtatása Ide sorolhatjuk a képek színeit és méretét

változtató függvényeket. Érdemes végiggondolnunk, mikor melyik képformátumot célszerű használni. A GIF 8 bites színt (256 különböző szín), a JPEG 24 bites színt használ. A GIF és a PNG pontos színeket tárol, a JPEG viszont egy közelítést tárol, amely egyre pontatlanabb lesz, ha növeljük a tömörítést. Ha az imagejpeg()-et használjuk, és a minőségi paramétert (alapértelmezett érték a 100) 100-nál kisebbre állítjuk, veszítünk a színhelyességből. A képek átméretezésénél a nehézséget az optimális kép előállítása jelenti. A pixeles átméretezés az éles vízszintes és függőleges vonalak esetében működik, ahol az új méret az eredetinek páros töredéke. Egyéb technikák az átlós vonalakat és színárnyalatokat részesítik előnyben. Kicsinyítés után az eredeti méretre nagyítva a képet, könnyű észrevenni, hogy az eredeti kép tiszta, éles, egyenes vonalai egyenetlen görbékbe mennek át. A PHP képek

átméretezésére használható függvénye az imagecopyresized() Az újramintavételezés segít az egyenetlenség eltűntetésében, viszont elmosódottá teszi a képet Az imagecopyresampled() függvény szolgál a PHP-ben a képek újbóli mintavételezéssel történő átméretezésére. A lenti példaprogram a felhasználó által feltöltött kép kicsinyített mását készíti el, melyet megjelenít az oldalon, és elkészíti az eredeti képre való hivatkozást. 79 Az űrlap-fájl (kep.php): 01: <html> 02: <head> 03: <title>Kép feltöltése</title> 04: <meta http-equiv="Content-Type" content="text/html; charset=iso8859-2"> 05: </head> 06: <body> 07: <?php 08: $konyvtar="C:/kepek"; 09: $kvt=opendir("$konyvtar/kicsi"); 10: $fajl=readdir($kvt); 11: $fajl=readdir($kvt); 12: while ($fajl=readdir($kvt)) 13: { 14: print "<a href=$konyvtar/nagy/$fajl target= blank> 15: <img

src=$konyvtar/kicsi/$fajl border=0></a><br>"; 16: } 17: closedir($kvt); 18: ?> 19: <form enctype="multipart/form-data" action="kepf.php" method="POST"> 20: Válassza ki a képet:<br> 21: <input type="file" name="fajl"><br> 22: <input type="hidden" name="MAX FILE SIZE" value="200000"><br> 23: <input type="submit" value="Feltöltés"> 24: </form> 25: </body> 26: </html> A feldolgozást végző fájl (kepf.php): 01: 02: 03: 04: 05: 06: 07: 08: <?php $feltoltes konyvtar="C:/kepek"; if ($fajl type=="image/gif" || $fajl type=="image/pjpeg") { move uploaded file($fajl,"$feltoltes konyvtar/nagy/$fajl name") or die("Nem lehet mozgatni!"); if ($fajl type=="image/gif") 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: }

$im=imagecreatefromgif("$feltoltes konyvtar/nagy/$fajl name"); else $im=imagecreatefromjpeg("$feltoltes konyvtar/nagy/$fajl name"); $size=getimagesize("$feltoltes konyvtar/nagy/$fajl name"); if ($size[0]>100) { $h=$size[0]/100; $image=imagecreatetruecolor(100,$size[1]/$h); imagecopyresized($image,$im,0,0,0,0,100,$size[1]/$h, $size[0],$size[1]); } else { $image=imagecreatetruecolor($size[0],$size[1]); imagecopy($image,$im,0,0,0,0,$size[0],$size[1]); } imageJPEG($image,"$feltoltes konyvtar/kicsi/$fajl name",255); print "A kép feltöltése sikeresen megtörtént."; print "<br><a href=kep.php>Vissza</a>"; 80 28: 29: 30: 31: 32: 33: else { print "Nem GIF vagy JPEG formátumú fájlt adott meg!"; print "<br><a href=kep.php>Vissza</a>"; } ?> Miután sikeresen feltöltöttük a képfájlt (5. sor), eldöntöttük, hogy GIF vagy JPEG típusú képet adott meg a

felhasználó (7. sor), majd ennek megfelelően hoztuk létre a $im képváltozót (8. és 9 sor) Lekérdeztük az eredeti kép méretét, és ha a kép szélesebb volt, mint 100 képpont, kicsinyítést hajtottunk végre, így egy pontosan 100 képpont széles 24 bites képterületet ($image) készítettünk (15. sor) A kapott területre lekicsinyítettük a $im változóban található teljes képet az imagecopyresized() függvénnyel (16. sor) Ha nem volt szükség a kicsinyítésre, az eredeti képpel megegyező méretű képterületet készítettünk (21. sor), majd oda átmásoltuk az eredeti képet Végül JPEG formátumban mentettük a képet (25. sor) 81 11 Session-ök A HTTP állapot nélküli protokoll. Ez azt jelenti, hogy ahány oldalt a felhasználó letölt kiszolgálóról, annyi önálló kapcsolat létesül, ráadásul az egyes oldalakon belül a képek, külső fájlok letöltésére is külön kapcsolatok nyílnak. A felhasználók és a készítők viszont

környezetként kezelnek egy weboldalt, amelyben egyetlen oldal is része egy nagyobb egésznek. Hogyan továbbíthatjuk tehát adatainkat oldalról oldalra, azaz hogyan valósíthatjuk meg az információtárolást? Több megoldás is rendelkezésünkre áll, melyek közül egyet már ismerünk: a GET típusú lekérdezést. A kifinomultabb lehetőségeknél említhetjük meg a cookie-k (sütik) és a session-ök használatát. A cookie-ban kis mennyiségű adatot tárol a felhasználó böngészője egy kiszolgáló vagy egy program kérésének eleget téve. Minden cookie egy nevet, egy értéket, a lejárati időpontot, a kiszolgálóra és elérési útra vonatkozó információkat tartalmazza. Vegyünk példának egy bevásárlókosár-szoftvert, amely a bevásárlólistát cookie-ban tárolja. Lesz olyan felhasználó, aki megváltoztatja a termékek árait a cookie-ban, lesz olyan, aki a kosara felét elhagyja, mert a cookie túllépi a böngészőjében beállított 4 KB-os

maximális méretet. Olyan felhasználók is lesznek, akik egyáltalán nem tudnak vásárolni, mert letiltották a cookie-kat. Ha cookie-kat használunk, nem bízhatunk meg abban, ami a cookie-ban van. A session-ök egy azonosítót adnak a böngészőnek és a kiszolgálónak, hogy egy oldal lekérését ugyanabban a session-ben történt többi lekéréshez kapcsolják. A session a honlap tulajdonosának és látogatójának is rengeteg hasznot nyújt. A tulajdonos - az előző példánál maradva - megnézheti a látogatók által keresett termékeket, így tudja mivel célszerű oldalát frissíteni, valamint megtudhatja, hogy ki mit vásárolt. A látogató pedig be tud jelentkezni, automatikusan a testre szabott profilját használhatja. A sessionazonosítót szokták cookie-ban tárolni, de a session-ökhöz nem feltétlen kell cookie, és az azonosítón kívül semmit nem tárolnak benne. Ha a session-azonosítót cookie-ban tároljuk, mindig meg kell győződnünk arról,

hogy valódi –e. A cookie-k segítségével távol tarthatjuk a zavaros session-azonosító sztringeket az URL-ektől, így a látogató felveheti az oldalt a kedvencek közé anélkül, hogy a session-azonosító is belekerülne. Amikor egy látogató a honlapunkon a következő oldalra megy, keresnünk kell a bejövő cookie-t annak a megállapítására, hogy a böngészője be van –e állítva a cookie-k fogadására. Ha a látogató kikapcsolta a cookie-kat, az URL-es megoldást használjuk 11.1 PHP-szolgáltatások A PHP-ben vannak beépített session-kezelő szolgáltatások, melyek beállításait a php.ini fájl tartalmazza Ezek a szolgáltatások a legtöbb esetben működnek, ha azonban jobban akarjuk kontrollálni a session-öket, kikapcsolhatjuk őket. A következő táblázatban néhány ilyen szolgáltatás szerepel: Szolgáltatás session.save handler=files session.save path=/tmp session.use cookies=1 session.name=phpsessid Leírás Alapértelmezésben fájlban

tárolja a sessionöket, az adatbázisban való tároláshoz a files-t user-re kell megváltoztatni. Meghatározza, hogy a PHP hova írja a sessionfájlokat. Bekapcsolja/kikapcsolja a cookie-kat. Az 1 a bekapcsolt, a 0 a kikapcsolt állapot. A cookie nevét adja. 82 session.auto start=0 Bekapcsolja/kikapcsolja a session-ök automatikus elindítását. session.cookie lifetime=0 A cookie-k élettertamát határozza meg. Alapesetben addig futtatja a session-öket, amíg a böngésző aktív. session.cookie path=/ Meghatározza, hogy a PHP hova írja a cookiekat. session.gc probability=1 A PHP session-hulladékgyűjtőjét állítja be. Akárhányszor egy oldalkérés PHP sessionkezelő rutint indít el, a PHP ellenőrzi, hogy szükség van –e hulladékgyűjtésre. Az 1-es érték jelentése, hogy a hulladékgyűjtő 100 oldalanként egyszer fusson. session.gc maxlifetime=1440 Meghatározza, hogy a session-rekord az utolsó használat után hány másodpercig érhető el. Az

alapértelmezés 1440 másodperc, azaz 24 perc. session.referer check= Korlátozza a felhasználókat bizonyos oldalak elérésében, ám az ellenőrzés nem igazán megbízható, mert az sem, hogy ki látogatja az oldalt. session.entropy file= Meghatároz egy külső fájlt, amely további adatokat biztosít a session-azonosító generáló rutinnak. session.entropy length=0 A külső fájlból beolvasott bájtok számát határozza meg, így a 0 letiltja a külső fájlból való beolvasát. url rewriter.tags="a=href,area= Meghatározza, hogy melyik HTML tag kapja a href,frame=src,input=src,form= session-azonosítót, amelyikben a cookie ki van fakeentry" kapcsolva. 11.2 Session-függvények A session-függvényekkel (munkamenet függvényekkel) manuálisan lehet szabályozni a session-öket, így a php.ini beállításait is A következő táblázat a fontosabb függvényeket tartalmazza: Függvény session decode() session destroy() session encode() session get cookie

params() session id() session is registered() Leírás A session-rekord manuális kikódolására szolgál. Eltávolítja az adott session-höz kapcsolódó összes adatot. A regisztrált változókat a PHP-nek megfelelő módon kódolja. Visszaadja a session cookie paramétereit egy asszociatív tömbben (lifetime, domain, path, secure). Az aktuális session-azonosítót adja vissza, és újat állít be. A sztringként megadott változónévre igazat 83 session module name() session name() session register() session save path() session set cookie params() session set save handler() session start() session unregister() session unset() ad, ha a változó regisztrálva van a session-ben, hamisat, ha nem. Megadja, hogy a session.save handler files-ra vagy user-re van –e állítva, illetve újat állít be. A session.name által megadott session-nevet adja vissza, és újat állít be. A session-rekordban elmentésre kerülő változókat regisztrálja, melyeket sztringként

kell megadni. Ha nem futattjuk a session start()-ot, akkor a session register() indítja el a session-t. A session-fájlok tárolásánál használt elérési utat adja vissza, illetve újat állít be. Session cookie-t állít be. Adott könyvtárhoz adott cookie-kat állít be, és felülír cookie paramétereket. Az összes - általunk megírt - session-rekord kezelő függvény nevét fogadja el, és regisztrálja őket a kódban való használathoz, így a PHP ezeket használja majd a sessionkezelésre. Ha a sessionsave handler user-re van állítva, azaz adatbázisba mentünk, akkor a session-rekord kezelő függvényeket manuálisan kell definiálni. Elindít vagy folytat egy session-t. Eltávolítja a regisztrációs lista egy változóját. Minden regisztrált válozót megszűntet. Megegyezik az session unregister() lefutattásával az összes regisztrált változón. 11.3 Session indítása A session-öket mindig manuálisan kell elindítanunk a session start()

függvénnyel (vagy a session register()-rel) kivéve, ha a php.ini fájlban a sessionauto start-ot 1-re állítottuk. A munkamenet elindítása után a session id() függvénnyel lekérdezhetjük a generált session-azonosítót, és akár újat is megadhatunk. Keressük meg a session mentési könyvtárat (session.save path), és figyeljük meg, hogy minden session egy session-fájl formájában található meg. A fájlok neve a sess karakterekkel kezdődik, a fájlnév további része a session-azonosító: sess 11e4ac4f039606c194375fd192ca9685 11.4 Változók regisztrálása A változók munkamenetbe való regisztrálásához a session register() PHP-függvényt használjuk: $szemely="Kiss Pista"; $kor=28; session register("szemely","kor"); A regisztrálás a session register() használatakor történik, de a változók ténylegesen akkor lesznek a session-rekordba írva, amikor a szkript végére érünk. A szkript végén a 84 változóknak

létezniük kell azzal az értékkel, amit el akarunk menteni. Ezután a sessionrekord minden változója a memóriába kerül, regisztrálva lesz A változókat nem kell minden szkriptben regisztrálni, amíg a session tart, a változók regisztrálva maradnak. A változók eléréséhez azonban minden oldalnál meg kell hívnunk a session start() függvényt. Ha regisztráltunk már változókat, érdemes megtekinteni, hogy a PHP hogyan tárolja a session-rekordot a session-fájlban: szemely|s:10:"Kiss Pista";kor|i:28; A változó neve után | jel, majd a típusa következik. Az i az egész, a d a valós, a b a logikai, az s a sztring, az a a tömb, az o pedig az objektum. A : jel jelzi, hogy attribútum következik. A sztringnél az első attribútum a hossz, a második az érték, az egésznél az egyetlen attribútum az érték. A tömböknél a {} jelek a tömbön belüli elemek definiálására szolgálnak. Ha egy változó neve előtt a ! szerepel és nincsenek

attribútumai, az azt jelenti, hogy a változónak nincsen értéke. Ha ellenőrizni szeretnénk, hogy egy változó regisztrálva van –e a munkamenetben, a session is registered() függvénnyel tehetjük meg: if (session is registered("szemely")) print "A személy be van jegyezve."; else print "A személy nincs bejegyezve."; 11.5 A regisztrált változók és a session megszűntetése A session megszűntetésére a session destroy() függvény alkalmas. Ez a függvény a munkamenethez tartozó minden adatot töröl, azaz törli a session-fájlt, de nem törli a globális változókat és a session cookie-t. Ha kiadjuk a session destroy() parancsot, utána még elérhetők a regisztrált változók, amíg a böngésző fut, hiszen azok a memóriában vannak. A session unregister() PHP-függvény törli a paraméterként megadott változókat a session-ből. Törléshez használhatjuk a session unset() parancsot is, amely minden bejegyzett

munkamenet-változót felszabadít. Az összes említett függvényre igaz, hogy nem törli a megfelelő globális változókat, így azokat az unset() fügvénnyel szűntethetjük meg. 11.6 Session-függvények használata A lenti példaprogram az alapvető session-függvények használatát mutatja be. A session.php fájlban regisztrált asszociatív tömböt a sessionfphp fájlban próbáljuk meg elérni és tartalmát kiíratni. A session.php fájl: 01: <?php 02: session start(); //session indítása 03: print "Session elindítva.<br>Session azanosító: ".session id()"<br>"; 04: $szemely=array("Név"=>"István","Születési idő"=>"1956.1003", 05: "Születési hely"=>"Keszthely"); 06: session register("szemely"); 07: //a szemely változó regisztrálása a session-be 08: print "<br>Adatok:<br>"; 09: foreach($szemely as $kulcs=>$ertek) 10: {

11: print $kulcs.": "$ertek"<br>"; 12: } 85 13: 14: 15: 16: 17: 18: $kodolt=session encode(); /*a regisztrált változók kódolása a PHP-nak megfelelő módon, az eredmény a $kodolt változóba kerül*/ print "<br>Kódolva: ".$kodolt"<br><br> <a href=sessionf.php>Tovább</a>"; ?> A sessionf.php fájl: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: <?php session start(); if (session is registered("szemely")) print "A szemely változó regisztrált!<br>"; session decode($szemely); //a session-rekord-információk kikódolása print "<br>Az adatok:<br>"; foreach($szemely as $kulcs=>$ertek) { print $kulcs.": "$ertek"<br>"; } session unset(); // a regisztrált változók megszűntetése if (!session destroy()) print "<br>A session-t nem sikerült megszűntetni!"; else print

"<br>A session sikeresen megszűntetve!"; //a session-höz tartozó adatok eltávolítása ?> 11.7 Példa: a fórum modul A következőkben egy egyszerű fórum-szoftvert mutatunk be. A fórum hozzászólásait bármely látogató megtekintheti témák szerint csoportosítva, hozzászólás feladásához viszont regisztrálnia kell magát. Egy témán belüli hozzászólások ötösével jelennek meg egy oldalon, így biztosítunk gombokat a további és korábbi hozzászólások eléréséhez. Mivel egy regisztrált felhasználó általában több témához is hozzá szeretne szólni, nem lenne jó megoldás, ha minden egyes hozzászólás előtt be kellene jelentkeznie. A fórum nyitóoldalán minden regisztrált felhasználó bejelentkezhet, bejelentkezés után pedig szabadon küldheti hozzászólásait bármelyik témában, vagy hozhat létre új témát mindaddig, amíg a kijelentkezés gombra nem kattint, vagy be nem zárja a böngészőt. Egy új látogató

regisztrálásához, vagy egy regisztrált felhasználó adatainak módosításához lehetőséget szintén a nyitóoldalon biztosítunk. A fórum több fájlból áll össze, ezeket mutatjuk be sorban: A szükséges adatbázis és táblák létrehozása (abcreate.php): 01: <?php 02: $felhasznalo="latogato"; 03: $jelszo="valami"; 04: $kapcsolat=mysql connect("localhost",$felhasznalo,$jelszo); 05: if (!$kapcsolat) die("Nem lehet kapcsolódni a MySQL kiszolgálóhoz!"); 06: $parancs="CREATE DATABASE forum"; 07: if (!mysql query($parancs,$kapcsolat)) 08: print "Nem sikerült létrehozni a forum adatbázist: " 09: .mysql error()"<br>"; 10: else 11: print "A forum adatbázis sikeresen létrehozva!<br>"; 12: mysql select db("forum",$kapcsolat) or die("Nem lehet megnyitni 13: a(z) $adatbazis adatbázist: ".mysql error()); 14: $parancs="CREATE TABLE forum(azon INT AUTO

INCREMENT PRIMARY KEY, 15: felado VARCHAR(30),temaazon INT,datum DATETIME,szoveg TEXT)"; 16: if (!mysql query($parancs,$kapcsolat)) 86 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: print "Nem sikerült létrehozni a forum táblát: " .mysql error()"<br>"; else print "A forum tábla sikeresen létrehozva!<br>"; $parancs="CREATE TABLE forumtema(azon INT AUTO INCREMENT PRIMARY KEY,tema VARCHAR(40),datum DATETIME)"; if (!mysql query($parancs,$kapcsolat)) print "Nem sikerült létrehozni a forumtema táblát: " .mysql error()"<br>"; else print "A forumtema tábla sikeresen létrehozva!<br>"; $parancs="CREATE TABLE forumuser(nev VARCHAR (30),fnev VARCHAR (30) PRIMARY KEY,jszo VARCHAR(32),email VARCHAR (40))"; if (!mysql query($parancs,$kapcsolat)) print "Nem sikerült létrehozni a forumuser táblát: " .mysql error(); else print

"A forumuser tábla sikeresen létrehozva!"; mysql close($kapcsolat); ?> Az adatbazis.php fájl: 01: <?php 02: $felhasznalo="latogato"; 03: $jelszo="valami"; 04: $adatbazis="forum"; 05: $kapcsolat=mysql connect("localhost",$felhasznalo,$jelszo); 06: if (!$kapcsolat) die("Nem lehet kapcsolódni a MySQL kiszolgálóhoz!"); 07: mysql select db($adatbazis,$kapcsolat) or die("Nem lehet megnyitni 08: a(z) $adatbazis adatbázist: ".mysql error()); 09: ?> A fórum nyitóoldala (forum.php): 01: <html> 02: <head> 03: <title>Fórum</title> 04: <meta http-equiv="Content-Type" content="text/html; charset=iso8859-2"> 05: </head> 06: <body> 07: <center> 08: <h2>Fórum</h2> 09: <?php 10: session start(); //a session indítása 11: if (isset($name) && isset($pass)) 12: //ha kitöltötte a nevet és a jelszót 13: { 14: $van=false;

15: include("adatbazis.php"); 16: $eredmeny=mysql query("SELECT jszo FROM forumuser WHERE fnev=$name"); 17: $user=mysql fetch row($eredmeny); 18: mysql close($kapcsolat); 19: if ($user[0]==md5($pass)) //ha a név és a jelszó is megfelelő 20: session register("name"); //felvesszük a nevet a session-be 21: } 22: if (session is registered("name")) 23: //ha a név regisztrálva van a session-ben 24: { 25: $van=true; 87 26: print "<form method=post action=flogout.php> 27: <table width=300 border=1><td align=center><b>Bejelentkezve</b> 28: </td></tr><table><table width=300 border=1><tr><td width=150> 29: Felhasználónév:</td><td width=150>".$name"</td></tr> 30: </table><p><input type=submit name=Submit value=Kilépés> 31: </p></form>"; 32: } 33: else //ha a név nincs regisztrálva a session-ben 34: {

35: if (isset($van)) //ha nem megfelelőt adott 36: print "Nem megfelelő felhasználónév/jelszó!<p>"; 37: print "<form method=post action=$PHP SELF> 38: <table width=300 border=1><td align=center><b>Bejelentkezés</b> 39: </td></tr></table><table width=300 border=1><tr><td width=140> 40: Felhasználónév:</td><td width=160><input name=name type=text> 41: </td></tr><td width=140>Jelszó:</td><td width=160> 42: <input name=pass type=password></td></tr></table><p> 43: <input type=submit name=Submit value=Belépés></p></form>"; 44: } 45: print "</form>Témák:<br>"; 46: include("adatbazis.php"); 47: $eredmeny=mysql query("SELECT azon,tema,datum FROM forumtema ORDER BY datum DESC"); 48: while ($t=mysql fetch row($eredmeny)) //témák megjelenítése 49: { 50:

print "<table width=500 border=1><tr><td width=240> 51: <a href=flista.php?azon=$t[0]>$t[1]</a></td><td width=260 align=right> 52: Utolsó bejegyzés: "; 53: if (isset($t[2])) print $t[2]; 54: else print "nincs"; 55: print "</td></tr></table>"; 56: } 57: mysql close($kapcsolat); 58: ?> 59: <form action="turlap.php" method="post"> 60: <input type="submit" name="Submit" value="Új téma létrehozása"> 61: </form> 62: <?php 63: if ($van) print "<a href=furlapum.htm>Adatmódosítás</a></p>"; 64: else print "<a href=furlapu.htm>Regisztráció</a></p>"; 65: ?> 66: </center> 67: </body> 68: </html> A kiválasztott témában található hozzászólások megjelenítése (flista.php): 01: <html> 02: <head> 03: <title>Fórum</title>

04: <meta http-equiv="Content-Type" content="text/html; charset=iso8859-2"> 05: </head> 06: <body> 07: <center><h2>Hozzászólások</h2> 08: <?php 09: session start(); 10: if (!isset($db)) 11: /*ha nem tudjuk hány hozzászólás van a témában 12: (most lépett be a látogató téma hozzászólásaiba)*/ 88 13: { 14: session unregister("hozzaszolas"); 15: /*kivesszük a session-ből a hozzászólások tömböt, mert lehet, 16: hogy egy másik téma hozzászólásai vannak benne*/ 17: unset($hozzaszolas); 18: /*megszűntetjük magát a változót is, nehogy hozzáfűzze 19: az új hozzászólásokat*/ 20: include("adatbazis.php"); 21: $eredmeny=mysql query("SELECT azon,tema FROM forumtema WHERE azon=$azon"); 22: $tema=mysql fetch row($eredmeny); 23: $eredmeny=mysql query("SELECT felado,temaazon,datum,szoveg FROM forum 24: WHERE temaazon=$tema[0] ORDER BY datum DESC"); 25: for

($i=0;$hozzaszolas[$i]=mysql fetch row($eredmeny);$i++) 26: $hozzaszolas[$i][3]=nl2br($hozzaszolas[$i][3]); 27: //az összes témabeli hozzászólás beírása a hozzaszolas tömbbe 28: $db=mysql num rows($eredmeny); //a hozzászólások száma 29: mysql close($kapcsolat); 30: session register("tema"); 31: /*a témaazonosító regisztrálása, hogy később hozzászólást tudjuk 32: létrehozni a témában*/ 33: session register("hozzaszolas"); 34: //a hozzaszolas tömb regisztrálása 35: } 36: print "<< <b>$tema[1]</b> téma >><br><br>"; 37: if ($db==0) print "Nincs hozzászólás a témában<br>"; 38: if (!isset($szam)) $szam=0; 39: $i=$szam; 40: while ($szam<$i+5 && $hozzaszolas[$szam]!="") 41: //5 db hozzászólás megjelenítése 42: { 43: print "<table width=500 border=1><tr><td width=350><b>Feladó:</b>" 44:

.$hozzaszolas[$szam][0]"</td><td width=150 align=right>" 45: .$hozzaszolas[$szam][2]"</td></tr></table><table width=500 border=1> 46: <tr><td>".$hozzaszolas[$szam][3]"<br></td></tr></table><br>"; 47: $szam++; 48: } 49: ?> 50: </p> 51: <table width="500" border="0"><tr><td> 52: <?php 53: if ($szam>5) //a vissza gomb megjelenítésének vizsgálata 54: { 55: $szam2=$i-5; 56: print "<form action=$PHP SELF?szam=$szam2&db=$db method=post> 57: <p align=left><input type=submit name=Submit value=Vissza></p> 58: </form>"; 59: } 60: ?> 61: </td><td><div align="right"> 62: <?php 63: if ($db-$szam>0) //a tovább gomb megjelenítésének vizsgálata 64: { 65: print "<form action=$PHP SELF?szam=$szam&db=$db method=post> 66: <p

align=right><input type=submit name=Submit value=Tovább></p> 67: </form>"; 68: } 69: ?> 70: </div></td></tr></table> 89 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: <?php if ($db!=0) //számok megjelenítése (az ötösével való ugrálás) { $darab=$db/5; $maradek=$db%5; $i=1; $szam=-5; while ($i<=$darab) { $szam+=5; print "<a href=$PHP SELF?szam=$szam&db=$db>$i<a> "; $i++; } if ($maradek!=0) { $szam+=5; print "<a href=$PHP SELF?szam=$szam&db=$db>$i<a> "; } } ?> <form action="furlap.php" method="post"> <input type="submit" name="Submit" value="Új hozzászólás"> </form> <br><a href=forum.php>Vissza<a> </td></tr></table> </center> </body> </html> Hozzászólás létrehozása

(furlap.php): 01: <html> 02: <head> 03: <title>Hozzászólás feltöltése</title> 04: <meta http-equiv="Content-Type" content="text/html; charset=iso8859-2"> 05: </head> 06: <body> 07: <?php 08: session start(); 09: if (!isset($name)) 10: { 11: print "Nincs bejelentkezve! 12: <br><a href=forum.php>Bejelentkezés</a>"; 13: } 14: else 15: { 16: print "<form method=post action=ffeld.php> 17: <b>Téma: </b>$tema[1]<br><b>Feladó: </b>$name<br> 18: <b>Hozzászólás:<b><br> 19: <textarea name=szoveg cols=60 rows=10></textarea><br> 20: <input type=submit name=Submit value=Feltöltés> 21: </form>"; 22: } 23: ?> 24: </body> 25: </html> Hozzászólás feltöltése (ffeld.php): 01: <?php 02: session start(); 03: if ($szoveg=="") 90 04: { 05: print "Nem töltötte ki

a szükséges mezőt! 06: <br><a href=furlap.php>Vissza</a>"; 07: die(); 08: } 09: $datum=date("Y.md H:i:s"time()); 10: include("adatbazis.php"); 11: $parancs="INSERT INTO forum(felado,temaazon,datum,szoveg) 12: VALUES($name,$tema[0],$datum,$szoveg)"; 13: if (!mysql query($parancs,$kapcsolat)) 14: { 15: print "Nem lehet az adatbázisba írni! 16: <br><a href=furlap.php>Vissza</a>"; 17: mysql close($kapcsolat); 18: die(); 19: } 20: $parancs="UPDATE forumtema SET datum=$datum WHERE azon=$tema[0]"; 21: if (!mysql query($parancs,$kapcsolat)) 22: { 23: print "Nem lehet az adatbázisba írni! 24: <br><a href=furlap.php>Vissza</a>"; 25: } 26: else 27: { 28: print "Hozzászólását sikeresen rögzítettük! 29: <br><a href=flista.php?azon=$tema[0]>Hozzászólás megtekintése</a>"; 30: } 31: mysql close($kapcsolat); 32: ?> Téma létrehozása

(turlap.php): 01: <html> 02: <head> 03: <title>Téma létrehozása</title> 04: <meta http-equiv="Content-Type" content="text/html; charset=iso8859-2"> 05: </head> 06: <body> 07: <?php 08: session start(); 09: if (!isset($name)) 10: { 11: print "Nincs bejelentkezve! 12: <br><a href=forum.php>Bejelentkezés</a></p>"; 13: } 14: else 15: { 16: print "<form method=post action=tfeld.php> 17: Téma: <input type=text name=temanev><br> 18: <input type=submit name=Submit value=Létrehozás> 19: </form>"; 20: } 21: ?> 22: </body> 23: </html> Téma feltöltése (tfeld.php): 01: <?php 02: session start(); 91 03: if ($temanev=="") 04: { 05: print "Nem töltötte ki a szükséges mezőt! 06: <br><a href=turlap.php>Vissza</a>"; 07: die(); 08: } 09: include("adatbazis.php"); 10: $eredmeny=mysql

query("SELECT tema FROM forumtema WHERE tema=$temanev"); 11: $sor=mysql fetch row($eredmeny); 12: if (isset($sor[0])) 13: { 14: print "Ilyen téma már szerepel! 15: <br><a href=turlap.php>Vissza</a>"; 16: mysql close($kapcsolat); 17: die(); 18: } 19: $parancs="INSERT INTO forumtema(tema) VALUES($temanev)"; 20: if (!mysql query($parancs,$kapcsolat)) 21: { 22: print "Nem lehet az adatbázisba írni! 23: <br><a href=turlap.php>Vissza</a>"; 24: } 25: else 26: { 27: print "A téma létre lett hozva!"; 28: $eredmeny=mysql query("SELECT azon,tema FROM forumtema 29: WHERE tema=$temanev"); 30: $tema=mysql fetch row($eredmeny); 31: session register("tema"); 32: print "<br><a href=furlap.php> 33: Új hozzászólás létrehozása a témában</a>"; 34: } 35: mysql close($kapcsolat); 36: ?> Kijelentkezés a fórumból (flogout.php): 01: 02: 03: 04: 05: 06: 07:

08: 09: <?php session start(); session unset(); if (!session destroy()) print "A kijelentkezés sikertelen!"; else print "A kijelentkezés sikeresen megtörtént!"; print "<br><a href=forum.php>Fórum</a>"; ?> Regisztrációs űrlap (furlapu.php): 01: <html> 02: <head> 03: <title>Regisztráció</title> 04: <meta http-equiv="Content-Type" content="text/html; charset=iso8859-2"> 05: </head> 06: <body> 07: <form action="fufeld.php" method="post"> 08: <table> 09: <tr><td>Név:</td><td><input name="nev" type="text"></td></tr> 10: <tr><td>Felhasználónév:</td><td> 11: <input name="fh" type="text"></td></tr> 92 12: <tr><td>Jelszó:</td><td><input name="jsz"

type="password"></td></tr> 13: <tr><td>Jelszó megerősítése:</td><td> 14: <input name="jsz2" type="password"></td></tr> 15: <tr><td>E-mail:</td><td><input name="email" type="text"></td></tr> 16: </table> 17: <input type="submit" name="Submit" value="Regisztráció"> 18: </form> 19: </body> 20: </html> A felhasználó adatainak feltöltése (fufeld.php): 01: <?php 02: if ($nev=="" || $fh=="" || $jsz=="" || $jsz2=="" || $email=="") 03: { 04: print "Nem töltötte ki a szükséges mezőket! 05: <br><a href=furlapu.htm>Vissza</a>"; 06: die(); 07: } 08: if ($jsz!=$jsz2) 09: { 10: print "A két jelszó nem egyezik meg! 11: <br><a href=furlapu.htm>Vissza</a>"; 12: die(); 13: }

14: include("adatbazis.php"); 15: $eredmeny=mysql query("SELECT fnev FROM forumuser WHERE fnev=$fh"); 16: $user=mysql fetch row($eredmeny); 17: if (isset($user[0])) 18: { 19: print "Ilyen felhasználó már létezik! 20: <br><a href=furlapu.htm>Vissza</a>"; 21: mysql close($kapcsolat); 22: die(); 23: } 24: $j=md5($jsz); 25: $parancs="INSERT INTO forumuser(nev,fnev,jszo,email) 26: VALUES($nev,$fh,$j,$email)"; 27: if (!mysql query($parancs,$kapcsolat)) 28: { 29: print "Nem lehet az adatbázisba írni! 30: <br><a href=furlapu.htm>Vissza</a>"; 31: die(); 32: } 33: else 34: { 35: print "A regisztráció sikeresen megtörtént! 36: <br><a href=forum.php>Vissza</a>"; 37: } 38: mysql close($kapcsolat); 39: ?> 93 12 Biztonság A PHP egy igen hatékony nyelv és feldolgozó program, akár egy különálló CGI futtatható állományként, akár kiszolgálómodulként

működik. Képes elérni fájlokat, futtatni parancsokat és hálózati kapcsolatokat nyitni a szerveren. Ezek a tulajdonságok veszélyessé is tehetik a Web-szerveren futó alkalmazások számára, a PHP-t azonban úgy fejlesztették, hogy biztonságosabb legyen CGI programok írására, mint a Perl vagy C nyelvek. A teljesen biztonságos rendszer kialakítani tulajdonképpen lehetetlen, ám a PHP fordítási és futásidejű beállításainak helyes megválasztásával, és megfelelő programírási módszerek betartásával nagy mértékben növelhetjük a biztonságot. A továbbiakban néhány biztonsági tanács kerül említésre a különböző beállítási lehetőségekkel. 12.1 CGI futtatható állományként telepített PHP A PHP CGI futtatható állományként való használata egy telepítési lehetőség azok számára, akik valami oknál fogva nem szeretnék a PHP-t modulként a szerverbe integrálni (pl. Apache) Ez a forma magával vonja azt, hogy a PHP a szerver

cgi-bin könyvtárába legyen telepítve. a PHP-t úgy tervezték, hogy az ilyen telepítésekből adódó támadásokat kivédje: − Rendszerfájlok elérése: http://domain.nev/cgi-bin/php?/etc/passwd Az URL lekérési információja, ami a kérdőjel után található, parancssori paraméterként kerül átadásra a feldolgozónak. Általában a feldolgozók megnyitják, és lefuttatják az első paraméterként adott fájlt. Ha a PHP CGI futtatható állományként hívódik meg, nem veszi figyelembe a parancssori paramétereket. − Bármilyen web dokumentum elérése a szerveren: http://domain.nev/cgi-bin/php/titkos/dochtml Az elérési út információ az URL része, a futtatható fájl neve után lévő /titkos/doc.html a CGI program által megnyitásra és futtatásra kerülő fájl elérésének meghatározására használatos. Tipikusan néhány webkiszolgáló beállítási lehetőség (Apache-ban: Action) használatos a kérések átirányítására a dokumentumhoz,

mint a http://domain.nev/titkos/szkriptphp a PHP értelmező számára. Ezzel a beállítással a szerver először ellenőrzi az elérési engedélyeket a /titkos könyvtárra, és ezután állítja elő az átirányító kérést a http://domain.nev/cgi-bin/php/titkos/szkriptphp oldalra, amit így már a PHP feldolgoz. Azonban ha eredetileg is ebben a formában volt megadva a kérés, nem történik elérési ellenőrzés a /titkos/szkript.php fájlra, csak a /cgi-bin/php fájlra. Ilyen módon bárki, aki elérheti a /cgi-bin/php címet, egyben tetszőleges védett dokumentumot is elérhet. 1. Csak publikus állományok találhatók a szerveren Ha a szerveren nincs olyan tartalom, ami jelszó vagy IP alapú védelemmel van ellátva, nincs szükség ezekre a konfigurációs beállításokra. 2. Az --enable-force-cgi-redirect használata Ez a fordítási paraméter megakadályozza, hogy bárki meghívja a PHP-t egy http://domain.nev/cgi-bin/php/titkos/szkriptphp URL-el Ehelyett a PHP

csak akkor fog elfogadni egy ilyen kérést ha egy szerver átirányításban kapta. 94 Apache esetében tipikusan a következő direktívákkal történik a beállítás: Action php-script /cgi-bin/php AddHandler php-script .php 3. A doc root és a user dir beállítások A PHP szkript dokumentumok gyökérkönyvtárát a doc root konfigurációs beállítással határozhatod meg a konfigurációs fájlban, vagy a PHP DOCUMENT ROOT környezeti változóban adhatod meg ezt az értéket. Ha ez be van állítva a PHP CGI verziója a fájl elérési útját a doc root és a kérés elérési út információja alapján állítja elő, ami azt jelenti, hogy ezen a könyvtáron kívül nem futtatható fájl (kivéve a user dir esetét). Egy másik itt használható opció a user dir. Ha ez nincs megadva, akkor csak a doc root szabályozza a megnyitható fájlok körét. Ekkor egy http://domain.nev/~user/docphp URL nem a "user" nevű felhasználó home könyvtárában lévő

fájlt keresi, hanem a ~user/doc.php fájlt keresi a doc root alatt. Ha a user dir meg van adva, például public php, akkor a fenti http://domain.nev/~user/docphp kérés a docphp nevű fájlt fogja megnyitni a "user" nevű felhasználó home könyvtárában lévő public php könyvtárban. Ha a "user" home könyvtára /home/user, a lefuttatandó fájl a /home/user/public php/doc.php lesz 4. PHP feldolgozó a web könyvtárfán kívül Rendkívül biztonságos lehetőség a PHP feldolgozót valahol a webről látható könyvtárakon kívülre tenni, például a /usr/local/bin könyvtárba. Az egyetlen igazi hátránya ennek az opciónak az, hogy minden PHP szkript első sorának egy ehhez hasonló sort kell megadni: #!/usr/local/bin/php ami meghatározza, hogy hol található a PHP feldolgozó, ami lefuttatja majd ezt a kódot. Ráadásul minden PHP szkriptnek futási jogot kell adni Ahhoz, hogy ebben az esetben a PHP helyesen kezelje a PATH INFO és a PATH

TRANSLATED információkat, a PHP feldolgozót az --enable-discard-path "configure" paraméterrel kell fordítani. 12.2 Apache modulként telepített PHP A PHP-t Apache modulként használva örökli az Apache-t futtató felhasználó (tipikusan a "nobody") jogait. Ennek többféle hatása van a biztonságra és az azonosításra PHP-n keresztüli adatbázis elérés esetén például, az adatbázist elérhetővé kell tenni ezen felhasználó számára is, kivéve ha az adatbázisnak beépített azonosítása van. Így egy rosszindulatú szkript elérheti, és módosíthatja az adatbázist, akár felhasználói név és jelszó nélkül is. Ez ellen lehet védekezni az Apache azonosítási technikákkal, vagy LDAP segítségével megvalósított saját elérési modellekkel. Az Apache felhasználó jogainak root szintre bővítése különösen veszélyes, és tönkreteheti a teljes rendszert. Az open basedir használatával szabályozni lehet, hogy mely

könyvtárakat olvashatja a PHP. Ki lehet jelölni ún csak apache területeket, hogy minden web alapú művelet ide, csak ezekre a nem rendszer- és nem felhasználói fájlokra korlátozódjon. 95 12.3 Fájlrendszer A PHP képes a fájlok és könyvtárak hozzáférési jogosultságainak kezelésére. Ez lehetőséget ad arra, hogy megszabjuk, mely fájlok olvashatóak a rendszerben. A mindenki számára olvasható fájloknál ügyelni kell arra, hogy ne tartalmazzanak olyan adatot, amit nem szabad elolvasnia bármelyik felhasználónak. Mivel a PHP úgy készült, hogy felhasználói szintű fájlrendszer hozzáférést ad, lehetséges olyan program készítése, amely a rendszerfájlokat olvassa, mint pl. az /etc/passwd fájl Ez maga után vonja, hogy minden esetben meg kell győződni arról, hogy a helyes fájlokat olvassa illetve írja a program. Nézzük a következő szkriptet, ahol a felhasználó megadja, hogy le szeretne törölni egy fájlt a könyvtárában. Ez

többnyire egy webes felületet jelent, ahol egy PHP program használatos fájlkezelésre, ezért az Apache-t futtató felhasználónak engedélyezni kell a fájlok törlését a felhasználó könyvtárában. <?php //egy fájl törlése akárhonnan, ahol a PHP usernek joga van erre $usernev=$ SERVER[REMOTE USER]; //ez a user azonosított neve(ha volt előtte azonosítás) $konyvtar="/home/$usernev"; $torlendo file=basename("$userfile"); //elérési trükközés eldobása unlink($konyvtar/$torlendo file); $fp=fopen("/home/logging/filedelete.log","a"); //törlés naplózása $logstring="$usernev $konyvtar $torlendo file"; fputs($fp,$logstring); fclose($fp); print "$torlendo file törölve!"; ?> Ha az aktuálisan használt hitelesítési módszer megengedi a felhasználóknak, hogy saját login nevet válasszanak, és az egyikük a "./etc/" -t választja, akkor a rendszer ugyanolyan védtelenné válik. Ebből

kiindulva a jobban testreszabott ellenőrzés a következőképp alakulna: <?php $usernev=$ SERVER[REMOTE USER]; // hitelesites $homedir="/home/$usernev"; if (!ereg(^[^./][^/]*$,$userfile)) die(rossz fájlnév); //vége, nincs feldolgozás if (!ereg(^[^./][^/]*$,$usernev)) die(rossz usernev); //vége, nincs feldolgozás //stb. ?> A használt operációs rendszertől függően széles a védeni kívánt fájlok skálája, beleértve az eszköz hivatkozásokat (/dev/ vagy COM1), konfigurációs fájlokat (/etc/ és az .ini fájlok), jól ismert tárolóhelyeket (/home/, My Documents). Emiatt könnyebb egy olyan rendszert készíteni, ahol mindent tiltunk azon kívül, amelyet kifejezetten megengedünk. 12.4 Adatbázis Az első lépés mindig az adatbázis létrehozása, hacsak nem egy kívülállóét kell használni. Az adatbázis létrehozásakor a tulajdonosé lesz, azé, aki lefuttatta az utasításokat. Általában csak a tulajdonos - esetleg az ún superuser -

jogosult bármiféle az adatbázis elemeit érintő műveletre. Annak érdekében, hogy más felhasználók is hozzáférjenek, jogokat kell nekik biztosítani. Az alkalmazásoknak soha nem szabad a tulajdonosaként vagy superuserként csatlakozni az adatbázishoz, mert ezek bármilyen 96 utasítást és lekérdezést tetszés szerint futtathatnak, így például szerkezeti módosításokat hajthatnak végre vagy táblákat törölhetnek. Mindig csak a legszükségesebb jogokat szabad engedélyezni, és el kell kerülni, hogy ugyanazt a felhasználót használjuk szerepeiben egymástól különböző esetekben. Ez azt jelenti, hogy ha a behatoló meg is szerzi valamelyik ilyen minősítést (hitelesítési információ=felhasználói név+jelszó), akkor is csak akkora változást tud okozni, mint az alkalmazás maga. Nem kell minden feladatfüggő szabályozást a webalkalmazásban (PHP szkriptben) kódolni, ehelyett inkább használjuk az adatbázis lehetőségeit: view-k

(nézetek), trigger-ek, rule-ok (szabályok). Az űrlapokból származó adatokat gyakran tároljuk adatbázisokban. SQL-parancsokat küldünk az adatbázis-szervernek, melyek előre elkészített és a felhasználótól kapott részekből állnak össze. Ha a bevitelek érvényességét nem ellenőrizzük le még egyszer szerver-oldalon, azt a hackerek kihasználhatják. Egy ellenőrizetlen mezőbe egyszerűen beírnak egy további SQL-parancsot, amely a lekérdezéssel egy időben végrehajtódik. Így olvasni vagy manipulálni lehet az adatokat, ami a felhasználó előtt rejtve marad. A hackernek ehhez még az adatbázis felépítését sem kell ismernie. Ha a támadó közvetlen hozzáférést szerzett az adatbázishoz (megkerülve a Webszervert), a tárolt adatok védtelenné váltak, és visszaélhet velük, ha csak maga az adatbázis nem védi valahogy azokat. Az adatok titkosítása enyhíti ezt a veszélyt, de jelenleg nagyon kevés adatbázis kezelő támogatja a

titkosítást. Ebben az esetben a PHP segítséget nyújthat néhány kiterjesztésével, mint például az Mcrypt vagy az Mhash, amelyek nagyon sokféle titkosító algoritmust fednek le. Olyan teljesen rejtett adatok esetén, amelyeknek nyílt ábrázolásukra nincs szükség, mert nem lesznek kiíratva, a hashelés alkalmazása is meggondolandó. A hashelés jól ismert példája az, hogy a jelszavak helyett, azoknak csak MD5 hash értékét tárolják az adatbázisban. Mindig ellenőrizzük a bejövő adat típusát, hogy az a vártnak megfelelő-e. A PHP a bevitelt ellenőrző függvények széles körével rendelkezik kezdve a legegyszerűbbektől (pl. változókkal kapcsolatos függvények – is numeric()) a Perl kompatibilis reguláris kifejezések támogatásáig. Ha az alkalmazás számot vár, akkor megfontolandó az is numeric() függvénnyel ellenőrizni a típusát, vagy megváltoztatni a típusát a settype() függvénnyel, vagy szám szerinti ábrázolását használni

az sprintf() függvénnyel. Semmilyen adatbázisra jellemző információt - különösen szerkezetit - nem szabad kiírni. Idézőjelek közé kell tenni minden nem szám jellegű, felhasználótól származó adatot, erre használható az addslashes() vagy az addcslashes(). 12.5 Felhasználótól érkező adatok Mindig alaposan meg kell vizsgálni a felhasználók által beadott adatokat, feltéve a következő kérdéseket: − − − − − Biztos, hogy ez a szkript csak a kívánt fájlokat fogja módosítani? Előfordulhat egy ponton, hogy szokatlan vagy nem kívánatos adat jelenjen meg? Használható-e az adott szkript nem kívánatos formában? Felhasználható-e más szkriptekkel együtt egy negatív hatás elérésére? Megfelelően naplózásra kerülnek-e a tranzakciók (elérések, változtatások)? Alaposan átgondolva a fenti kérdéseket a szkript írásakor, megkímélhet minket attól, hogy később észrevéve a problémákat szerencsétlen módon újra kelljen

írni a teljes kódot a védelem növelése érdekében. Persze ezzel sem lehet garantálni a rendszer biztonságát, de segíthet annak növelésében vagy fenntartásában. 97 12.6 Hibakezelés A PHP biztonsági kérdések felől a hibajelzéseknek két oldaluk van. Az egyiket nézve hasznos a védelem növelése szempontjából, a másik szemszögből viszont káros. Egy szokásos támadási technika minél több információ begyűjtése a rendszerről. Ezt úgy próbálják megoldani, hogy helytelen adatokat küldenek be, és rögzítik a hibaüzenetek típusait és környezetüket. Ez lehetőséget ad a crackernek, hogy elég információt gyűjtsön a rendszerről, és meghatározza a lehetséges gyenge pontokat. Ha például a támadó összeszedegetett elég információt az előző űrlap kitöltések alapján, akkor megpróbálhatja a változókat felülírni vagy megváltoztatni őket. A PHP által visszaadott hibaüzenetek általában hasznosak a hibákat kereső

fejlesztő számára, megjelölve a fájlt, és a függvényt, ami hibás, valamint megadva a megfelelő programsor számát. Nem ritka, hogy egy PHP fejlesztő a show source(), highlight string(), vagy highlight file() függvényeket a fejlesztés során hibakeresésre is használja, de egy élesben lévő webhelyen ez rejtett változókat, ellenőrizetlen kódokat, és más veszélyes információkat fedhet fel. Kifejezetten veszélyes beépített hibakezelővel rendelkező ismert forrású kódok használata. Ha a támadó ráismer valamilyen általános programozási technikára, akkor megpróbálhatja feltörni az oldalt a különböző megszokott hibakereső (debugging) változók elküldésével. A fájlrendszer vagy általános PHP hibák jelezhetik, hogy milyen jogokkal rendelkezik a Web-szerver, és megmutathatják a fájlok elrendezését és struktúráját. A fejlesztő által írt hibás kód súlyosbíthatja a helyzetet, egykori rejtett információk könnyű

kiderítését lehetővé téve. Három megoldási lehetőség adódik erre a problémára Az első, megvizsgálni alaposan a függvényeket, és megpróbálni elkerülni a hibákat. A második a a hibajelzés kikapcsolása a teljes kódon belül. A harmadik a PHP testreszabható hibajelentési funkcióinak használata, így saját hibakezelőket definiálhatunk. A már megtett biztonsági intézkedésektől függően esetleg mindhárom fenti módszert választható. Hasznot nyújthat a PHP beépített error reporting() függvénye, amely segít biztonságosabbá tenni a programokat és megtalálni a változók vészelyeket rejtő használati formáit. 12.7 Globálisan elérhető változók A PHP 4.20 változatától kezdődően a register globals direktíva alapértelmezett értéke OFF-ra van állítva. Amikor a register globals be van kapcsolva, megmérgezi a szkriptet mindenféle változóval, mint például a HTML űrlapokból származókkal. Ehhez még hozzáadódik az, hogy a

PHP nem követeli meg a változók inicializálását, így sokkal könnyebb veszélyes kódot írni. Ha bekapcsolt állapotban van, sokan úgy használják a változókat, hogy valójában nem is tudják honnan származnak, csak feltételezik. Ilyenkor a szkriptben definiált változók összekeverednek a felhasználótól érkezőkkel. A 410 változattól kezdődően bevezetésre kerültek olyan szuperglobális hatókörű tömbök, mint például a $ GET, $ POST, $ SERVER. Ezek segítségével könnyen ellenőrizhetjük, hogy a változók honnan érkeztek. A lenti példa a session-ökhöz kapcsolódik: <?php //Nem tudhatjuk, hogy a $usernev honnan származik, de azt igen, hogy //a $ SESSION a munkamenet adatokat hivatkozza if (isset($ SESSION[usernev])) { print "Hello, <b>{$ SESSION[usernev]}</b>"; } else 98 { } ?> print "Hello, <b>Vendég</b><br>"; 12.8 A PHP elrejtése Néhány egyszerű módszerrel elrejthető, hogy

PHP-t használsz, így lassítva le a támadót, aki fel akarja deríteni a rendszer gyenge pontjait. A phpini-ben az expose php= off beállítással csökkentheted ezeket az információkat. Másik taktika a Web-szerver (pl. apache) olyan beállítása, hogy különböző típusú fájlokat is PHP-n keresztül futtasson. HTML típus használata PHP fájlkiterjesztésként: AddType application/x-httpd-php .htm html Ahhoz, hogy ez jól működjön, minden PHP fájlt át kell nevezni a htm vagy html kiterjesztések valamelyikére. Mivel ez is a rejtőzésen alapuló védelmi forma, kevés hátránya mellett csekély megakadályozó intézkedést jelent. 12.9 Frissítések A PHP, mint bármilyen más nagy rendszer folyamatosan változások és fejlesztések alatt áll. Minden új változat kisebb-nagyobb változtatásokat tartalmaz, fejlesztve a nyelvet, kijavítva biztonsági hibákat, beállítási kellemetlenségeket, és más olyan elemeket, amik a teljes rendszer stabilitására

és biztonságára hatnak. A legjobb hozzáállás a gyakori frissítés, valamint a friss változatokról, és a fellépő változásokról való informálódás. 99 Irodalomjegyzék 1. BAKKEN, STIG SÆTHER – http://www.huphpnet 2002-2004 2. SCHMID, EGON: PHP kézikönyv. CASTAGNETTO, JESUS – RAWAT, HARISH – SCHUMANN, SASCHA – SCOLLO, CHRIS – VELIATH, DEEPAK: Professional PHP Programming. Wrox Press, 1999. 3. GILMORE, WILLIAM JASON: A Programmer’s Introduction to PHP 40 Apress, 2001. 4. ILLÉS ZOLTÁN: Programozási nyelvek: C++ μlógia 23, ELTE TTK Informatikai Tanszékcsoport, Budapest, 1996. 5. KERNIGHAN, BRIAN W – RITCHIE, DENNIS M: A C programozási nyelv Műszaki Könyvkiadó, Budapest, 1988. 6. MOULDING, PETER: PHP Haladóknak Fekete Könyv Perfact, Budapest, 2002 7. WELLING, LUKE – THOMPSON, LAURA: PHP and MySQL Web Development, Second Edition. Sams Publishing, 2003 8. ZANDSTRA, MATT: Tanuljuk meg a PHP4 használatát 24 óra alatt Kiskapu,

Budapest, 2001. 100