Kihagyás

10.2. fejezet

A fejezet anyaga

Kivételkezelés

A kivétel fogalma

A programvégrehajtás során bekövetkezhet olyan nem várt esemény, amely meggátolja a program futását az adott blokkban. PHP-ban ebben az esetben úgynevezett kivétel dobódik.

Példa: A nullával való osztás egy DivisionByZeroError típusú kivételt eredményez

1
2
3
4
<?php
  $szentsegtores = 5 / 0;
  echo "Mérges matematikus hangok...";
?>

A kód kimenete

Fatal error: Uncaught DivisionByZeroError: Division by zero in C:\xampp\htdocs\test.php:2 Stack trace: #0 {main} thrown in C:\xampp\htdocs\test.php on line 2

PHP-ban kétféle kivételtípust különböztetünk meg:

  • az Error-ok belső PHP hibákat reprezentálnak
  • az Exception-ök programozói hibákat jelölnek.

Az Error és az Exception osztályok mindketten a Throwable interfészt valósítják meg, amely minden PHP-beli kivétel közös interfésze. A beépített kivételek az Error vagy az Exception osztályokból származnak. Ezt a hierarchiát szemlélteti az alábbi ábra.

PHP kivételek

Kivétel dobása

A throw utasítással mi magunk is dobhatunk manuálisan egy kivételt. A throw kulcsszó után meghívjuk annak a kivételosztálynak a konstruktorát, amilyen típusú kivételt el szeretnénk dobni. PHP-ban (Javával ellentétben) sehol sem kell jelezni a kivételdobást.

1
2
3
<?php
  throw new Exception();    // Exception típusú kivétel dobása
?>

A kivételosztály példányosításakor a konstruktornak átadhatunk egy szöveget is paraméterben, ekkor ez lesz a kivétel üzenete (hibaüzenet).

1
2
3
<?php
  throw new Exception("Valamit elszúrtunk...");
?>

Kivételek kezelése

Ha a programban valahol egy kivétel el lett dobva, akkor azt el is tudjuk kapni. PHP-ban a kivételkezelésre a try, catch és finally utasításokat használjuk, a Javához hasonló módon.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?php
  try {
    // a kód azon része, ahol kivétel dobódhat
  } catch (DivisionByZeroError $exc) {
    // DivisionByZeroError típusú kivétel elkapása ($exc-ként hivatkozhatunk rá)
  } catch (Exception $exc) {
    // Exception típusú kivétel elkapása ($exc-ként hivatkozhatunk rá)
  } catch (Error $err) {
    // Error típusú kivétel elkapása ($err-ként hivatkozhatunk rá)
  } finally {
    // mindenképpen lefutó kódrész
  }
?>

Több catch ág esetén a legelső olyan fog lefutni, amely a dobott kivétel típusára illeszkedik.

Példa: Írjunk egy osztás függvényt, amely két egész paramétert vár ($a és $b), visszatérési értéke pedig az $a/$b hányados! Ha nem egész típusú paramétereket kapunk vagy ha nullával szeretnénk osztani, akkor dobjunk kivételt!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
  function osztas($a, $b) {
    if (is_int($a) && is_int($b)) {
      if ($b === 0)
        throw new DivisionByZeroError("Ejnye, nullával nem osztunk!");  // kivétel dobása
      return $a / $b;
    }

    throw new TypeError("Egész paramétereket adj meg!");                // kivétel dobása
  }

  // kivételkezelés

  try {
    echo osztas(5, 2) . "<br/>";
    echo osztas(5, 0) . "<br/>";
    echo osztas(3, 2) . "<br/>";
  } catch (DivisionByZeroError $dze) {
    echo $dze->getMessage() . "<br/>";      // kivétel szövegének kiíratása
  } catch (TypeError $te) {
    echo $te->getMessage() . "<br/>";
  } catch (Error $err) {
    echo "Nem várt hiba történt a program futása során! <br/>";
  } catch (Exception $exc) {
    echo "Nem várt hiba történt a program futása során! <br/>";
  } finally {
    echo "--- Kivételkezelés vége. --- <br/>";
  }
?>

A kód kimenete

2.5 Ejnye, nullával nem osztunk! --- Kivételkezelés vége. ---

Saját kivételosztályok

Ha szeretnénk, akkor PHP-ban akár saját kivételosztályt is írhatunk. A létrehozni kívánt kivételosztályt valamely létező kivételosztályból kell örököltetnünk (jellemzően az Exception osztályból vagy annak valamelyik gyermekosztályából szoktunk öröklődni).

Példa: Saját kivételosztály írása

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<?php
  class NincsPisztaciaException extends Exception {   // egy Exception-ből származó kivételosztály
    public function __construct($uzenet) {
      parent::__construct($uzenet);                   // ősosztály konstruktorának meghívása
    }
  }

  try {
    $fagyi_izek = ["vanília", "szamóca", "málna", "karamell"];

    if (!in_array("pisztácia", $fagyi_izek))
      throw new NincsPisztaciaException("A pisztácia kifogyott!");
  } catch (NincsPisztaciaException $npe) {
    echo $npe->getMessage();
  }
?>

A kód kimenete

A pisztácia kifogyott!


Utolsó frissítés: 2024-02-10 17:23:02