Aktualna sytuacja: PHP2Shell. Dwie krytyczne luki w PHP (CVSS 9,2) umożliwiają wykonanie złośliwego kodu bez logowania. Poprawki od 21.10.2026.Co należy teraz zrobić →

Programowanie obiektowe w PHP

Nowoczesne aplikacje PHP są niemal zawsze obiektowe. Ta strona wyjaśnia elementy składowe, nowości od PHP 8.0 do 8.4 i dlaczego metody magiczne odgrywają rolę w bezpieczeństwie.

Stan 4 min czytaniaWiedza o PHP

Krótko: Programowanie obiektowe (OOP) łączy dane i należące do nich funkcje w klasach. PHP oferuje w tym celu klasy, klasy abstrakcyjne, interfejsy, traity, a od PHP 8.1 enumy. W PHP 8.0 do 8.4 doszło wiele środków językowych, na przykład promocja konstruktora, readonly, property hooks i asymetryczna widoczność. Dla bezpieczeństwa ważne jest to, że dobrze zamknięty w kapsułę kod łatwiej sprawdzić, a metody magiczne czynią niebezpieczną niebezpieczną deserializację. Przed lukami w interpreterze, takimi jak PHP2Shell, OOP nie chroni.

Co oznacza programowanie obiektowe w PHP

Zamiast luźnych funkcji i zmiennych globalnych klasa opisuje rzecz ze świata biznesu: zamówienie, klienta, fakturę. Określa, jakie dane do niej należą (właściwości) i co można z nimi robić (metody). Obiekt jest konkretnym egzemplarzem tej klasy.

Dla osób podejmujących decyzje ma to wartość praktyczną: kod obiektowy z jasnymi klasami łatwiej testować, sprawdzać i przekazywać usługodawcom. Stare aplikacje PHP złożone z wielu pojedynczych skryptów ze zmiennymi globalnymi są natomiast trudne w utrzymaniu i podatne na błędy przy aktualizacjach.

Centralną ideą jest enkapsulacja: klasa udostępnia na zewnątrz tylko te metody, których inni naprawdę potrzebują, i chroni swój wewnętrzny stan. Zamówienie można wtedy na przykład oznaczyć jako opłacone tylko metodą, która wcześniej sprawdza, czy jest to w ogóle dopuszczalne. Zebranie takich reguł w jednym miejscu jest zyskiem także dla bezpieczeństwa.

Elementy składowe w skrócie

Element Cel Krótki przykład
Klasa wzorzec obiektów z właściwościami i metodami class Rechnung { ... }
klasa abstrakcyjna wspólna baza, nie do bezpośredniego instancjonowania abstract class Zahlart { ... }
Interfejs umowa: jakie metody klasa musi oferować interface Versandfaehig { ... }
Trait metody do ponownego użycia w klasach bez wspólnej klasy nadrzędnej trait MitZeitstempel { ... }
Enum stały zestaw dozwolonych wartości jako własny typ, od PHP 8.1 enum Status { case Offen; ... }

Widoczności (public, protected, private) regulują, kto może uzyskiwać dostęp do właściwości i metod. Klasy są organizowane w przestrzeniach nazw i ładowane przez autoloader; jak to działa, pokazuje strona Przestrzenie nazw i autoloading.

Nowoczesny PHP: nowości od 8.0 do 8.4

Poniższe środki językowe są udokumentowane w podręczniku PHP lub w ogłoszeniach o wydaniach:

Wersja Nowość
8.0 promocja konstruktora, operator nullsafe ?->, ::class na obiektach
8.1 właściwości readonly, enumy, new w inicjalizatorach, final dla stałych klas
8.2 klasy readonly; właściwości dynamiczne uznano za przestarzałe
8.3 atrybut #[\Override], typowane stałe klas
8.4 property hooks, asymetryczna widoczność, new bez otaczających nawiasów

Przykład łączący kilka z tych środków:

<?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 zamiast błędu

readonly uniemożliwia zmianę identyfikatora po utworzeniu. private(set) pozwala na odczyt z zewnątrz, ale na zapis tylko wewnątrz klasy. Takie zapewnienia w kodzie zmniejszają prawdopodobieństwo błędów, które inaczej wychodzą na jaw dopiero w eksploatacji. Typy, które za tym stoją, wyjaśnia strona System typów w PHP.

Pułapki aktualizacji w kodzie obiektowym

