| |||
Napjainkban és az elmúlt néhány évben újabb és újabb programozási nyelvek születésének lehetünk (lehettünk) tanúi. Ezeknek az új nyelveknek nagy része a tradicionális, széles körben alkalmazható társaik (C, C++, Pascal) szintaxisát, logikáját veszi alapul, és úgy egészíti ki azokat, hogy valamilyen a nyelv által kitűzött célnak jobban megfeleljen, tehát jobban specializálódjon.
Hogy egy kicsit konkrétabb legyek és a címhez is tartsam magam, ezek közül a programozási nyelvek közül ebben a sorozatban a dinamikus oldalak készítésére használhatóakkal foglakozunk, azon belül is elsősorban az egyre szélesebb körben elterjedő PHP-vel.
Azt már elárultam, hogy mire specializálódott a PHP lássuk, hogy honnan indult, hogyan tett szert ekkora népszerűségre a fejlesztők körében és egyáltalán mekkora is ez a népszerűség.
Egy kis történelem
A PHP születése 1994-re tehető, amikor Rasmus Lerdorf elkészítette első, a nyilvánosság számára nem elérhető verzióját, melyet csupán azért írt, hogy megkönnyítse olyan, egyszerű script-ek írását, mint például egy vendégkönyv vagy számláló. A program 1995 elején Personal Home Page Tools néven kezdett egyre ismertebbé válni. Még ebben az évben újraírta a szerző a program script-feldolgozó (parser) részét és kiadta a 2-es verziót PHP/FI néven. Az FI rész a névben az újonnan beépített form-feldolgozó részből adódott. De nem csak ez az egy extra került bele az új kiadásba: a nyelv immár támogatta az mSQL adatbázisok használatát, amely nagyban hozzájárult ahhoz, hogy újabb emberek kapcsolódjanak a fejlesztésbe, bővítve ezzel a nyelv palettáját.
1997-re már több mint 50 000 szerveren futott a PHP. Ekkor új irány vett a fejlesztés azzal, hogy társultak Rasmus-hoz más fejlesztők is, akik teljes egészében újraírták az interpretert, mely az 1998-ban megjelenő 3.0-s verzió alapja lett.
A nyelv sikerességét azt hiszem legjobban a statisztikai adatok bizonyítják: A NetCraft (www.netcraft.com) felmérése szerint 1998-ban 150 000 domain név alatt futott PHP, ami már önmagában nem kis szám és mondhatni azóta se csökkent, mivel az 1999. novemberi felmérés szerint ez 1 114 021, tehát jóval meghaladja az egymilliót.
A történetnek azonban még nincs vége, folytatódik a jelenben a PHP 4-es verziójával, melynek a script-értelmezője szintén teljesen újra lett írva, ami minimum 2-3-szoros, de előfordulhat, hogy 200-szoros sebességkülönbséget jelent a PHP3-hoz képest. Kapható lesz hozzá (sajnos nem ingyen) fordítóprogram is, mely a Java-éhoz hasonló hordozható, félig lefordított állapotba hozza a programunkat, ezáltal az még gyorsabban fog futni (3-4-szeres a különbség a PHP4-hez képest!!) és meg is védi a szerzőt attól, hogy mások az engedélye nélkül felhasználják a kódját.
Kapcsolódó linkek:
- http://www.php.net/manual/introduction.php3
- http://www.zend.com/
- http://www.phpbuilder.com/columns/zeev19990518.php3
Aki foglalkozott már dinamikus oldalak készítésével annak bizonyára ismerősek a következő nevek: Perl, Active Server Pages (ASP), Cold Fusion Markup Language (CFML). Ez a három script nyelv és a PHP a leggyakrabban használt a web-es világban. Nem szeretnék végletekbe menő összehasonlítást tenni közöttük, mivel ez elég nagy terjedelmű lenne, és nem feltétlenül lenne objektív az összehasonlítás.
Szintaktika
Azért néhány szó a nyelvek fő különbségeiről: szintaktika szempontjából a Perl talán a legbonyolultabb, ha egy C-hez szokott programozó meglát egy összetettebb programot Perl-ben, akkor azt hiszem, egyből az jut az eszébe, hogy te jó Isten, hogy lehet ilyen rondán programozni. A Perl nagyon sokféle lehetőséget nyújt egy probléma megoldására. Ezt megalkotásakor előnynek szánták, azóta kiderült, hogy inkább hátrányára vált, mivel nagyon nehéz dokumentálni a programot és egy nem tökéletesen dokumentált Perl programról még a készítője se tudja két hónap múlva, hogy mit, hogyan, miért tesz. Az ASP, a Microsoft találmánya, az IIS szerverekkel együtt használható (bár már létezik Unix alá is ASP, de persze ezt nem az MS fejleszti). Maga a nyelv nagyon hasonlít a Visual Basic-re (talán nem véletlen), ennek megfelelően a Perl-hez képest könnyen átlátható. A Cold Fusion-t az Allaire készíti (ha ismerős a név, akkor az a HomeSite miatt lehet, mert ez is az ő termékük). Szintaktikája a HTML-éhez hasonló, aki ehhez a stílushoz szokott hozzá az könnyen kiismeri magát egy ilyen programban. Mint már utaltam rá a PHP több nyelv formalitását ötvözi, ezek: C, Perl, Javascript. Leginkább a C-hez szokott fejlesztőknek lesz ismerős a szintaktika, elsajátítása azonban annyira egyszerű, hogy aki nem mozog otthonosan a programozásban az is könnyedén meg tudja tanulni. Ez egyébként a Perl kivételével, mindhárom nyelvről elmondható.
Függvények
Persze a szintaktika nem minden egy programozási nyelvben, használhatóságához nagymértékben hozzájárul az is, hogy milyen segítséget nyújt (ebben az esetben) a web oldalak dinamikus felépítéséhez, magyarul milyen függvény-tárházat használhatunk a nyelvben. A PHP-t használó programozó ez miatt igazán nem panaszkodhat, íme egy lista a legfontosabb függvénycsoportokról:
Adatbázis-kezelők elérése (MS-SQL, MySQL, Oracle, SyBase, PostgreSQL, dBase, filePro, Informix, InterBase, mSQL, dbm, ODBC), tömbkezelés, matematikai függvények, file-kezelés, programfuttatás, képlétrehozás/manipulálás, IMAP, LDAP, kódolás, hálózat, NIS, PDF, string, url, tömörítés, XML.
Ezek persze csak a nyelvhez tartózó függvények voltak, azonban lehetőségünk van saját függvények létrehozására (a Cold Fusion-el ellentétben), ezáltal akár saját könyvtárakat is készíthetünk hasznosnak vélt függvényeinkből. Ezt már sokan meg is tették, így rengeteg hasznos könyvtárat tölthetünk le Internetről. A legismertebb ezek közül a PHPLib.
Nyelvi struktúrák
Fontosak még a nyelv által strukturális szempontból nyújtott lehetőségek/korlátok. A PHP-ben megtalálhatóak a C-ben megszokott vezérlési struktúrák (if-else-if, while, do-while, for, break, continue, switch, include) és használhatóak a jól ismert operátorok is (string, matematikai, bitenkénti, logikai, összehasonlító és értékadás).
A PHP ún.: "gyengén típusos" nyelv, ami azt jelenti, hogy nem kötöttek a változó-típusok és a változók egyeztetése (pl. értékadásnál) automatikus konverzióval történik.
Mivel a PHP-ben írt programok tulajdonképpen CGI-k ezért különösön érdekes a web szerver által átadott változók elérése. Háromféle külső változó típust különböztet meg a PHP, ezek:
- GET metódus által kapott adatok
- ugyanez POST metódus esetén
- HTTP Cookie változók.
A kívülről kapott paraméterek kezelése nagyon egyszerűvé válik azáltal, hogy a PHP minden egyes paramétert automatikusan átalakítja a programban használható változókká. Például ha egy HTML form-ban a kitöltendő mező neve: cím, akkor a script meghívásakor ebből egy $cím nevű globális változó lesz (a $-el a változókat jelöli a nyelv a Perl-hez hasonlóan), amit ugyanúgy használhatunk, mint bármely más programváltozót. Néha persze kavarodást okozhat, hogy több helyről is kaphatunk változókat akár ugyanazzal a névvel is (GET/POST/Cookie), ezért felállíthatunk egy tetszőleges prioritást, vagy akár le is tilthatjuk az egyik forrás automatikus átalakítását.
Négy féle változótípust használhatunk a programjainkban: egész szám, valós szám, string, tömb, objektum. Az utóbbiból kiderül, hogy a PHP támogatja objektumok/osztályok létrehozását. Azért nem kell mindjárt Java-szintű objektumorientáltságra gondolni, a PHP-ben az objektumokat elsősorban könyvtárak írásakor használják, mivel így az objektumokba zárt változók nem érintik a globális társaikat. A PHP az objektumokra vonatkozó zártságon kívül a konstruktorok használatát és az egy szülőtől való öröklést teszi lehetővé. Jól hasznosíthatóak az objektumok például adatbázis-szerverek absztrakt kezelésére, elősegítve ezzel a programjaink hordozhatóságát (a már említett PHPLib is objektumokat használ erre a célra).
A tömbkezelés is a PHP egy nagyon fontos része, mivel az adatbázisból nyert adatainkat általában egy vektorban kapjuk vissza, ezt annak köszönhetően tehetjük meg, hogy a vektorokban nem csak azonos típusú elemeket tárolhatunk. Ezen kívül lehetőségünk van HTML űrlapokban elhelyezett adatokat is vektorként megkapni. Ez hasznos lehet például akkor, ha kiválasztó lista, vagy checkbox-ok adatait szeretnénk visszanyerni, mert vektorok használatával egyszerűbben végig tudunk haladni a kiválasztott elemeken. Az asszociatív tömbök használatával szintén könnyebbé tehetjük életünket (és persze olvashatóbbá a kódunkat), mivel sokkal egyszerűbb az adatbázis egy rekordját tároló tömbből, úgy kiválasztani a megfelelő elemet, hogy nem kell emlékeznünk, hogy "hányadik a sorban", hanem egyszerűen a mezőnévvel hivatkozhatunk rá, pl.: személy["név"]. A fentieket megfejelve még számos (34) függvénnyel szolgál a PHP a tömbök igazán hasznossá tételéért, pl.: rendezés (véletlenszerűvé is), elem beszúrás, verem függvények (push, pop), elemcsere, elemeken való lépkedés...
Legjobban talán egy példán keresztül tudom bemutatni a nyelv sajátosságait, ezért most jöjjön egy kicsit hosszabb lélegzetvételű példa. Nem szükséges minden egyes sorát értelmezni, inkább csak átnézni érdemes, mert sok mindent elmond a PHP-ről. A program maga egy vendégkönyv alprogramja, mely a vendégkönyv adatainak megjelenítéséért felelős. Nincs agyoncicomázva a HTML és a program sincs túlbonyolítva, hogy könnyebben meg lehessen érteni, de azért működőképes. SQL adatbázist használunk a vendégkönyv adatainak kinyerésére (ott tárolja egy másik script), a bejegyzéseket szűrhetjük dátum alapján és rendezhetjük dátum, név és e-mail cím szerint. A megjelenített form action paraméteréből kiderül, hogy a program önmagát hívja meg, ami nagyon gyakori form-ok feldolgozásakor PHP-ben. Ezért ellenőrizni kell, hogy beállított adatokkal hívták-e meg a programot (szűrés, rendezés) és hogy az adatok értékei megfelelnek-e nekünk, ha nem akkor az alapértelmezett rendezés és szűrés lesz érvényben.
A használt tábla mezői:
- üzenet : szöveges
- név : szöveges
- e-mail : szöveges
- dátum : dátum
- kommentek jelölése:
- // (egysoros)
- # (egysoros)
- /* */ (többsoros)
- a PHP kódot bárhova beágyazhatjuk a standard HTML közé ezért jelölni kell a kezdetét és a végét, amit a következő módokon tehetünk meg:
- <? kód ?>
- <?php kód ?>
- <% kód %> (ASP stílus)
- <script language="php"> kód </script>
<?php
header("Expires: Thu, 15
Jul 1999 1:00:00 GMT");
header("Last-Modified: "
. gmdate("D, d M Y H:i:s") . "GMT");
header("Cache-Control: no-cache,
must-revalidate");
header("Pragma: no-cache");
/*
HTML headerek kiküldése azért,
hogy a böngészők és a proxy-k ne tárolják a cache-ben az oldalt (dinamikus
oldal lévén nincs értelme)
*/
/*
fejléc beszúrása egy html állományból
közös fejléc-állománnyal könnyebben
testre szabhatjuk a vendégkönyv összes oldalát
az így beszúrt állomány tartalmazhat
PHP kódot is
/*
include("./header.html");
/*
a form-ban előzőleg beállított
értékek eltárolása változókban
ellenőrizni kell azt is, hogy megadták-e
a paramétereket,
és hogy jót adtak-e meg (pl. default
a switch-nel)
*/
if (!isset($orderby))
$orderby="date";
/*
az isset() függvénnyel ellenőrizhetjük,
hogy egy változóban kaptunk-e adatot
ha nem kaptunk az $orderby-ba (ami
azt mutatja hogy mi szerint kell
rendeznünk), akkor a dátum szerintit
állítjuk be (alapértelmezés)
*/
$checkdate=$checkname=$checkemail="";
// a form rádiógombjainak helyes
beállításához szükséges változók
switch ($orderby)
{
case "name":
$checkname="checked";
break;
case "email":
$checkemail="checked";
break;
case "date":
default:
$orderby="date";
$checkdate="checked";
}
/*
Az $orderby változóban kapjuk azt,
hogy mi szerint kell rendeznünk
A kapott adatból meghatározzuk,
hogy melyik rádiógombnak
kell "checked" állapotba lennie
Azt a lehetőséget már kizártuk,
hogy nem kapunk adatot,
itt a default címkével a rossz
adat lehetőségét is kizárjuk
*/
if (!isset($way))
$way="desc";
$checkasc=$checkdesc="";
if ($way=="asc")
$checkasc="checked";
else
{
$checkdesc="checked";
$way="desc";
}
/*
a $way a rendezési irányt mutatja
(csökkenő/növekvő)
asc vagy desc lehet az értéke,
ezt az $orderby-hoz hasonlóan leellenőrizzük
*/
if (!isset($datefilter))
$datefilter="week";
$checkweek=$checktwoweeks=$checkmonth=$checkalltime="";
/*
a $datefilter-ben a dátum szerinti
szűrés időtartamát kapjuk
a $check... változók itt is a rádiógombok
beállításához szükségesek
*/
/*
a $showtime a SELECT SQL parancs
BETWEEN záradékához szükséges
ebben állítjuk össze a $datefilter-ben
kapott adatnak megfelelően azt
az időtartamot, amit majd a szűréshez
használunk fel
*/
switch ($datefilter)
{
case "twoweeks":
$checktwoweeks="checked";
$showtime=mktime(date("H"),date("i"),date("s"),date("m"),date("d")-14,date("Y"));
/*
az mktime() függvény a neki átadott
paramétereknek megfelelő UNIX dátumot ad vissza
a date() függvény az aktuális dátum
egy részét adja vissza a paraméterben
kapott formátummezőnek megfelelően
a $shotime-ban ebben az esetben
az aktuális dátumnál két héttel korábbi dátum lesz
UNIX formátumban (ami az 1970-től
eltelt másodpercek számát jelenti)
*/
break;
case "month":
$checkmonth="checked";
$showtime=mktime(date("H"),date("i"),date("s"),date("m")-1,date("d"),date("Y"));
break;
case "all":
$checkalltime="checked";
$showtime=mktime(0,0,0,0,0,0);
break;
case "week":
default:
$checkweek="checked";
$showtime=mktime(date("H"),date("i"),date("s"),date("m"),date("d")-7,date("Y"));
}
/*
a form megjelenítése és az eltárolt
beállítások újbóli kijelzése, a PHP script-ünket
itt egy kicsit megszakítjuk, mivel
a nem változó dolgokat célszerű direktben írni
a sebesség miatt
*/
?>
<HTML>
<HEAD>
<TITLE>Hiper-szuper vendégkönyv</TITLE>
</HEAD>
<BODY>
<FORM action='gbmain.php3'
method=post>
<TABLE>
<TR>
<TD width=30%>Rendezd az üzeneteket </TD>
<TR>
<TD width=30%>
<INPUT type=radio name=orderby value=date <?php echo"$checkdate"?>>
dátum <BR>
<INPUT type=radio name=orderby value=name <?php echo"$checkname"?>>
név <BR>
<INPUT type=radio name=orderby value=email <?php echo"$checkemail"?>>
e-mail cím szerint
<TD valign=center>
<INPUT type=radio name=way value=asc <?php echo"$checkasc"?>> növekvő
vagy <BR>
<INPUT type=radio name=way value=desc <?php echo"$checkdesc"?>> csökkenő
sorrendben
<TR>
<TD>Mutasd az elmúlt
<TR>
<TD width=30%>
<INPUT type=radio name=datefilter value=week <?php echo"$checkweek"?>>
hét <BR>
<INPUT type=radio name=datefilter value=twoweeks <?php echo"$checktwoweeks"?>>
2 hét <BR>
<INPUT type=radio name=datefilter value=month <?php echo"$checkmonth"?>>
hónap üzeneteit
<TD valign=center>inkább<INPUT type=radio name=datefilter value=all
<?php echo"$checkalltime"?>> Mutasd az összes üzenetet
</TABLE>
<!—
Itt használtuk fel a program elején
beállított $check.... változókat, így azokat a rádiógombok lesznek bejelölve
a submit gomb megnyomása után is amit előzőleg beállított a felhasználó
-->
<INPUT
type=submit>
</FORM>
<P>
<A href=gbaddmsg.html>Itt
lehet új üzenetet küldeni.</A>
<P>
<?php
/*
adatbázis megnyitása, és a lekérdezés
futtatása
PostgreSQL-t adatbázisszervert
használunk ebben a példában,
ennek tudhatóak be a pg_-vel kezdődő
függvények
*/
$gb=pg_connect("dbname=gb
user=nobody password=nobody") or die(";HIBA: Nem sikerült kapcsolódni az
adatbázishoz<BR>");
/*
csatlakozunk az adatbázis-szerverhez,
$gb-ben kapjuk vissza
a kapcsolat azonosítóját, ami 0
lesz akkor ha nem sikerült az akció
az "or die... " egy kicsit furcsának
tűnhet, de azért működik, mert az
értékadás kifejezésnek számít és
a pg_connect() függvény fail-t (azaz nullát)
ad vissza ha nem sikerül csatlakozni,
így a PHP tovább folytatja a kiértékelést,
ami ebben az esetben kilépteti
a scriptből egy hibaüzenet kíséretében
*/
/*
listázás az adattáblából, adott
ideig visszamenőleg,
a megadott mező szerint és a megadott
sorrendben rendezve
+ $shotime átalakítása stringé
(emlékezzünk UNIX idő volt benn eddig,
ami egy integer, tehát átalakul
a változó típusa)
*/
$showtime=date("D
M d H:i:s Y",$showtime);
$result=pg_exec($gb,"SELECT
* FROM msgs WHERE date BETWEEN '$showtime' and 'now' ORDER BY $orderby
$way") or die("HIBA: Nem kaptam adatot az adatbázisból");
/*
SQL lekérdezés a kapott adatokat
felhasználásával
a $result változóban kapjuk meg
a lekérdezés eredményének azonosítóját
*/
/*
kísérőinformáció kiírása (megerősítésként)
arról, hogy mi
kerül kilistázásra és hogyan lesz
rendezve
*/
echo "
<TABLE align=center width=500px>
<TR><TD align=left>Üzenetek
<TR><TD align=center><B>$showtime</B>
és <B>" . date("D M d H:i:s Y") . "között</B>
<TR><TD align=right><B>$orderby
szerint rendezve</B>:\n
</TABLE>";
/*
most jön a programnak értelmet
adó rész: az üzenetek megjelenítése
*/
?>
<TABLE width=100% cellspacing=0
cellpadding=0>
<?php
$empty=1;
while (list($msg,
$name, $email, $date) = pg_fetch_row($result))
/*
a pg_fetch_row egy tömbben adja
vissza minden híváskor a lekérdezésben
kapott rekordok közül a következőt
a list(), ami bár függvénynek tűnik,
de nem az, mert nincs visszatérési értéke,
hanem ellenkezőleg neki "ad értéket"
a pg_fetch_row, mégpedig egy tömböt,
amit a list szétbont a paramétereiben
megadott változókra, így kinyertük a tömbből
az aktuális rekord adatait
most jön a while ciklus törzse:
*/
{
echo " <TR>
<TD width=40% >Name: <B>" . htmlspecialchars($name) . "</B>
<TD>E-mail:<A href=mailto:" . htmlspecialchars($email) . ">" .
htmlspecialchars($email) . "
<TR>
<TD
colspan=2 align=left>Date: $date
<TR>
<TD>Message:<BR>
" . nl2br(htmlspecialchars($msg)) ."
</TABLE><BR>";
$empty=0;
}
/*
a htmlspecialchars() és az ln2br()
függvények a szövegek html-ben való normális
megjelenítéséhez szükséges átalakítását
végzik (pl <> jelek, újsor)
*/
if ($empty)
echo "<P align=center>(A
megadott intervallumban nincs üzenet)</P>\n";
else
echo "<P align=center><B>(nincs
több üzenet)";
pg_close($gb);
/*
csak a formalitás kedvéért írtam
a pg_close-t, ami bontja a kapcsolatot az
adatbázisszerverrel, mert a PHP
a script végeztével magától
felszabadít minden használt erőforrást
*/
/*
* lablec beszurasa
*/
include("./footer.html");
?>
</BODY>
</HTML>
Ennyi volt a példa, remélem sikerül megérteni többé-kevésbé, bár most nem azon volt a hangsúly, hanem hogy lássa az olvasó, hogy is néz ki a szintaktika, a nyelv struktúrája és fényt derítsünk a változók használatára is.
A következő szám fő témája a PHP telepítése lesz Windows és Linux platformokra.
Addig is néhány link, amit lehet bogarászni:
- a PHP hivatalos oldala: http://www.php.net
- http://www.phpwizard.net/ (szabadon felhasználható programgyűjtemény)
- http://www.phpbuilder.com/ (cikkek, programok)
- http://www.albasoftware.com/index.php3
- http://www.devshed.com/Server_Side/PHP/ (cikkek, példák)
- http://www.314interactive.com/io/content.php3?req=php&sec=intro (cikkek)


