# PHP és adatbázisok: PDO és mysqli

> PHP és adatbázisok elmagyarázva: PDO és mysqli összehasonlítása, prepared statementek, hibakezelés a PHP 8 óta és biztonságos hozzáférési adatok üzem közben.

Forrás: https://phpsos.de/hu/php/php-und-datenbanken/  
Állapot: 2026. 10. 25.  
Szolgáltató: PHP SOS, PHP-vészhelyzeti segítség és szerverbiztonság. Azonnali segítség WhatsAppon: https://wa.me/491736494914?text=%C3%9Cdv%C3%B6zl%C3%B6m%2C%20PHP%20SOS%21%20Seg%C3%ADts%C3%A9gre%20van%20sz%C3%BCks%C3%A9g%C3%BCnk%20a%20PHP-szerver%C3%BCnkkel.%20C%C3%A9g%3A%20%E2%80%A6%20Weboldal%3A%20%E2%80%A6

**Röviden:** A PHP két elterjedt felületen keresztül fér hozzá az adatbázisokhoz: a PDO (PHP Data Objects) sok adatbázis-rendszerrel dolgozik egységes felületen, a mysqli a MySQL-re és a MariaDB-re van szabva. Mindkettővel a prepared statementek, vagyis a helyőrzős lekérdezések megbízhatóan védenek az SQL-injekció ellen. A PHP 8.0 (PDO), illetve 8.1 (mysqli) óta mindkettő alapértelmezetten kivételként jelzi a hibákat.

## Hogyan beszél a PHP az adatbázisokkal

Szinte minden PHP-alkalmazás adatbázisban tárolja a tartalmait: oldalakat, rendeléseket, felhasználói fiókokat, beállításokat. A PHP-szkript ehhez kapcsolatot létesít, SQL nyelven lekérdezést küld, és feldolgozza az eredményt. A hozzáférési adatok többnyire egy konfigurációs fájlban állnak ugyanazon a szerveren.

Az ügyvezetés számára ez azért fontos, mert az adatbázis többnyire a vállalkozás legértékesebb adatait tartalmazza. Aki a webszerveren kódot tud végrehajtani, az általában a konfigurációs fájlt is el tudja olvasni, és ezekkel a hozzáférési adatokkal hozzáférhet az adatbázishoz.

## PDO és mysqli összehasonlítva

| Jellemző | PDO | mysqli |
|---|---|---|
| Adatbázisok | sok, olyan illesztőprogramokon keresztül, mint a `PDO_MYSQL`, `PDO_PGSQL`, `PDO_SQLITE`, `PDO_SQLSRV`, `PDO_OCI` | MySQL és MariaDB |
| Helyőrzők | elnevezett (`:name`) és pozicionális (`?`) | pozicionális (`?`) |
| Stílus | objektumorientált | objektumorientált és procedurális |
| Hiba kivételként | alapértelmezett a PHP 8.0.0 óta | alapértelmezett a PHP 8.1.0 óta |
| Rövid forma paraméteres lekérdezésekhez | `prepare()` és `execute()` tömbbel | `execute_query()` a PHP 8.2.0 óta |

A gyakorlatban gyakran a keretrendszer vagy a CMS dönt. Sok saját adatbázisréteget hoz magával, amely belsőleg a PDO-t vagy a mysqli-t használja. Aki átvesz egy alkalmazást, a forráskódban végzett egyszerű kereséssel megállapíthatja, melyik felületet használják, és hol keletkeznek lekérdezések:

```bash
# Hol létesít kapcsolatot az alkalmazás, hol keletkeznek lekérdezések?
grep -rn --include='*.php' -E 'new PDO|new mysqli|mysqli_connect|->query\(' /var/www/app/src | head -50
```

A `->query(` találatok nem automatikusan veszélyesek. Megérdemelnek azonban egy második pillantást, mert ott az értékek közvetlenül az SQL-szövegbe kerülhetnek, ahelyett, hogy helyőrzőkön keresztül adnák át őket. Éppen a régebbi projektek keverik a két stílust, és az ellenőrzés minden nagyobb frissítés előtt megéri.

## Prepared statementek: a legfontosabb minta

Prepared statementnél a lekérdezést helyőrzőkkel küldik az adatbázisnak, az értékeket pedig külön adják át. A PHP-kézikönyv szerint ez véd az SQL-injekció ellen, ha minden felhasználói bevitel helyőrzőkön keresztül halad.

