Aktuālā situācija: PHP2Shell. Divas kritiskas PHP ievainojamības (CVSS 9.2) ļauj izpildīt ļaunprātīgu kodu bez pieteikšanās. Ielāpi kopš 21.10.2026.Kas jādara tagad →

Objektorientētā programmēšana PHP

Modernas PHP lietojumprogrammas gandrīz vienmēr ir objektorientētas. Šī lapa izskaidro pamatelementus, jaunumus no PHP 8.0 līdz 8.4 un kāpēc maģiskās metodes ir svarīgas drošībā.

Aktuāls uz 4 min lasīšanas laiksPHP zināšanas

Īsi: objektorientētā programmēšana (OOP) apvieno datus un tiem piederošās funkcijas klasēs. PHP tam piedāvā klases, abstraktas klases, interfeisus, traits un kopš PHP 8.1 enum. Ar PHP 8.0 līdz 8.4 pievienotas daudzas valodas iespējas, piemēram, konstruktora promocija, readonly, Property Hooks un asimetriska redzamība. Drošībai svarīgi: labi iekapsulētu kodu ir vieglāk pārbaudīt, un maģiskās metodes padara nedrošu deserializāciju bīstamu. Pret ievainojamībām interpretatorā, piemēram, PHP2Shell, OOP nepalīdz.

Ko nozīmē objektorientētā programmēšana PHP

Tā vietā, lai lietotu brīvas funkcijas un globālos mainīgos, klase apraksta kādu priekšmetnozares lietu: pasūtījumu, klientu, rēķinu. Tā nosaka, kādi dati tai pieder (īpašības) un ko ar tiem var darīt (metodes). Objekts ir konkrēts šīs klases eksemplārs.

Lēmumu pieņēmējiem tam ir praktiska vērtība: objektorientētu kodu ar skaidrām klasēm ir vieglāk testēt, pārbaudīt un nodot pakalpojumu sniedzējiem. Savukārt vecas PHP lietojumprogrammas no daudziem atsevišķiem skriptiem ar globāliem mainīgajiem ir grūti uzturamas un jauninājumos kļūdaini.

Centrāla ideja ir iekapsulēšana: klase uz āru atver tikai tās metodes, kas citiem patiešām vajadzīgas, un aizsargā savu iekšējo stāvokli. Pasūtījumu tad, piemēram, var atzīmēt kā apmaksātu tikai ar metodi, kas iepriekš pārbauda, vai tas vispār ir pieļaujams. Šādu noteikumu apkopošana vienā vietā ir ieguvums arī drošībai.

Pamatelementu pārskats

Elements Nolūks Īss piemērs
Klase objektu projekts ar īpašībām un metodēm class Rechnung { ... }
abstrakta klase kopīga bāze, tieši neinstancējama abstract class Zahlart { ... }
Interfeiss līgums: kādas metodes klasei jāpiedāvā interface Versandfaehig { ... }
Trait atkārtoti izmantojamas metodes klasēm bez kopīgas vecākklases trait MitZeitstempel { ... }
Enum fiksēts atļauto vērtību kopums kā atsevišķs tips, kopš PHP 8.1 enum Status { case Offen; ... }

Redzamība (public, protected, private) nosaka, kam drīkst piekļūt īpašībām un metodēm. Klases tiek organizētas nosaukumvietās un ielādētas ar autoloader; kā tas darbojas, rāda lapa Nosaukumvietas un autoloading.

Modernais PHP: jaunumi no 8.0 līdz 8.4

Šīs valodas iespējas ir dokumentētas PHP rokasgrāmatā vai izlaidumu paziņojumos:

Versija Jaunums
8.0 konstruktora promocija, nullsafe operators ?->, ::class uz objektiem
8.1 readonly īpašības, enum, new inicializatoros, final klases konstantēm
8.2 readonly klases; dinamiskās īpašības ir novecojušas
8.3 atribūts #[\Override], tipizētas klases konstantes
8.4 Property Hooks, asimetriska redzamība, new bez apņemošām iekavām

Piemērs, kas apvieno vairākas no šīm iespējām:

<?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,  // no 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, nevis kļūda

readonly neļauj mainīt ID pēc izveides. private(set) ļauj lasīšanu no ārpuses, bet rakstīšanu tikai klases iekšienē. Šādi apgalvojumi kodā samazina kļūdu iespējamību, kas citādi tiek pamanītas tikai ekspluatācijā. Aiz tiem esošos tipus izskaidro lapa PHP tipu sistēma.

Jauninājuma slazdi objektorientētā kodā

Vecākām lietojumprogrammām īpaši svarīgas divas izmaiņas. Kopš PHP 8.2.0 dinamisko īpašību izveide ir novecojusi, tas ir, īpašību, kas klasē nav deklarētas, ja vien klasei nav atribūta #[\AllowDynamicProperties]. Vecāks kods to bieži izmanto neapzināti un žurnālus piepilda ar norādēm. Turklāt tipizētām īpašībām saskaņā ar rokasgrāmatu pirms pirmās lasīšanas jābūt inicializētām, citādi PHP met Error.

