Praegune olukord: PHP2Shell. Kaks kriitilist PHP turvaauku (CVSS 9,2) lubavad kahjulikku koodi ilma sisselogimata. Paigad alates 21.10.2026.Mida nüüd teha →

Objektorienteeritus PHP-s

Kaasaegsed PHP rakendused on peaaegu alati objektorienteeritud. Leht selgitab ehituskive, PHP 8.0–8.4 uuendusi ja miks maagilised meetodid turvalisuses rolli mängivad.

Seis Lugemisaeg 4 minPHP teadmised

Lühidalt: Objektorienteeritud programmeerimine (OOP) koondab andmed ja nendega seotud funktsioonid klassidesse. PHP pakub selleks klasse, abstraktseid klasse, liideseid, trait'e ja alates PHP 8.1-st enume. PHP 8.0–8.4-ga lisandus palju keelevahendeid, näiteks konstruktori promotsioon, readonly, Property Hooks ja asümmeetriline nähtavus. Turvalisuse jaoks on oluline: hästi kapseldatud koodi on lihtsam kontrollida ning maagilised meetodid muudavad ebaturvalise deserialiseerimise ohtlikuks. Interpretaatori turvaaukude nagu PHP2Shell vastu OOP ei aita.

Mida objektorienteeritud programmeerimine PHP-s tähendab

Lahtiste funktsioonide ja globaalsete muutujate asemel kirjeldab klass asja erialamaailmast: tellimust, klienti, arvet. See määrab, millised andmed sinna kuuluvad (omadused) ja mida nendega teha saab (meetodid). Objekt on selle klassi konkreetne eksemplar.

Otsustajale on sellel praktiline väärtus: selgete klassidega objektorienteeritud koodi on parem testida, kontrollida ja teenusepakkujale üle anda. Vanad PHP rakendused, mis koosnevad paljudest üksikutest skriptidest ja globaalsetest muutujatest, on seevastu raskesti hooldatavad ja uuenduste puhul veaaldised.

Kesksel kohal on kapseldus: klass avab väljapoole ainult need meetodid, mida teised tõesti vajavad, ja kaitseb oma sisemist seisundit. Tellimuse saab siis näiteks tasutuks märkida ainult meetodiga, mis kontrollib enne, kas see on üldse lubatud. Sellised reeglid ühte kohta koondada on kasu ka turvalisusele.

Ehituskivid ülevaatlikult

Ehituskivi Otstarve Lühinäide
Klass objektide ehitusplaan omaduste ja meetoditega class Rechnung { ... }
abstraktne klass ühine alus, otse instantseerimatu abstract class Zahlart { ... }
liides (interface) leping: milliseid meetodeid klass pakkuma peab interface Versandfaehig { ... }
trait taaskasutatavad meetodid klassidele, millel pole ühist vanemklassi trait MitZeitstempel { ... }
enum kindel lubatud väärtuste kogum oma tüübina, alates PHP 8.1-st enum Status { case Offen; ... }

Nähtavused (public, protected, private) reguleerivad, kes omadustele ja meetoditele ligi pääseb. Klassid organiseeritakse nimeruumidesse ja laaditakse automaatlaaduri kaudu; kuidas see töötab, näitab leht Nimeruumid ja automaatlaadimine.

Kaasaegne PHP: uuendused versioonides 8.0–8.4

Järgmised keelevahendid on dokumenteeritud PHP käsiraamatus või väljalaskekuulutustes:

Versioon Uuendus
8.0 konstruktori promotsioon, nullsafe-operaator ?->, ::class objektidel
8.1 readonly-omadused, enumid, new initsialiseerijates, final klassikonstantidele
8.2 readonly-klassid; dünaamilised omadused loetakse iganenuks
8.3 atribuut #[\Override], tüpiseeritud klassikonstandid
8.4 Property Hooks, asümmeetriline nähtavus, new ilma ümbritsevate sulgudeta

Näide, mis ühendab mitu neist vahenditest:

<?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,  // alates PHP 8.4-st
    ) {}

    public function alsBezahltMarkieren(): void
    {
        $this->status = Status::Bezahlt;
    }
}

$b = new Bestellung(42);
$b->alsBezahltMarkieren();
echo $b->status->value;              // bezahlt
$s = Status::tryFrom('storniert');   // null vea asemel

readonly takistab ID muutmist pärast loomist. private(set) lubab lugemist väljastpoolt, kirjutamist aga ainult klassi sees. Sellised tagatised koodis muudavad ebatõenäolisemaks vead, mis muidu tulevad välja alles töö käigus. Nende taga olevaid tüüpe selgitab leht PHP tüübisüsteem.

Uuenduse lõksud objektorienteeritud koodis

