Kihagyás

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:

Egyszerű PHP kód

Egyszerű PHP kód

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:

Változók tulajdonságainak kiíratása

Változók tulajdonságainak kiíratása

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-t

    echo 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
      
  • 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

    $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";
    
    VAGY
    $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

    $targyak = array(
        "BMEVIAUA203" => "Info 2",
        "BMEVIAUAV08" => "Webfejlesztés",
        "BMEVIMIA102" => "Digitális technika"
    );
    
    VAGY
    $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öbbdimenziós tömb - kimenet

Többdimenziós tömb - kimenet

Tömb elemeinek végigolvasása foreach ciklussal:

foreach($bme_targyak as $targykod => $targynev){
    echo "<b>".$targykod."</b>: " . $targynev . "<br/>";
}

Foreach ciklus - kimenet

Foreach ciklus - kimenet

Tömbökkel kapcsolatos hasznos függvények:

  • print_r($tomb): tömb tartalmának kiírása formázott szövegként

    • explode($elvalaszto, $string): egy stringet bont darabokra, a részeket tömbben adja vissza.
      $string_elemei = explode(", ","Első, második, harmadik");
      print_r($string_elemei);
      
      print_r - kimenet
      print_r - kimenet
  • implode($ragaszto, $reszek): az explode() párja, tömb elemei ragasztja össze egy String-é

    $keywords = array("webfejlesztés", "alapoktól", "CMS", "PHP");
    echo implode(", ", $keywords);
    
    Kimenet: “webfejlesztés, alapoktól, CMS, PHP”

  • array_keys($tomb): visszaadja az asszociatív tömb kulcsait egy tömbben

    $kulcsok = array_keys($bme_targyak);
    print_r($kulcsok);
    
    array_keys - kimenet
    array_keys - kimenet

  • in_array($mit, $tomb): Megvizsgálja, hogy a $mit szerepel-e értékként a $tomb-ben. Visszatérési értéke true vagy false.

    $mit = "dió";
    $tomb = array("körte", "alma", "dió");
    if(in_array($mit, $tomb))
        echo "Benne van a " . $mit;
    else
        echo "Nincs benne a " . $mit;
    
    Kimenet: “Benne van a dió”

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>
Kimenet:
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.

Állapotmentesség - példa

Állapotmentesség - példa

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

  1. Milyen különbségek vannak a PHP és egy erősen típusos nyelv (pl. C++) típuskezelése között?
  2. Mire jók a $_GET, $_POST, és $_REQUEST tömbök? Mit jelent az, hogy asszociatív tömb?
  3. Milyen vezérlési szerkezeteket használhatunk a PHP nyelvben?
  4. Mire jó a session kezelés?
  5. Milyen módszerekkel tudjuk egy másik .php fájl tartalmát felhasználni?
  6. Í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!
  7. Írj PHP kódot, ami kapcsolódik a localhost gépen található MySQL adatbázsszerverhez és utána bontja a kapcsolatot!
  8. Készíts PHP oldalt, amely listázza az autok(id, rendszam, szin) adatbázistábla minden sorát!

2025-08-04 Szerzők