Labor 05 Segédlet – Webfejlesztés (PHP)¶
A PHP nyelv címszavakban¶
- Szerveroldali szkript nyelv, vagyis a webszerveren történik a végrehajtása, nem a böngészőben.
- Gyengén típusos, vagyis a változóinak nincs explicit típusa (nem kell megadnunk, hogy pl. int vagy double típusú változóval szeretnénk dolgozni).
- Neve a PHP Hypertext Preprocessor rekurzív rövidítésből ered.
- Egy PHP forrásfájl tipikus kiterjesztése .php, .php3 vagy .phtml.
- A PHP forrásfájlokat a webszerver értelmezi és futtatja - a generált HTML kimenetet pedig visszaküldi a böngészőnek.
- Sokféle adatbázis szerverrel képes együttműködni (MySQL, MSSQL, PosgreSQL, Oracle, stb...)
- Ingyenes, nyílt forráskódú platform, emiatt szinte minden tárhelyszolgáltatónál elérhető.
- Windowson és Linuxon is használható.
- MySQL-el kombinálva teljes értékű webalkalmazás készíthető a segítségével.
- Viszonylag gyorsan tanulható.
- Egy PHP forrásfájl vegyesen tartalmazhat szöveget, HTML elemeket és forráskódot.
A PHP nyelv felépítése¶
Minden PHP forrásfájlban vegyesen fordulhat elő konstans szöveg és futtatandó PHP nyelvű forráskód. A php kódot minden esetben <?php és ?> jelek közé kell zárni az alábbihoz hasonló módon:
Ha változtattunk a forrásfáljon, annak eredménye mindig csak azután lesz látható, hogy a fájlt elmentettük és utána a böngészőben frissítettük az oldalt.
Gyengén típusos nyelv¶
PHP-ban a változókat bárhol deklarálhatjuk, a tartalmuknak megfelelő típussal jönnek létre, ami később dinamikusan változhat. Ha olyan változót próbálnuk használni ami még nem létezik, akkor az magától létrejön. A változó nevek dollár jellel ($) kezdődnek, második karakterük nem lehet szám (csak betű vagy alulvonás karakter), és nem lehet benne szóköz. Például:
$welcome = "Első PHP oldalam";
Próbaképpen hozzunk létre három különböző típusú változót, majd a var_dump($valtozo) függvénnyel írassuk ki a tulajdonságaikat!
<body>
<?php
$szoveg = "Első PHP oldalam";
$szam = 12;
$logikai_ertek = false;
var_dump($szoveg);
var_dump($szam);
var_dump($logikai_ertek);
?>
</body>
Eredmény:
String műveletek¶
A PHP nyelv elsődleges célja szöveges (HTML) kimenet generálása, ezért a nyelv gazdag sztringműveletekben. Ezek közül a legfontosabbak:
-
Összefűzés pont karakterrel
$elso = "Hello"; $masodik = "World"; $szoveg = $elso . " " . $masodik . "!"; echo $szoveg; // "Hello World!" -
Szöveg hossza:
strlen($szoveg)echo strlen($szoveg); // 12 -
Szövegrész keresés:
strpos($miben, $mit). Ha tartalmazza, akkor az első találat indexét adja vissza, ellenkező esetben false-techo strpos($szoveg, "World"); // 6
Operátorok¶
A PHP nyelvben használható operátorok hasonlítanak C nyelvű társaikhoz, de van néhány eltérés: - Minden “szokásos” operátor használható (+, -, *, /, %)
- Mivel a PHP egy gyengén típusos nyelv, így egy változó típusa változhat a futás során
- Lehetőség van típus szerinti egyezést is ellenőrizni az === operátorral (párja: !==). Nem csak primitív típusokra, hanem pl. asszociatív tömbökre is használható:
$x == $y // igaz, ha egyezik az érték, pl. 5==8 hamis, 5=="5" igaz $x === $y // igaz, ha egyezik az érték és a típus // pl. 5==="5" hamis, 5===5 igaz
- Lehetőség van típus szerinti egyezést is ellenőrizni az === operátorral (párja: !==). Nem csak primitív típusokra, hanem pl. asszociatív tömbökre is használható:
-
PHP-ban megszokott, hogy egy függvény különböző típusú visszatérési értékkel rendelkezik, például egy adatbázis táblában keresés a rekordot adja vissza találat esetén, egyébként null-t. Ilyenkor jól jön a visszaadott érték típus ellenőrzése az === operátorral.
-
Logikai operátorok: vagy: ||, és: &&
Vezérlési szerkezetek¶
- if, if..else ugyanúgy, mint más nyelvekben
$nap = "péntek"; // a hét aktuális napjának lekérése if($nap == "szombat" || $nap == "vasárnap"){ echo "Jó hétvégét!"; } else{ echo "Jó napot!"; } - Többszörös ág esetén: if..elseif..else
$nap = "péntek"; // hét aktuális napjának lekérése if($nap == "szombat" || $nap == "vasárnap"){ echo "Jó hétvégét!"; } elseif($nap == "péntek"){ echo "Mindjárt hétvége!"; } else{ echo "Jó napot!"; } - switch működik Stringekre is!
$nap = "péntek"; // hét aktuális napjának lekérése switch($nap){ case "hétfő": // ha hétfő van echo "A hét első napja"; break; case "szombat": // ha szombat case "vasárnap": // vagy vasárnap echo "Hétvége! "; break; default: // minden más esetben echo "Sima hétköznap"; break; } - for: ugyanúgy mint a többi nyelvben
for($i=0 ; $i<15 ; $i++){ echo $i." | "; }
Tömbök¶
A PHP tömbkezelése sokkal kifinomultabb a C nyelvénél: a PHP tömbök nem csak pozicióval, hanem tetszőleges típusú értékekkel címezhetők. Ebben az esetben asszociatív tömbökről beszélünk. Az asszociatív tömbök jól használhatók kulcs-érték párok tárolására:
$config[ "email" ] = "webmaster@aut.bme.hu";
$config[ "logfile" ] = "C:\log.txt";
Gyakran használunk többdimenziós asszociatív tömböket struktúrált adatok tárolására.
A tömbök előnyei:
- Egy változóban több érték
- Kulcs-érték párkét tárolható
- Tetszőlegesen sok dimenziós lehet
- Asszociatív (szöveges kulcs) is engedélyezett
Tömbök jellemzői PHP-ban:
- Indexelés szögletes zárójelben, pl.
echo $autok[2]; - Az index 0-ról indul
- Ha nem írunk indexet, akkor a következő elemre mutat a pointer, lásd numerikus tömbök
- Nem kötelező deklarálni, az első értékadáskor létrejön, lásd numerikus tömbök
Tömbök típusai:
-
Numerikus – a kulcsok a tömb elemek indexei
VAGY$targyak = array("Info 2","Webfejlesztés","Digitális technika");VAGY$targyak[0] ="Info 2"; // NEM deklaráltuk, futásidőben létrejön ha elkezdjük használni $targyak[1] = $targyak = array("Info 2","Webfejlesztés","Digitális technika");VAGY$targyak[0] ="Info 2"; // NEM deklaráltuk, futásidőben létrejön ha elkezdjük használni $targyak[1] ="Webfejlesztés"; $targyak[2] ="Digitális technika";$targyak[] ="Info 2"; // nem írtunk indexet, ez lesz a 0. elem $targyak[] ="Webfejlesztés"; // 1. elem $targyak[] ="Digitális technika"; // 2. elem -
Asszociatív – a kulcsok nem indexek, hanem Stringek
VAGY$targyak = array( "BMEVIAUA203" => "Info 2", "BMEVIAUAV08" => "Webfejlesztés", "BMEVIMIA102" => "Digitális technika" );$targyak["BMEVIAUA203"] = "Info 2"; $targyak["BMEVIAUAV08"] = "Webfejlesztés"; $targyak["BMEVIMIA102"] = "Digitális technika"; -
Többdimenziós – olyan tömb, ami további tömböket tartalmaz
$bme_targyak = array( "BMEVIAUA203" => "Info 2", "BMEVIAUAV08" => "Webfejlesztés", "BMEVIMIA102" => "Digitális technika" ); $elte_targyak = array( "ELTE123" => "Analízis 1", "ELTE345" => "Analízis 2", "ELTE2553443" => "Diszkrét matematika" ); $ossz_targyak = array( "BME" => $bme_targyak, "ELTE" => $elte_targyak ); print_r($ossz_targyak);
Tömb elemeinek végigolvasása foreach ciklussal:
foreach($bme_targyak as $targykod => $targynev){
echo "<b>".$targykod."</b>: " . $targynev . "<br/>";
}
Tömbökkel kapcsolatos hasznos függvények:
-
print_r($tomb):tömb tartalmának kiírása formázott szövegként -
implode($ragaszto, $reszek):azexplode()párja, tömb elemei ragasztja össze egy String-éKimenet: “webfejlesztés, alapoktól, CMS, PHP”$keywords = array("webfejlesztés", "alapoktól", "CMS", "PHP"); echo implode(", ", $keywords); -
array_keys($tomb):visszaadja az asszociatív tömb kulcsait egy tömbben$kulcsok = array_keys($bme_targyak); print_r($kulcsok);
array_keys - kimenet -
in_array($mit, $tomb):Megvizsgálja, hogy a$mitszerepel-e értékként a$tomb-ben. Visszatérési értéke true vagy false.Kimenet: “Benne van a dió”$mit = "dió"; $tomb = array("körte", "alma", "dió"); if(in_array($mit, $tomb)) echo "Benne van a " . $mit; else echo "Nincs benne a " . $mit;
Függvények¶
PHP-ban nagyon egyszerűen hozhatunk létre és hívhatunk meg függvényeket. Egy függvénynek tetszőleges mennyiségű bemenő paramétere van és lehet visszatérési értéke is, de ez nem kötelező. A függvények használatát leggyorsabban egy példán keresztül érthetjük meg:
<!DOCTYPE html>
<html>
<head></head>
<body>
<?php
/* függvények elkészítése */
function print_hello() {
print( "Sziasztok! <br />" );
}
function return_hello( $name ) {
return "Hello " . $name . "!";
}
/* függvények használata */
print_hello();
print( return_hello( "világ" ) );
?>
</body>
</html>
Sziasztok!
Hello világ!
Session kezelés¶
A HTTP alapvetően állapotmentes protokoll, azaz a kérések kiszolgálása egymástól teljesen függetlenül történik – például nem tudjuk, hogy az előző kérés melyik felhasználótól származik.
A fenti ábra alapján a webszerver a következőket érzékeli állapotmentes protokoll esetén: - Óra a kosárba - Angry bird a kosárba - Megrendelés: Óra és Angry bird megrendelése
Ekkor hibásan az első megrendelésbe belerakja a madarat is, pedig annak a másik felhasználóhoz kéne tartoznia!
Megoldás: felhasználói munkamenet (session) azonosítása és követése.
termeklista.php:
session_start();
$_SESSION["userId"] = 1; // speciális változó
$_SESSION["kosar"][] = "Óra";
megrendeles.php:
session_start();
$kosar = $_SESSION["kosar"]; // = array("Óra")
Adatok fogadása és küldése¶
Egy HTML űrlap mezőinek tartalma a webszerverre kétféle módon juthat el:
- GET: Az URL-ben generálódnak paraméterek, például: "login.php?email=tivadar@gmail.com&jelszo=alma"
- POST: URL-től függetlenül egy asszociatív tömbben utaznak az adatok
A form HTML oldalon:
<form action="login.php" method="get|post">
E-mail cím: <input type="text" name="email" /><br/>
Jelszó: <input type="password" name="jelszo" /><br/>
<input type="submit" value="Bejelentkezés!" />
</form>
A kapott adat feldolgozására PHP oldalon két különleges tömböt használhatunk. Amennyiben az űrlapon method="get"-et állítottunk be, akkor szerver oldalon a $_GET asszociatív tömbből olvashatjuk ki az adatokat. A tömb kulcsai az űrlapon lévő input mezők name attribútumainak értékei, például a fenti HTML form esetén az e-mail címet a $_GET["email"], a jelszót pedig a $_GET["jelszo"] tartalmazza. Ugyanez method="post" esetén: $_POST["email"] és $_POST["jelszo"].
GET-ben, azaz URL-be belefűzve nem csak űrlap elküldés során adhatunk értéket egy szerver oldali kódnak, hanem például linkek megnyitásával is:
$email = $_GET["email"];
$jelszo = $_GET["jelszo"];
Ha az űrlapon POST-ra állítottuk a method attribútumot:
$email = $_POST["email"];
$jelszo = $_POST["jelszo"];
A $_GET és a $_POST tömböket egyesítve tartalmazza a $_REQUEST tömb:
$email = $_REQUEST["email"];
$jelszo = $_REQUEST["jelszo"];
MySQL integráció¶
A szerver oldali fejlesztés szinte mindig együtt jár adatbázis használatával, melyek közül mi a MySQL-t használjuk. A PHP nyelv lehetőséget teremt az adatbázisok teljeskörű elérésére és manipulálására. MySQL mellett még számos más különböző típusú adatbázis használható. Ezek egységes kezeléséhez a PDO osztálykönyvtárat használjuk.
Az adatbázissal való együttműködés során az alábbi függvényeket használjuk a leggyakrabban:
$db = new PDO(...): kapcsolatot épít fel a PHP program és egy adott szerveren futó adatbázisszerver között.$result = $db->query(...): segítségével egy SQL utasítást futtathatunk.$statement = $db->prepare(...): segítségével előkészítünk egy prepared statement-et.$statement->bindParam(...): segítségével paramétereket rendelünk a prepared statement-hez.$statement->execute(...): segítségével lefuttatjuk a prepared statement-et.$result->fetch(...): egy SQL parancs eredményén (például a lekérdezett könyvek listáján) haladhatunk végig a segítségével.$result->closeCursor();: eredmények felszabadítása.
Az alábbi példában a localhost gépen futó MySQL adatbázisszerver konyvtar nevű adatbázisának a konyv táblájából kérdezzük le a nyilvántartott könyvek azonosítóját és címét:
<?php
try {
$db = new PDO("mysql:host=localhost;dbname=konyvtar", "mysql_username", "mysql_password");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
printf('Sikertelen kapcsolódás: ' . $e->getMessage());
exit;
}
$result = $db->query("SELECT id, cim FROM konyv");
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
printf("ID: %s Cím: %s", $row["id"], $row["cim"]);
}
$result->closeCursor();
?>
Az alábbi példa név-telefonszám párosokat ment el a telefonkonyv adatbázis phonebook táblájába:
<!DOCTYPE html>
<html>
<head></head>
<body>
<form method="post">
Név: <input type="text" name="nev" />
<br />
Telefonszám: <input type="text" name="szam" />
<br />
<input type="submit" name="ok" value="ok" />
</form>
<?php
if( isset( $_POST[ "ok" ] ) ) {
$name = $_POST[ "nev" ];
$number = $_POST[ "szam" ];
try {
$db = new PDO("mysql:host=localhost;dbname=telefonkonyv", "mysql_username", "mysql_password");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
printf('Sikertelen kapcsolódás: ' . $e->getMessage());
exit;
}
$statement = $db->prepare("INSERT INTO phonebook ( name, number ) VALUES ( :name, :number )");
$statement->bindParam(':name', $name, PDO::PARAM_STR);
$statement->bindParam(':number', $number, PDO::PARAM_STR);
$statement->execute();
}
?>
</body>
</html>
Több PHP fájl használata¶
Azokat a programrészeket, amiket gyakran használunk – például az adatbázishoz történő kapcsolódást – érdemes csak egyszer elkészíteni és utána mindig ezt az implementációt használni. Ennek a legegyszerűbb módja, ha ezekre a részekre egy függvényt készítünk és ezt egy önálló PHP fájlba (pl. seged.php) tesszük. Később ha szükség van erre a függvényre, akkor csak betöltjük az őt tartalmazó fájlt és használjuk a függvényt. Ezt a betöltést többféleképpen is megtehetjük, de a legegyszerűbb és legbiztonságosabb módszer a require_once("seged.php") utasítás használata.
Az alábbi példa az adatbázisműveleteket szervezi ki egy újrahasznosítható segédfájlba:
db-helper.php:
<?php
$db_server = "localhost";
$db_user = "mysql_user";
$db_password = "mysql_password";
$db_default = "telefonkonyv";
function connectDB(): PDO
{
global $db_server, $db_user, $db_password, $db_default;
try {
$db = new PDO("mysql:host=$db_server;dbname=$db_default", $db_user, $db_password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $db;
} catch (PDOException $e) {
echo 'Sikertelen kapcsolódás: ' . $e->getMessage();
exit;
}
}
function insertDB($db, $nev, $szam ) {
$statement = $db->prepare("INSERT INTO phonebook ( name, number ) VALUES ( :name, :number )");
$statement->bindParam(':name', $name, PDO::PARAM_STR);
$statement->bindParam(':number', $number, PDO::PARAM_STR);
$statement->execute();
}
?>
adatbevitel.php:
<!DOCTYPE html>
<html>
<head></head>
<body>
<form method="post">
Név: <input type="text" name="nev" />
<br />
Telefonszám: <input type="text" name="szam" />
<br />
<input type="submit" name="ok" value="ok" />
</form>
<?php
require_once( "db-helper.php" );
if( isset( $_POST[ "ok" ] ) ) {
$db = connectDB();
insertDB( $db, $_POST["nev"], $_POST["szam"] );
}
?>
</body>
</html>
A másik gyakori eset, hogy az oldalaink közös részeit (például a menüt) helyezzük egy külső fájlba és utána az egyes oldalainkon a menüt mindig ebből a fájlból töltjük be. A legegyszerűbb ilyenkor az include utasítás használata. Erre mutatnak példát az alábbi kódrészletek:
header.php:
<!DOCTYPE html>
<html>
<head></head>
<body>
<a href="home.php">Kezdőoldal</a> |
<a href="blog.php">Blog</a> |
<a href="contact.php">Kapcsolat</a>
footer.php:
// ide jön a lábléc további tartalma
</body>
</html>
home.php:
<?php
include("header.php");
<br />
// ide jöhet az oldal tartalma
include("footer.php");
?>
Ellenőrző kérdések¶
- Milyen különbségek vannak a PHP és egy erősen típusos nyelv (pl. C++) típuskezelése között?
- Mire jók a
$_GET,$_POST, és$_REQUESTtömbök? Mit jelent az, hogy asszociatív tömb? - Milyen vezérlési szerkezeteket használhatunk a PHP nyelvben?
- Mire jó a session kezelés?
- Milyen módszerekkel tudjuk egy másik .php fájl tartalmát felhasználni?
- Írj egy PHP függvényt, mely kiszámolja a paraméterül kapott szám faktoriálisát és az eredményt kiírja!
- Írj PHP kódot, ami kapcsolódik a localhost gépen található MySQL adatbázsszerverhez és utána bontja a kapcsolatot!
- Készíts PHP oldalt, amely listázza az
autok(id, rendszam, szin)adatbázistábla minden sorát!