Vanemate rakenduste jaoks on eriti olulised kaks muudatust. Alates PHP 8.2.0-st on dünaamiliste omaduste loomine iganenud, see tähendab omaduste, mida klassis ei ole deklareeritud, välja arvatud juhul, kui klassil on atribuut #[\AllowDynamicProperties]. Vanem kood teeb seda sageli tahtmatult ja täidab seejärel logid märkustega. Lisaks peavad tüpiseeritud omadused käsiraamatu järgi olema enne esimest lugemist initsialiseeritud, vastasel juhul viskab PHP vea Error.

Abiks on PHP 8.3 atribuut #[\Override]: see märgib meetodi vanemmeetodi ülekirjutusena. Kui seda meetodit enam ei ole, näiteks teegis ümbernimetamise järel, teatab PHP veast, selle asemel et lasta meetodil vaikselt tühja jooksma. Sellised kontrollid teevad uuendused planeeritavamaks; kinni kiilunud vanade projektide puhul aitab meie üleminek toetatud PHP versioonile.

Objektid ja mälu

Objekte antakse PHP-s edasi tunnuste (handle'ite) kaudu. Kui objekt funktsioonile üle anda, töötab see sama objektiga, mitte koopiaga. See on tõhus, kuid viib kergesti tsükliliste viideteni, näiteks kui tellimus teab oma positsioone ja iga positsioon omakorda oma tellimust. Selliseid tsükleid viidete loendur üksi ei koristata; selleks on PHP-l oma prügikoristaja (Garbage Collector). Üksikasjad on lehel Mäluhaldus PHP-s.

OOP ja turvalisus: maagilised meetodid ja deserialiseerimine

PHP tunneb maagilisi meetodeid, mida kutsutakse välja automaatselt, näiteks __construct, __destruct, __toString, __get või __wakeup. See on praktiline, kuid sel on varjukülg: kui rakendus muudab võõrad andmed funktsiooniga unserialize() tagasi objektideks, saab ründaja määrata, millised klassid tekivad, ja käivitada nii olemasolevat koodi maagilistes meetodites. Kuidas seda vältida, kirjeldab juhend Ebaturvaline deserialiseerimine PHP-s. Lühidalt: andmevahetuseks kasutage json_encode() ja json_decode() ning unserialize() ainult oma usaldusväärsete andmete jaoks, ideaalis suvandiga allowed_classes.

PHP2Shelli vastu hea objektorienteeritud kood seevastu ei aita. CVE-2026-109618 ja CVE-2026-109619 asuvad interpretaatoris ning mod_php puhul näidati PHP meeskonna andmetel ekspluateerimist enne, kui rakenduse kood käivitub. Kohustuslik on uuendus versioonile PHP 8.5.12, 8.4.27, 8.3.36 või 8.2.35 ja kõigi PHP protsesside taaskäivitus.

Kuidas PHP SOS konkreetselt aitab?

  • Hindame teie rakenduse ülesehitust ja näitame, millised osad raskendavad üleminekut toetatud PHP versioonile.
  • Otsime sihipäraselt riskantseid mustreid, nagu unserialize() võõraste andmete peal ja ohtlikud maagilised meetodid.
  • Kontrollime omaarendusi turvaauditi ja penetratsioonitesti raames.
  • Paigaldame PHP uuenduse, käivitame kõik workerid uuesti ja testime rakendust seejärel.

Korduma kippuvad küsimused

Kas PHP on objektorienteeritud keel?

PHP toetab nii protseduurset kui ka objektorienteeritud koodi. Raamistikud, CMS-ide tuumad ja poesüsteemid on tänapäeval siiski valdavalt objektorienteeritud, klasside, liideste ja nimeruumidega.

Mis vahe on liidesel ja abstraktsel klassil?

Liides kirjeldab ainult seda, milliseid meetodeid klass pakkuma peab. Abstraktne klass võib lisaks sisaldada juba koodi ja omadusi, kuid seda ei saa otse instantseerida. Klassil võib olla mitu liidest, aga ainult üks vanemklass.

Millest alates on PHP-s enumid?

Enumeratsioonid tulid PHP 8.1-ga. Need asendavad konstantide kogumeid oma tüübiga, mis lubab ainult defineeritud juhtumeid. Backed Enumidel on lisaks int- või string-väärtus.

Miks on maagilised meetodid turvalisuse seisukohast olulised?

Meetodeid nagu __destruct või __wakeup kutsub PHP välja automaatselt, näiteks andmete deserialiseerimisel. Kui võõrad andmed jõuavad kontrollimata funktsiooni unserialize(), võib see käivitada olemasolevates klassides ootamatuid protsesse.

Allikad

Kohene kontakt

Iga tund loeb. Kirjutage meile kohe.

Kirjeldage lühidalt süsteemi, PHP versiooni ja tähelepanekut. Võtame teiega ühendust, selgitame olukorra välja ja töötame kaugtööna, kuni intsident on lõpetatud ja dokumenteeritud.

Kohene abi