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