W starszych aplikacjach szczególnie istotne są dwie zmiany. Od PHP 8.2.0 tworzenie właściwości dynamicznych, czyli takich, które nie są zadeklarowane w klasie, jest przestarzałe, chyba że klasa ma atrybut #[\AllowDynamicProperties]. Starszy kod często robi to nieświadomie i wtedy wypełnia logi uwagami. Poza tym według podręcznika typowane właściwości muszą być zainicjalizowane przed pierwszym odczytem, w przeciwnym razie PHP zgłasza Error.

Pomocny jest atrybut #[\Override] z PHP 8.3: oznacza metodę jako nadpisanie metody klasy nadrzędnej. Jeśli takiej metody już nie ma, na przykład po zmianie nazwy w bibliotece, PHP zgłasza błąd, zamiast pozwolić metodzie po cichu działać w próżnię. Takie kontrole czynią aktualizacje bardziej przewidywalnymi; w utkniętych starych projektach pomaga nasza migracja do wspieranej wersji PHP.

Obiekty i pamięć

Obiekty są w PHP przekazywane przez identyfikatory (handle). Jeśli przekaże się obiekt do funkcji, pracuje ona na tym samym obiekcie, a nie na kopii. Jest to wydajne, ale łatwo prowadzi do odwołań cyklicznych, na przykład gdy zamówienie zna swoje pozycje, a każda pozycja znowu swoje zamówienie. Takich cykli samo zliczanie referencji nie sprząta; PHP ma do tego własny garbage collector. Szczegóły są na stronie Zarządzanie pamięcią w PHP.

OOP a bezpieczeństwo: metody magiczne i deserializacja

PHP zna metody magiczne, wywoływane automatycznie, na przykład __construct, __destruct, __toString, __get lub __wakeup. Jest to praktyczne, ale ma ciemną stronę: jeśli aplikacja zamienia obce dane za pomocą unserialize() z powrotem w obiekty, atakujący może zdecydować, jakie klasy powstaną, i w ten sposób uruchomić istniejący kod w metodach magicznych. Jak temu zapobiec, opisuje poradnik Niebezpieczna deserializacja w PHP. Krótko: do wymiany danych używać json_encode() i json_decode(), a unserialize() stosować tylko dla własnych, zaufanych danych, najlepiej z opcją allowed_classes.

Przy PHP2Shell dobry kod obiektowy natomiast nie pomaga. CVE-2026-109618 i CVE-2026-109619 leżą w interpreterze, a przy mod_php zespół PHP pokazał exploit, zanim zacznie działać kod aplikacji. Obowiązkowa jest aktualizacja do PHP 8.5.12, 8.4.27, 8.3.36 lub 8.2.35 i restart wszystkich procesów PHP.

Jak konkretnie pomaga PHP SOS?

  • Oceniamy budowę Państwa aplikacji i pokazujemy, które jej części utrudniają przejście na wspieraną wersję PHP.
  • Szukamy celowo ryzykownych wzorców, takich jak unserialize() na obcych danych i niebezpieczne metody magiczne.
  • Sprawdzamy własne rozwiązania w ramach audytu bezpieczeństwa i testu penetracyjnego.
  • Instalujemy aktualizację PHP, restartujemy wszystkie workery i potem testujemy aplikację.

Częste pytania

Czy PHP jest językiem obiektowym?

PHP obsługuje zarówno kod proceduralny, jak i obiektowy. Frameworki, rdzenie CMS i systemy sklepowe są dziś jednak w przeważającej mierze zbudowane obiektowo, z klasami, interfejsami i przestrzeniami nazw.

Jaka jest różnica między interfejsem a klasą abstrakcyjną?

Interfejs opisuje tylko, jakie metody klasa musi oferować. Klasa abstrakcyjna może dodatkowo zawierać już kod i właściwości, ale nie można jej bezpośrednio instancjonować. Klasa może mieć wiele interfejsów, ale tylko jedną klasę nadrzędną.

Od kiedy w PHP istnieją enumy?

Enumeracje pojawiły się w PHP 8.1. Zastępują zbiory stałych własnym typem, który dopuszcza tylko zdefiniowane przypadki. Backed enumy mają dodatkowo wartość int lub string.

Dlaczego metody magiczne mają znaczenie dla bezpieczeństwa?

Metody takie jak __destruct lub __wakeup PHP wywołuje automatycznie, na przykład przy deserializacji danych. Jeśli obce dane trafią bez sprawdzenia do unserialize(), może to wywołać nieoczekiwane przebiegi w istniejących klasach.

Źródła

Kontakt natychmiast

Liczy się każda godzina. Proszę napisać do nas teraz.

Proszę krótko opisać system, wersję PHP i obserwacje. Skontaktujemy się z Państwem, ustalimy sytuację i będziemy pracować zdalnie, aż incydent zostanie zamknięty i udokumentowany.

Natychmiastowa pomoc