```php
<?php
declare(strict_types=1);

$pdo = new PDO(
    'mysql:host=localhost;dbname=shop;charset=utf8mb4',
    $dbUser,
    $dbPass,
    [PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]
);

$stmt = $pdo->prepare('SELECT id, name FROM kunden WHERE plz = :plz AND aktiv = :aktiv');
$stmt->execute(['plz' => $plz, 'aktiv' => 1]);

foreach ($stmt as $zeile) {
    echo htmlspecialchars($zeile['name'], ENT_QUOTES, 'UTF-8'), "\n";
}
```

Ugyanez a mysqli-vel a PHP 8.2 óta létező rövid formában:

```php
<?php
$db = new mysqli('localhost', $dbUser, $dbPass, 'shop');
$ergebnis = $db->execute_query('SELECT id, name FROM kunden WHERE plz = ?', [$plz]);

foreach ($ergebnis as $zeile) {
    echo htmlspecialchars($zeile['name'], ENT_QUOTES, 'UTF-8'), "\n";
}
```

A fejlesztőknek két korlátot kell ismerniük. A helyőrzők nem állhatnak idézőjelek között; `LIKE` keresésnél a `%` helyettesítő karakterek az átadott értékbe tartoznak. És a helyőrzők csak értékeket helyettesítenek, tábla- vagy oszlopneveket nem. Hogy az ilyen különleges eseteket hogyan lehet biztonságosan megoldani, azt az [SQL-injekció megelőzése PHP-ban](https://phpsos.de/hu/ratgeber/sql-injection-php/) útmutató mutatja.

## Hibakezelés: kivételek néma hibák helyett

Korábban mindkét felület alapértelmezetten némán dolgozott: egy sikertelen lekérdezés `false` értéket adott, és aki ezt nem ellenőrizte, üres adatokkal dolgozott tovább. Ez megváltozott:

- **PDO:** A PHP 8.0.0 óta a `PDO::ERRMODE_EXCEPTION` az alapértelmezett. A hibák `PDOException` kivételt dobnak.
- **mysqli:** A PHP 8.1.0 óta a hibajelzés a `MYSQLI_REPORT_ERROR` és a `MYSQLI_REPORT_STRICT` értékre van állítva. A hibák `mysqli_sql_exception` kivételt dobnak; korábban a jelzés ki volt kapcsolva.

A biztonság szempontjából ez azt jelenti: a kivételeket el kell kapni és naplózni kell, de soha nem szabad SQL-szöveggel, táblanevekkel vagy hozzáférési adatokkal a böngészőben végezniük. Hogyan lehet ezt tisztán szétválasztani, azt a [Hibák és kivételek a PHP-ban](https://phpsos.de/hu/php/fehler-und-exceptions/) oldal írja le.

## Hozzáférési adatok és jogok helyes kiosztása

Az adatbázis csak annyira védett, mint a hozzáférési adatai. Ezek a szabályok váltak be:

1. **Alkalmazásonként külön felhasználó:** Soha ne használja az adatbázis adminisztrátorát a weboldalhoz.
2. **Csak a szükséges jogok:** Egy weboldalnak többnyire olvasásra, írásra, módosításra és törlésre van szüksége a saját adatbázisában, más adatbázisokra vagy szerverfunkciókra vonatkozó jogokra viszont nincs.
3. **Ok nélkül ne legyen távoli kapcsolat:** Az adatbázisnak csak a webszerverről szabad elérhetőnek lennie, az internetről nem.
4. **A hozzáférési adatok a webgyökéren kívül:** A konfigurációs és `.env` fájlok nem lehetnek URL-en keresztül lekérhetők. Erről bővebben a [A hozzáférési adatok és a .env fájlok védelme](https://phpsos.de/hu/blog/env-dateien-schuetzen/) cikkben.
5. **Titkosított kapcsolat szétválasztott szervereknél:** Ha az adatbázis másik gépen van, a kapcsolatnak titkosítottan kell futnia, hogy a hozzáférési adatok és a tartalmak ne haladjanak nyílt szövegként a hálózaton.
6. **Külön hozzáférések a karbantartáshoz:** Az adatmentés, a kiértékelések és az adminisztrátorok saját felhasználót kapnak. Így a naplóból nyomon követhető, ki mit tett, és egy hozzáférés a weboldal zavarása nélkül zárolható.

## Adatbázisok, PHP2Shell és az éles eset

A PHP2Shell nem magát az adatbázist érinti, hanem a PHP-értelmezőt: a CVE-2026-109618 és a CVE-2026-109619 bejelentkezés nélkül lehetővé teszi kártékony kód végrehajtását. Ha ez sikerül, a kód a PHP-folyamat jogaival fut, és így általában el tudja olvasni az adatbázis hozzáférési adatait tartalmazó konfigurációs fájlt. A prepared statementek ez ellen nem segítenek, mert a támadás egyáltalán nem SQL-lekérdezésen keresztül zajlik.

Kötelező ezért a PHP 8.5.12, 8.4.27, 8.3.36 vagy 8.2.35 verzióra való frissítés és az összes PHP-folyamat újraindítása. Ha vannak jelek sikeres támadásra, új adatbázis-hozzáférési adatok, az adatbázis ellenőrzése beinjektált tartalmak szempontjából, és a GDPR szerinti bejelentési kötelezettség értékelése is hozzátartozik. Itt egy strukturált [Incident Response](https://phpsos.de/hu/leistungen/incident-response/) értelmes.

> **Tipp:**
> Az adatbázisjelszavakat csak a szerver megtisztítása után változtassa meg. Amíg kártékony kód fut, az az új hozzáférési adatokat is újra ki tudja olvasni.

## Hogyan segít konkrétan a PHP SOS?

- Ellenőrizzük, hogyan fér hozzá az alkalmazása az adatbázishoz, és hogy a felhasználók, a jogok és a hálózati hozzáférés megfelelnek-e a minimumnak.
- Ellenőrizzük, hogy a konfigurációs és hozzáférési fájlok a webgyökéren kívül vannak-e, és nem érhetők-e el nyilvánosan.
- Incidens után a megfelelő sorrendben megújítjuk a hozzáférési adatokat, és megvizsgáljuk az adatbázist beinjektált kód szempontjából.
- Az eredményeket úgy dokumentáljuk, hogy az adatvédelmi felelősök és a biztosítók nyomon követhessék.


## Gyakori kérdések

**PDO-t vagy mysqli-t használjak?**  
Új projektekhez a PDO többnyire a rugalmasabb választás, mert sok adatbázissal dolgozik ugyanazon a felületen. A mysqli akkor értelmes, ha kizárólag MySQL-t vagy MariaDB-t használ, és szüksége van azok különleges funkcióira. Mindkettő biztonságos, ha a prepared statementeket következetesen használják.

**A PDO hiba esetén automatikusan kivételt dob?**  
Igen, a PHP 8.0.0 óta a PDO::ERRMODE_EXCEPTION az alapértelmezett. Korábban a néma mód volt az, amelyben a hibák csak az errorCode() és az errorInfo() útján voltak lekérdezhetők. A régebbi alkalmazások a módot gyakran még kifejezetten beállítják.

**A helyőrzők helyettesíthetnek tábla- vagy oszlopneveket is?**  
Nem. A helyőrzők csak értékeket helyettesítenek. A tábla- és oszlopneveket, például egy rendezéshez, ellenőrizni kell az engedélyezett nevek rögzített listájával, mielőtt behelyettesítik őket a lekérdezésbe.

**A PHP2Shell után meg kell változtatnom az adatbázis jelszavát?**  
Pusztán a frissítés ezt nem követeli meg. Ha viszont vannak jelek arra, hogy a szerver kompromittálódott, a konfigurációs fájlokban lévő összes hozzáférési adat ismertnek tekintendő. Ilyenkor a takarítás után újítsa meg őket.

## Források

- [PHP-kézikönyv: PDO prepared statementek](https://www.php.net/manual/en/pdo.prepared-statements.php)
- [PHP-kézikönyv: PDO hibakezelés](https://www.php.net/manual/en/pdo.error-handling.php)
- [PHP-kézikönyv: mysqli::execute_query](https://www.php.net/manual/en/mysqli.execute-query.php)
- [PHP-kézikönyv: mysqli_driver::$report_mode](https://www.php.net/manual/en/mysqli-driver.report-mode.php)