Noder atribūts #[\Override] no PHP 8.3: tas atzīmē metodi kā vecākmetodes pārrakstīšanu. Ja šīs metodes vairs nav, piemēram, pēc pārdēvēšanas bibliotēkā, PHP ziņo par kļūdu, nevis ļauj metodei bez paziņojuma darboties tukšumā. Šādas pārbaudes padara jauninājumus plānojamākus; iestrēgušiem vecajiem projektiem palīdz mūsu migrācija uz atbalstītu PHP versiju.

Objekti un atmiņa

Objekti PHP tiek nodoti ar identifikatoriem (handles). Ja objektu nodod funkcijai, tā strādā ar to pašu objektu, nevis ar kopiju. Tas ir efektīvi, bet viegli noved pie cikliskām atsaucēm, piemēram, ja pasūtījums zina savas pozīcijas un katra pozīcija atkal savu pasūtījumu. Šādus ciklus atsauču skaitīšana vien neattīra; tam PHP ir savs Garbage Collector. Detaļas ir lapā Atmiņas pārvaldība PHP.

OOP un drošība: maģiskās metodes un deserializācija

PHP pazīst maģiskās metodes, ko izsauc automātiski, piemēram, __construct, __destruct, __toString, __get vai __wakeup. Tas ir praktiski, bet tam ir ēnas puse: ja lietojumprogramma svešus datus ar unserialize() pārvērš atpakaļ objektos, uzbrucējs var noteikt, kādas klases rodas, un tā iedarbināt esošo kodu maģiskajās metodēs. Kā to novērst, apraksta ceļvedis Nedroša deserializācija PHP. Īsi: datu apmaiņai lietot json_encode() un json_decode(), bet unserialize() izmantot tikai saviem, uzticamiem datiem, ideālā gadījumā ar opciju allowed_classes.

PHP2Shell gadījumā labs objektorientēts kods tomēr nepalīdz. CVE-2026-109618 un CVE-2026-109619 atrodas interpretatorā, un mod_php gadījumā saskaņā ar PHP komandu exploit tika demonstrēts, pirms darbojas lietojumprogrammas kods. Obligāts ir atjauninājums uz PHP 8.5.12, 8.4.27, 8.3.36 vai 8.2.35 un visu PHP procesu pārstartēšana.

Kā PHP SOS palīdz konkrēti?

  • Mēs izvērtējam jūsu lietojumprogrammas uzbūvi un parādām, kuras daļas apgrūtina jauninājumu uz atbalstītu PHP versiju.
  • Mēs mērķtiecīgi meklējam riskantus modeļus, piemēram, unserialize() ar svešiem datiem un bīstamas maģiskās metodes.
  • Mēs pārbaudām pašrakstītos risinājumus drošības audita un penetrācijas testa ietvaros.
  • Mēs ieviešam PHP atjauninājumu, pārstartējam visus darbprocesus un pēc tam testējam lietojumprogrammu.

Biežāk uzdotie jautājumi

Vai PHP ir objektorientēta valoda?

PHP atbalsta gan procedurālu, gan objektorientētu kodu. Taču ietvari, CMS kodoli un veikalu sistēmas mūsdienās pārsvarā ir veidoti objektorientēti, ar klasēm, interfeisiem un nosaukumvietām.

Kāda ir atšķirība starp interfeisu un abstraktu klasi?

Interfeiss apraksta tikai to, kādas metodes klasei jāpiedāvā. Abstrakta klase papildus var saturēt jau kodu un īpašības, bet to nevar tieši instancēt. Klase var ieviest vairākus interfeisus, bet tai var būt tikai viena vecākklase.

Kopš kura laika PHP ir enum?

Uzskaitījumi (enum) parādījās ar PHP 8.1. Tie aizstāj konstanšu kopas ar atsevišķu tipu, kas pieļauj tikai definētos gadījumus. Backed enum papildus ir int vai string vērtība.

Kāpēc maģiskās metodes ir būtiskas drošībai?

Tādas metodes kā __destruct vai __wakeup PHP izsauc automātiski, piemēram, datu deserializācijas laikā. Ja svešie dati bez pārbaudes nonāk unserialize(), tas var izraisīt negaidītas norises esošajās klasēs.

Avoti

Tūlītējs kontakts

Katra stunda ir svarīga. Rakstiet mums tūlīt.

Īsi aprakstiet sistēmu, PHP versiju un novēroto. Mēs sazināsimies, noskaidrosim situāciju un strādāsim attālināti, līdz incidents ir slēgts un dokumentēts.

Tūlītēja palīdzība