# Objektově orientované programování v PHP

> Objektové programování v PHP: třídy, rozhraní, traity a enumy, novinky jazyka od PHP 8.0 do 8.4 a souvislost s deserializací a bezpečností.

Zdroj: https://phpsos.de/cs/php/objektorientierung/  
Stav: 25.10.2026  
Poskytovatel: PHP SOS, Nouzová pomoc pro PHP a bezpečnost serverů. Okamžitá pomoc přes WhatsApp: https://wa.me/491736494914?text=Dobr%C3%BD%20den%2C%20PHP%20SOS%2C%20pot%C5%99ebujeme%20pomoc%20s%20na%C5%A1%C3%ADm%20PHP%20serverem.%20Firma%3A%20%E2%80%A6%20Web%3A%20%E2%80%A6

**Stručně:** Objektově orientované programování (OOP) shrnuje data a příslušné funkce do tříd. PHP k tomu nabízí třídy, abstraktní třídy, rozhraní, traity a od PHP 8.1 enumy. S PHP 8.0 až 8.4 přibylo mnoho jazykových prostředků, například constructor promotion, `readonly`, property hooks a asymetrická viditelnost. Pro bezpečnost je důležité: dobře zapouzdřený kód se snáze kontroluje a magické metody dělají nebezpečnou deserializaci nebezpečnou. Proti zranitelnostem v interpretu, jako je PHP2Shell, OOP nepomáhá.

## Co znamená objektově orientované programování v PHP

Místo volných funkcí a globálních proměnných popisuje třída věc z odborné oblasti: objednávku, zákazníka, fakturu. Určuje, jaká data k ní patří (vlastnosti) a co se s nimi dá dělat (metody). Objekt je konkrétní exemplář této třídy.

Pro rozhodovatele to má praktickou hodnotu: objektově orientovaný kód s jasnými třídami se lépe testuje, kontroluje a předává dodavatelům. Staré aplikace PHP složené z mnoha jednotlivých skriptů s globálními proměnnými se naopak špatně udržují a při upgradech jsou náchylné k chybám.

Ústřední myšlenkou je zapouzdření: třída navenek zpřístupní jen ty metody, které ostatní skutečně potřebují, a chrání svůj vnitřní stav. Objednávku pak lze například označit za zaplacenou jen metodou, která předem ověří, zda je to vůbec přípustné. Soustředit taková pravidla na jednom místě je přínosem i pro bezpečnost.

## Stavební prvky v přehledu

| Prvek | Účel | Krátký příklad |
|---|---|---|
| Třída | plán pro objekty s vlastnostmi a metodami | `class Rechnung { ... }` |
| abstraktní třída | společný základ, nelze přímo instanciovat | `abstract class Zahlart { ... }` |
| Rozhraní | smlouva: jaké metody musí třída nabízet | `interface Versandfaehig { ... }` |
| Trait | znovupoužitelné metody pro třídy bez společného rodiče | `trait MitZeitstempel { ... }` |
| Enum | pevná sada povolených hodnot jako vlastní typ, od PHP 8.1 | `enum Status { case Offen; ... }` |

