Környezeti változók, űrlapok kezelése Környezeti változók, űrlapok kezelése...1 Az állapot nélküli (stateless) hálózati alkalmazások jellegzetességei...1 Környezeti változók...2 A PHP előre definiált változói...2 A HTTP GET illetve POST metódusok használata...4 Űrlapok használata (form-ok)...5 A <form> elem...5 A űrlap (form) elem tulajdonságai...6 A rejtett mezők...9 A select elem...9 A jelölőnégyzet (checkbox) elem...10 A választógomb (radio) elem...11 A textarea elem...11 Állományok feltöltése...11 Űrlapok tervezési kérdései...12 Űrlapok adatainak ellenőrzése...13 Az állapot nélküli (stateless) hálózati alkalmazások jellegzetességei - a felhasználó egy kliens programot használ - a webszerver egy fiú folyamatot vagy új szálat indít a kapcsolat létrejöttekor, a kiszolgálás után pedig megszünteti azt - tehát elveszíti a változóit -még ha ugyanaz fiú fogja kiszolgálni a következő kérést ugyanattól a klienstől, akkor sem tartja meg állapotát Az eljárás előnye, hogy így a szerver nagyon sok klienst tud kiszolgálni, lényegesen többet, mint ahány kiszolgáló folyamatot indít. Mivel a szerveren futó program és annak változó létrejönnek és a kiszolgálás után törlődnek, a programozási környezetnek biztosítani kell a: -a webes környezet leírását tartalmazó változók elérését (CGI változók, HTTP fejlécben küldött változók) -a szkriptek (programok) változóinak megőrzését két egymás utáni HTTP kérés között 1
Ezért az állapot követésére a szerveren az alábbi módszereket használjuk : Webtechnológia, előadásvázlat, 2007/08-II. félév -környezeti változók követése -URL-ben és űrlapok által küldött paraméterek kezelése -URL átírás (URL rewriting) -sütik (cookie) követése -a szükséges perszisztens változók automatikus mentése állományba vagy adatbázisba (szessziók) A következőkben ezeket a módszereket tekintjük át. Környezeti változók A PHP előre definiált változói A példákat PHP-ből vesszük, de ugyanezeknek a változóknak az elérése lehetséges bármely programozási nyelv alatt, amely webes programozási interfészt biztosít. A változók láthatósága PHP-ben: -osztály vagy függvényen kívüli változók (ezek a $GLOBALS tömbben vannak) -függvényeken belüli lokális változók -a global kulcsszó függvényen belül -a szuperglobális változók -a php.ini register_globals beállítása A környezeti változók történelmi okokból (PHP3, PHP4, PHP5) különböző nevek alatt érhetők el, mi a PHP4/5-ben bevezetett új neveket fogjuk használni. Valamennyi globális változó elérhető a $GLOBALS tömbön keresztül (pl. $GLOBALS['REQUEST_METHOD']), a különböző kategóriákba sorolhatóak esetében ajánlatos a kategóriához kötött globális tömb használata (pl. az előbbi változó a szerver változói közé tartozik, ezért így fogjuk elérni: $_SERVER['REQUEST_METHOD']). Ezek a változók a PHP -ben un. szuperglobális változók (bárhonnan elérhetőek, nem kell globálisnak deklarálni őket.) Ezek az alábbiak: $_SERVER A webszerver által használt, és PHP értelmezőben is elérhető változók. Nevük a CGI 1.1 -es specifikációból származik. Ebbe a változócsoportba tartoznak: - a kliens által küldött http fejléc értékek, amely így néz ki.: Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 2
elérhetősége a PHP-ben a HTTP_ACCEPT_CHARSET indexű változón keresztül lehetséges: $accept=$_server['http_accept_charset'] Példák szerver által generált változókra egy kérés esetén (valtozok.php): Változó neve értéke HTTP_HOST localhost A HTTP szervert futtató gép neve HTTP_USER_AGENT Mozilla/5.0 (X11; U; Linux i686; en- US; rv:1.6) Gecko/20040113 A böngésző adatai text/xml,application/xml,application /xhtml+xml,text/html;q=0.9,text/plai HTTP_ACCEPT A Http-Accept fejléc n;q=0.8,image/png,image/jpeg,image/g sor értéke if;q=0.2,*/*;q=0.1 HTTP_ACCEPT_LANGUAGE en-us,en;q=0.5 A Http-Acceptlanguage értéke A Http-Acceptencoding HTTP_ACCEPT_ENCODING gzip,deflate értéke(fogad e tömörített adatokat a böngésző) HTTP_ACCEPT_CHARSET ISO-8859-1,utf-8;q=0.7,*;q=0.7 Milyen karakterkészletet fogad el HTTP_KEEP_ALIVE 300 Menny ideig maradjon életben a TCP kapcsolat (sec) HTTP_CONNECTION keep-alive Maradjon életben a TCP kapcsolat HTTP_CACHE_CONTROL max-age=0 PATH / sbin:/usr/sbin:/bin:/usr/bin:/usr/x1 1R6/bin SERVER_SIGNATURE SERVER_SOFTWARE Apache/2.0.40 Server at localhost Port 80 Apache/2.0.40 (Red Hat Linux) A szerver aláírás sztringje A szerveren futó szoftver SERVER_NAME localhost A szerver domain neve SERVER_ADDR 127.0.0.1 A webszerver gép neve vagy címe SERVER_PORT 80 A használt TCP port REMOTE_ADDR 127.0.0.1 A kliens gép címe DOCUMENT_ROOT /var/www/html A szerver html dokumentumainak címe SERVER_ADMIN root@localhost 3
SCRIPT_FILENAME / var/www/html/webtech/forms/valtozok. php Webtechnológia, előadásvázlat, 2007/08-II. félév REMOTE_PORT 32820 A böngésző port címe GATEWAY_INTERFACE CGI/1.1 Az interfész SERVER_PROTOCOL HTTP/1.1 A használt protokoll verzió REQUEST_METHOD GET A kérés metódusa QUERY_STRING REQUEST_URI /webtech/forms/valtozok.php A kérés relatív webcíme SCRIPT_NAME /webtech/forms/valtozok.php PHP_SELF /webtech/forms/valtozok.php a szkript saját webcíme A többi szuperglobális: $_GET, $_POST, $_REQUEST a HTTP kérés által küldött paramétereket tartalmazzák, $_COOKIE cookie-kat (sütik) tartalmazó tömb, $_FILES információ a feltöltött fájlokról, $_SESSION a szessziókhoz kötött változókat tartalmaz, $_ENV az operációs rendszer környezeti változóit tartalmazza. A továbbiakban áttekintjük használatukat. A HTTP GET illetve POST metódusok használata A $_GET, $_POST és $_REQUEST változók A kliens által küldött paramétereket és adatokat tartalmazó változók. Ezek GET kérés esetén az elsőben POST kérés esetén a másodikban vannak. Mindkettő szuperglobális. Ezen kívül, a $_REQUEST tömb mindkettőt tartalmazza tehát azt általánosan lehet használni, ha nem fontos tudnunk, hogy a kérés GET vagy POST (a $_REQUEST a sütiket is tartalmazza). Például a : http://ms.sapientia.ro/index.php?alpha=2 című URL esetén a paramétert PHP-ben: $alpha=$_get['alpha']; 4
szintaxissal érem el. Elérés előtt mindenképpen meg kell nézni, beállított-e a változó, legalább az alábbi ellenőrzéssel: if ( isset ($_GET['alpha']) { $alpha=$_get['alpha']; }else{ $alpha=''; //implicit érték } -példák a GET használatára, hogyan kerülnek át a paraméterek a protokollon keresztül itt találhatóak get.php. Látható, hogy űrlapokkal is küldhetünk GET kérést: ez nagyobb méretű adatok (több száz karakter az URL-ben) nem ajánlott, és egy határon túl már nem is lehetséges -a GET kérésekben található paraméterek alkalmasak a szkriptek állapotváltozóinak vezérlésére, ha megfelelő URL-eket írunk ki a HTML oldalakra, példa itt: getvezerles.php. -a jelenlegi keresőgépek az "barátságos" URL formátumokat preferálják az indexelések miatt, példa itt: getfriendly.php. Űrlapok használata (form-ok) Hogyan küldi el a kliens a http kérést GET és POST esetében? GET kérés: GET /x.html?a=1&b=2 HTTP/1.1 Host: eowyn.ms.sapientia.ro POST kérés: POST /teszt.php HTTP/1.1 Host: eowyn.ms.sapientia.ro Content-Length: 19 Content-Type: application/x-www-form-urlencoded a=1&b=2&c=abc%20abc A POST esetében a paraméterek a kérés törzs részében lesznek elküldve, méretük nagy lehet. Általában az űrlapok, állományok, azaz több és nagyobb méretű adat elküldésénél használjuk a POST metódust. A GET metódus csupán kisebb mennyiségű név/érték pár elküldésére használandó. A <form> elem A form elemet egy űrlap elemeinek körülzárására használjuk, pl: <form action="szkript.php" method="post" enctype="x-www-form-urlencoded"> <label for="name">írd be a neved: <input type="text" name="nev" value="" size="8" maxlength="100"> 5
</label> <label for="pwd">jelszó <input type="password" name="pwd" value=""> </label> <label for="go"> <input type="submit" name="go" value="küldd!"> </label> </form> Webtechnológia, előadásvázlat, 2007/08-II. félév A fenti űrlap 3 beviteli elemet tartalmaz, melyek típusa szöveg (text), jelszó (password) és submit (elküldő gomb). A <label> elem az űrlap beviteli elemei elé helyez el egy kis szöveget. A böngésző ablakában ez így jelenik meg: A űrlap (form) elem tulajdonságai Tulajdonság action enctype Értékei a fogadó szkript web címe, abszolút vagy relatív URL -Az elküldött adatok kódolása a HTTP kérés törzs részében. A kódolási lehetőségek az alábbiak: 1. application/x-www-form-url-encoded ez a standard kódolási forma (ha nem adunk meg semmit, ezt használja a böngésző). Az űrlap által küldött adatok név/érték párokban lesznek elküldve. A standard kódolásnál az alábbi formában küldi az adatokat: 6
Tulajdonság Értékei név1=érték1+értek2&név2=... 2. text/plain A törzs rész tiszta szöveggel lesz elküldve 3. multipart/form-data több dokumentumot küld egymás után böngésző, köztük pedig egy elválasztó szövegsort. Így akár több dokumentumot, melyek MIME típusa különböző besorolhat egy HTTP POST kérésbe. Akkor fogjuk használni ha pl. állományokat töltünk fel. accept-charset method target Általános HTML tulajdonságok: Karakter készletek felsorolása, amelyekkel a böngésző elfogadja az űrlap feltöltését. Értéke pl.: utf-8, iso-8859-2 a küldésnél használt metódus: POST vagy GET Egy frame ablakot lehet ezzel megjelölni: ez lesz az az ablak ahova a szerver által adott válasz érkezik. Ez lehet a frame neve, illetve valamelyik cél az alábbi implicit értékek közül: _self, _parent, _top (sorrendben: ugyanaz az ablak ahonnan a kérést küldtük, annak szülője illete egy új ablak). id, name, class, style event JavaScript események: onmouseover(), onsubmit(),... Milyen adatokat lehet bevinni és elküldeni a beviteli HTML elemekkel : -kis szöveg mezőket (név/érték) -rejtett mezőt -állományt -hosszabb szövegmezőt (textarea) -opciók közül kiválasztott adatot: -listából (select) -rádió gomb (radio) -jelölőnégyzet (checkbox) Az <input> elem pl. <input type="text" name="kod" size="10" maxlength="10"> 7
<input type="text" name="cim" size="30" maxlength="200"> <input type="file" name="uploaded" accept=".gif,.jpg"> Webtechnológia, előadásvázlat, 2007/08-II. félév Az input az űrlap általános beviteli eleme. Az elem type tulajdonsága adja meg a beviteli elem típusát. Az elem name tulajdonsága adja meg azt a nevet, amivel el lesz küldve a szerver oldalra. Az input típusától függően az elemnek más és más tulajdonságai is lehetnek. A típus az alábbiak közül lehet: text password hidden file checkbox radio select submit reset image szövegmező, név/érték párok küldése a szerver oldalra maszkolt szöveg jelszónak rejtett mező állomány feltöltése checkbox, "választónégyzet" rádiógomb, választógomb választás, lenyíló lista űrlap elküldő elem az egész űrlap elemeinek nullázására használjuk gomb helyett képre kattintva indíthatjuk az űrlapot, action.x=100&action.y=35 paraméterek (kattintás helye a képen) is el lesznek küldve. button <input type="button"> vagy: <button> </button> A button elem a HTML 4-ben jelent meg, típusa lehet submit, egy más HTML elemet fog körül, pl. egy képet. Úgy jelenik meg, mint a körülfogott elem, és úgy viselkedik, mint a type által megadott tulajdonsággal rendelkező input elem. A fent megadott példa esetében: <input type="text" name="nev" value="" size="8" maxlength="100"> elküldés után a name változóban megy el a beírt érték, ez szerver oldalon a $_POST['nev'] illetve a $_REQUEST['nev'] változókban érhető el. A fenti elem két gyakran használt tulajdonsága a kijelzett mező hosszát (size) illetve a maximális beírható sztringhosszat (maxlength) tartalmazza. Az alábbiakban bemutatunk néhány beviteli elemet. Részletes HTML leírásukat lásd még itt. Egy minta űrlap amely minden alkalmazható beviteli mezőt tartalmaz itt található (form.php). 8
A rejtett mezők A type tulajdonság értéke: hidden. A rejtett mezők nem jelennek meg a HTML oldal kiírásakor. Használatuk során a látható űrlapváltozókon kívül küldünk át és várunk vissza olyan változókat, amelyek valamilyen szekvenciát, előzőleg beküldött változókat vagy ellenőrző adatokat tartalmaznak. pl: <input type="hidden" name="action" value="finish"> Egy példa több lépésés űrlap megoldásra rejtett mezővel itt található (rejtett.php). A select elem A select elem egy kiválasztó listát generál. <label for="szinek">válassza ki a listából: <select name="szinek"> <option value="piros" selected>első</option> <option value="kék">második</option> 9
<option value="zöld">harmadik</option> <option value="sárga">negyedik</option> </select> </label> Az elküldött változó neve a szinek lesz, értékeit az option elemekben felsorolt listából: kék, zöld, sárga veszi. Az option elem selected tulajdonsága a megjelenéskor automatikusan kiválasztott listaelemet jelöli. A select elemnek (akárcsak a checkbox elemnek) megvan az a tulajdonsága, hogy egy név alatt több értéket küldhetünk be. Ebben az esetben be kell jelölnünk, hogy többszörös kiválasztót használunk, ezt a select elem multiple tulajdonságával tesszük (példa: select.php): <select name="tomb[]" "multiple"> <option value="elso" label="a" "selected">elso <option value="masodik" label="b">masodik <option value="harmadik" label=c>harmadik </select> Ilyenkor a name tulajdonságban un. HTML tömböt kell bejelölnünk (tomb[]), ennek értékeit a PHP alatt a $_POST[tomb][0], $_POST[tomb][1],... szintaxissal érjük el (a $_POST[tomb] válozó ezúttal tömb lesz, 0-tól indexelve. A többszörös kijelölést a böngészőben a kontrol billentyű lenyomásával és ugyanakkor egér kattintással végezzük. A jelölőnégyzet (checkbox) elem Az űrlapon több jelölőnégyzet esetén ezekből egyet sem, egyet vagy akárhányat választhatunk ki. Általános szintaxisa: <label for="negyzet">négyzet: <input type="checkbox" name="negyzet1" value="1"> <input type="checkbox" name="negyzet2" value="2"> </label> A négyzeteknek adhatunk más és más nevet, illetve ugyanolyan nevet mindkét négyzetnek, ebben az esetben: <label for="negyzet">négyzet: <input type="checkbox" name="negyzet[]" value="1"> <input type="checkbox" name="negyzet[]" value="2"> </label> Látható, hogy a második esetben HTML tömböt kell használni. A négyzet bejelölésekor a value tulajdonságban megjelölt érték lesz elküldve pl. a negyzet1 név 10
alatt. Ellenkező esetben a negyzet1 változó nem lesz beállítva. Webtechnológia, előadásvázlat, 2007/08-II. félév A választógomb (radio) elem Ez az elem alternatív kiválasztásra szolgál, tehát több ugyanolyan nevű gomb esetén azokból egyet lehet kijelölni. Pl.: <span>válasszon egy színt</span> <label for="piros">piros <input type="radio" name="szingomb" value="piros" checked> </label> <label for="kek">kék <input type="radio" name="szingomb" value="kek"> </label> A kiválasztott értéket a kliens a szingomb nevű POST változóban küldi. A textarea elem A textarea elem tulajdonképpen nem input elem, mert segítségével nem egy mezőt, hn. egy hosszabb szöveget lehet bevinni. Használata: <textarea name="message" rows="20" cols="10" wrap="virtual"> Hosszú szöveg </textarea> A böngésző ablakában az elem a rows és cols tulajdonsággal megjelölt sor és oszlopszámot foglalja el. A wrap tulajdonsággal a szövegsorok törésének (újsor bevitele) elküldését lehet kezelni. Ennek értékei a alábbiak lehetnek: wrap: virtual, soft phisical,hard off A virtual vagy soft beállítással az automatikusan bevitt sortörések nem lesznek elküldve, a phisical vagy hard beállítással pedig igen. Ezek értelmezése böngészőfüggő lehet (a virtual,phyisical értékeket a Mozilla alapú, a hard,soft értékeket az Ineternet Explorer fogja érteni). Állományok feltöltése Állományok feltöltésére a file típusú input elemet használjuk: <input type="file" name="file1" maxlength="100000"> <input type="file" name="file2" maxlength="100000"> A maxlength tulajdonság jelzi a böngészőnek a feltöltött file maximális méretét, de hatása informatív. Mivel a feltöltött állományok mérete veszélyes lehet a webszerver működésére nézve, ezt szerver oldalon szokták korlátozni. PHP-ben a php.ini konfigurációs állományban található ennek beállítása: 11
; Whether to allow HTTP file uploads. file_uploads = On ; Temporary directory for HTTP uploaded files (will use system default if not ; specified). ;upload_tmp_dir = ; Maximum allowed size for uploaded files. upload_max_filesize = 2M Szerver oldalon a PHP létrehoz egy $_FILES nevű globális tömböt, ennek indexei a file elemben megadott nevek lesznek, tehát $_FILES['file1'] fogja tartalmazni az első feltöltött állomány adatait. Ezek egy tömbben lesznek, az alábbi indexekkel: file1 name screenshot.txt type text/plain tmp_name /tmp/phpicg13q error 0 size 60 Ezek a feltöltött állomány nevét, MIME típusát, ideiglenes nevét (a /tmp/phpicg13q név az operációs rendszer /tmp ideiglenes állományokat tartalmazó könyvtárában jön létre), egy hibakódot és az állomány méretét byte-okban tartalmazzák. A hibakód 0 ha nem történt semmilyen hiba. Részletes leírás a PHP kézikönyvben itt. Ogyanott található példa a is_uploaded_file() és a move_uploaded_file() függvényekre, valamint HTML tömbök használatára, amely a file típusú input elem esetében is használható. Űrlapok tervezési kérdései -egymásutániság -csoportosítás logikailag -csoportosítás az interfészen (design elvek) -elhelyezés: táblázatok vagy abszolút/relatív pozíciók használata -a <fieldset> és <legend> HTML elemek használata A <fieldset> elem bemeneti elemek csoportosítására, a <legend> elem a csoportosított elemek közös nevének kiírására szolgál. Példát láss a minta űrlapon (form.php). -a <label> elem és a tabindex valamint accesskey tulajdonság használata A <label> elem kis szöveget rendel a bemeneti elemek elé. A tabindex tulajdonság bármely input elemre alkalmazható, értékként egész számokat kell megadni, pl. tabindex="1", tabindex="2". Hatására a TAB billentyű többszörös egymásutáni lenyomására a kiválasztó kurzor a megadott sorrendben ugrál végig az elemeken. Az accesskey tulajdonsággal egy billentyűt rendelhetünk minden 12
elemhez: annak és egy kontroll billentyű lenyomására a kurzor az illető elemre ugrik, így pl. accesskey="a". A kontroll billentyű böngészőként változik: Firefox Alt-Shift, Explorer: Alt. Az accesskey tulajdonság az alábbi elemekre alkalmazható: <input>, <textarea>, <label>, <legend> és <button>. Űrlapok adatainak ellenőrzése 1. kliens oldalon, JavaScript megoldások A kliens oldali ellenőrzés általában elegáns és ajánlott, meg lehet vele spórolni egy HTTP kérést, de nem kell benne abszolút megbízni. Ezért minden esetben az adatokat szerver oldalon is ellenőrizzük. Példa itt (form3.html). 2. Szerver oldalon az ellenőrzéshez több függvénycsoport áll rendelkezésre: a. Egyszerű függvények mint: empty(), gettype(), is_numeric(), is_integer(), stb. Lásd Kézikönyv:Változókkal kapcsolatos függvények b. Reguláris kifejezések használata A legerősebb függvények ehhez a feladathoz a reguláris kifejezések. A PHP-ben kétféle: POSIX bővített és Perl típusúakat lehet használni. Részletesen át fogjuk őket venni. c. Szűrő és ellenőrző függvények, speciális karakterek ellenőrzésére Pl. string strip_tags ( string str [, string allowable_tags] ); kiszűri a HTML címkéket string htmlspecialchars ( string string [, int quote_style [, string charset]] ) pl. < -t átalakítja <-é, valamint a >, &, ', " karaktereket. A string htmlentities ( string string [, int quote_style [, string charset]] ) string html_entity_decode ( string string [, int quote_style [, string charset]] ) a HTML karakter egyedeket (mint & ) kódolja illetve dekódolja. Amennyiben a beérkezett POST vagy GET paraméter SQL lekérdezésben lesz használva, fontos az olyan függvények használata, amelyek kiszűrik az SQL kontroll karaktereket. Ennek egyszerű 13
változata az alábbi: string addslashes ( string str ) ' ből \' lesz, valamint átírja ezeket is: ", \, NULL a fordított műveletet az alábbi függvénnyel végezzük: string stripslashes ( string str ) a következő műveletet végzi el: \' ből ' lesz. Ezen kívül valamennyi adatbázis kezelő függvénykönyvtár rendelkezik saját, az adatbázis típusától függő védő függvénnyel. A string quotemeta ( string str ) függvény a metakaraktereket kódolja át, * -ból \* lesz 14