Viditelnosti (`public`, `protected`, `private`) určují, kdo smí přistupovat k vlastnostem a metodám. Třídy se organizují do jmenných prostorů a načítají přes autoloader; jak to funguje, ukazuje stránka [Jmenné prostory a autoloading](https://phpsos.de/cs/php/namespaces-autoloading/).

## Moderní PHP: novinky od 8.0 do 8.4

Následující jazykové prostředky jsou zdokumentovány v příručce PHP, resp. v oznámeních vydání:

| Verze | Novinka |
|---|---|
| 8.0 | constructor promotion, operátor nullsafe `?->`, `::class` na objektech |
| 8.1 | vlastnosti `readonly`, enumy, `new` v inicializátorech, `final` pro konstanty tříd |
| 8.2 | třídy `readonly`; dynamické vlastnosti jsou považovány za zastaralé |
| 8.3 | atribut `#[\Override]`, typované konstanty tříd |
| 8.4 | property hooks, asymetrická viditelnost, `new` bez obklopujících závorek |

Příklad, který kombinuje několik z těchto prostředků:

```php
<?php
declare(strict_types=1);

enum Status: string
{
    case Offen = 'offen';
    case Bezahlt = 'bezahlt';
}

final class Bestellung
{
    public function __construct(
        public readonly int $id,
        public private(set) Status $status = Status::Offen,  // od PHP 8.4
    ) {}

    public function alsBezahltMarkieren(): void
    {
        $this->status = Status::Bezahlt;
    }
}

$b = new Bestellung(42);
$b->alsBezahltMarkieren();
echo $b->status->value;              // bezahlt
$s = Status::tryFrom('storniert');   // null místo chyby
```

`readonly` brání tomu, aby se ID po vytvoření změnilo. `private(set)` povoluje čtení zvenčí, zápis ale jen uvnitř třídy. Taková ujištění v kódu snižují pravděpodobnost chyb, které by se jinak projevily až v provozu. Typy, které za tím stojí, vysvětluje stránka [Typový systém PHP](https://phpsos.de/cs/php/typsystem/).

### Pasti upgradu v objektově orientovaném kódu

Pro starší aplikace jsou obzvlášť důležité dvě změny. Od PHP 8.2.0 je vytváření dynamických vlastností zastaralé, tedy vlastností, které nejsou ve třídě deklarovány, pokud třída nemá atribut `#[\AllowDynamicProperties]`. Starší kód to často používá nevědomky a logy se pak plní upozorněními. Kromě toho musí být typované vlastnosti podle příručky před prvním čtením inicializovány, jinak PHP vyhodí `Error`.

Užitečný je atribut `#[\Override]` z PHP 8.3: označí metodu jako přepsání metody rodiče. Pokud tato metoda už neexistuje, například po přejmenování v knihovně, PHP ohlásí chybu, místo aby metodu tiše nechalo běžet naprázdno. Takové kontroly činí upgrady lépe plánovatelnými; u uvázlých starých projektů pomáhá naše [migrace na podporovanou verzi PHP](https://phpsos.de/cs/leistungen/php-migration-legacy/).

## Objekty a paměť

Objekty se v PHP předávají pomocí identifikátorů (handles). Pokud objekt předáte funkci, pracuje tato funkce se stejným objektem, ne s kopií. To je efektivní, ale snadno to vede ke kruhovým odkazům, například když objednávka zná své položky a každá položka zase svou objednávku. Takové cykly samotné počítání referencí neuklidí; k tomu má PHP vlastní garbage collector. Podrobnosti najdete na stránce [Správa paměti v PHP](https://phpsos.de/cs/php/speicherverwaltung/).

## OOP a bezpečnost: magické metody a deserializace

PHP zná magické metody, které se volají automaticky, například `__construct`, `__destruct`, `__toString`, `__get` nebo `__wakeup`. Je to praktické, ale má to stinnou stránku: pokud aplikace převádí cizí data pomocí `unserialize()` zpět na objekty, může útočník určit, které třídy vzniknou, a tím spustit stávající kód v magických metodách. Jak tomu zabránit, popisuje průvodce [Nebezpečná deserializace v PHP](https://phpsos.de/cs/ratgeber/deserialisierung-php/). Stručně: pro výměnu dat používejte `json_encode()` a `json_decode()` a `unserialize()` jen pro vlastní, důvěryhodná data, ideálně s volbou `allowed_classes`.

Proti PHP2Shell dobrý objektově orientovaný kód naopak nepomůže. CVE-2026-109618 a CVE-2026-109619 leží v interpretu a u mod_php byl podle týmu PHP předveden exploit dříve, než se spustí kód aplikace. Povinná je aktualizace na PHP 8.5.12, 8.4.27, 8.3.36 nebo 8.2.35 a restart všech procesů PHP.

## Jak konkrétně pomáhá PHP SOS?

- Posoudíme stavbu vaší aplikace a ukážeme, které části ztěžují upgrade na podporovanou verzi PHP.
- Cíleně hledáme rizikové vzorce, jako je `unserialize()` nad cizími daty a nebezpečné magické metody.
- Vlastní vývoj kontrolujeme v rámci [bezpečnostního auditu a penetračního testu](https://phpsos.de/cs/leistungen/sicherheitsaudit-penetrationstest/).
- Nasadíme aktualizaci PHP, restartujeme všechny workery a poté aplikaci otestujeme.


## Časté dotazy

**Je PHP objektově orientovaný jazyk?**  
PHP podporuje procedurální i objektově orientovaný kód. Frameworky, jádra CMS a e-shopové systémy jsou dnes ale převážně objektově orientované, s třídami, rozhraními a jmennými prostory.

**Jaký je rozdíl mezi rozhraním a abstraktní třídou?**  
Rozhraní pouze popisuje, jaké metody musí třída nabízet. Abstraktní třída může navíc obsahovat kód a vlastnosti, ale nelze z ní přímo vytvořit instanci. Třída může mít více rozhraní, ale jen jednoho rodiče.

**Od kdy existují enumy v PHP?**  
Výčty (enumy) přišly s PHP 8.1. Nahrazují sbírky konstant vlastním typem, který připouští jen definované případy. Backed enums mají navíc hodnotu typu int nebo string.

**Proč jsou magické metody významné z hlediska bezpečnosti?**  
Metody jako __destruct nebo __wakeup volá PHP automaticky, například při deserializaci dat. Pokud se cizí data dostanou bez kontroly do unserialize(), může to ve stávajících třídách spustit nečekané postupy.

## Zdroje

- [Příručka PHP: Třídy a objekty, základy](https://www.php.net/manual/de/language.oop5.basic.php)
- [Příručka PHP: Vlastnosti](https://www.php.net/manual/en/language.oop5.properties.php)
- [Příručka PHP: Viditelnost](https://www.php.net/manual/en/language.oop5.visibility.php)
- [Vydání PHP 8.1](https://www.php.net/releases/8.1/en.php)
