# PHP tüübisüsteem

> PHP tüübisüsteem selgitatud: andmetüübid, tüübideklaratsioonid PHP 7.1-st 8.3-ni, strict_types ja lõdvad võrdlused näidete ja turvaseosega.

Allikas: https://phpsos.de/et/php/typsystem/  
Seis: 25.10.2026  
Pakkuja: PHP SOS, PHP hädaabi ja serveri turvalisus. Kohene abi WhatsAppis: https://wa.me/491736494914?text=Tere%2C%20PHP%20SOS%2C%20vajame%20abi%20oma%20PHP-serveriga.%20Ettev%C3%B5te%3A%20%E2%80%A6%20Veebisait%3A%20%E2%80%A6

**Lühidalt:** PHP on dünaamiliselt tüpiseeritud: väärtuse tüüp selgub alles täitmisajal ja ilma lisanõueteta teisendab PHP väärtusi vajaduse korral automaatselt. Alates PHP 7-st saab parameetritele, tagastusväärtustele ja omadustele siiski tüübid anda ning `declare(strict_types=1)` muudab kontrolli rangeks. Kes tunneb reegleid ja kasutab rangeid võrdlusi operaatoriga `===`, väldib tervet klassi loogika- ja turvavigu.

## Dünaamiliselt tüpiseeritud, kuid mitte tüübita

PHP-s ei pea kirjas `$preis = 19.90;` tüüpi märkima. PHP tuvastab, et tegu on ujukomaarvuga. Kui väärtus seotakse hiljem sõnega, teisendab PHP selle. Seda käitumist nimetatakse Type Juggling'uks ehk automaatseks tüübiteisenduseks. See teeb alustamise lihtsaks, kuid võib viia üllatavate tulemusteni.

Otsustajale on see oluline, sest paljud vanemad PHP rakendused on kirjutatud ilma tüübimärgeteta. Sellist koodi on raskem kontrollida ja moderniseerida. Uuemad projektid kasutavad tüüpe järjekindlalt, mis toob vead varem nähtavale ja teeb [staatilise analüüsi](https://phpsos.de/et/php/statische-analyse/) tööriistadega nagu PHPStan või Psalm alles päriselt mõjusaks.

## PHP tüübid ülevaatlikult

PHP käsiraamat nimetab üheksa sisemist tüüpi, mis igal avaldisel võivad olla. Tavaliselt jaotatakse need kolme rühma:

| Rühm | Tüübid | Näide |
|---|---|---|
| Skalaarsed tüübid | `bool`, `int`, `float`, `string` | `true`, `42`, `3.5`, `"Text"` |
| Liittüübid | `array`, `object`, `callable` | `[1, 2]`, `new DateTime()` |
| Erilised tüübid | `null`, `resource` | `null`, avatud fail |

Tüübikontrolliks soovitab käsiraamat `is_*()` funktsioone nagu `is_int()`. Uurimiseks sobib `get_debug_type()`, mis annab alates PHP 8.0.0-st tavalised tüübinimed, samal ajal kui vanem `gettype()` tagastab näiteks `"integer"` ja `"double"`.

Automaatse teisenduse kõrval on olemas ka selgesõnaline: castiga nagu `(int) $wert` või funktsiooniga `settype()` määrab kood ise, mis tüüpi väärtus olema peab. See on vormisisestuste puhul tavaline, sest kõik, mis tuleb sisse `$_GET` või `$_POST` kaudu, on esialgu sõne või massiiv. Cast ei kontrolli siiski, kas väärtus oli mõistlik: „abc“ muutub vaikselt nulliks `0`. Sisendite puhul on seetõttu enamasti parem valik päris kontroll funktsiooniga `filter_var()`.

Ka klassid ja liidesed on PHP-s tüübid. Funktsioon võib seega nõuda, et parameeter oleks teatud klassi objekt või täidaks teatud liidest. Kuidas klassid, liidesed ja enumid koos töötavad, selgitab leht [Objektorienteeritus PHP-s](https://phpsos.de/et/php/objektorientierung/).

## Tüübideklaratsioonid: PHP 7.1-st 8.3-ni

Tüübideklaratsioonid määravad, milliseid väärtusi funktsioon vastu võtab ja tagastab. Tüübisüsteem on kasvanud paljude versioonide jooksul. Käsiraamatu muudatuste logi järgi lisandusid muu hulgas järgmised võimalused:

| Versioon | Uus |
|---|---|
| 7.1.0 | nullable tüübid (`?int`), `void`, `iterable` |
| 7.2.0 | `object` |
| 7.4.0 | tüpiseeritud klassi omadused |
| 8.0.0 | Union-tüübid (mitu lubatud tüüpi ühes märkes), `mixed`, tagastustüüp `static` |
| 8.1.0 | Intersection-tüübid (`A&B`), tagastustüüp `never` |
| 8.2.0 | DNF-tüübid, literaaltüüp `true`, `null` ja `false` eraldi tüüpidena |
| 8.3.0 | tüpiseeritud klassi-, liidese-, trait'i- ja enumi konstandid |

DNF tähendab disjunktiivset normaalkuju ja lubab kombinatsioone nagu `(A&B)|null`. Kes PHP versioone planeerib, näeb sellest tabelist ka seda, milliseid keelevahendeid rakendus eeldab.

## strict_types: teisendus või TypeError

Ilma lisamärketa töötab PHP teisendavas režiimis. Funktsioon, mille parameetrid on `int`, võtab siis vastu ka `1.5` ja teeb sellest `1`; alates PHP 8.1-st on see kadudega teisendus märgitud iganenuks. Kui faili alguses on `declare(strict_types=1)`, viskab PHP selle asemel vea `TypeError`.

```php
<?php
declare(strict_types=1);

function summe(int $a, int $b): int
{
    return $a + $b;
}

echo summe(1, 2);      // 3
echo summe(1.5, 2.5);  // TypeError, vaikselt 3 asemel
```

Kaks peensust on olulised. Esiteks kehtib `strict_types` väljakutsetele failist, milles see on, mitte seal defineeritud funktsioonidele. Kui `strict_types`'ita fail kutsub sama funktsiooni välja, siis teisendatakse. Teiseks on täisarv seal, kus oodatakse ujukomaarvu, lubatud ka ranges režiimis.

## Lõdvad ja rangad võrdlused

Operaator `==` võrdleb pärast tüübiteisendust, `===` võrdleb väärtust ja tüüpi ilma teisenduseta. Käsiraamat soovitab enamikul juhtudel `===` ja `!==`, sest teisendusreeglid ei ole alati ilmselged.

```php
<?php
var_dump(0 == "a");    // PHP 7: true,  PHP 8: false
var_dump("1" == "01"); // true, mõlemad on numbrilised sõned
var_dump("1" === "01");// false, sama tüüp, kuid erinev sõne
var_dump(1 == true);   // true
var_dump(1 === true);  // false
```

PHP 8.0-ga muutusid arvude ja mittenumbriliste sõnede võrdlused mõistlikumaks. Vanemad rakendused võivad uuenduse tõttu käituda teisiti, näiteks `switch`-plokkides. Samuti PHP 8.0-ga lisandunud avaldis `match` võrdleb alati rangelt. Kuidas lõdvad võrdlused viivad turvaaukudeni, näiteks tokeni- või paroolikontrollides, kirjeldab artikkel [Type Juggling: lõdvad võrdlused turvariskina](https://phpsos.de/et/blog/type-juggling-php/).

## Tüübid, uuendused ja PHP2Shell

Range tüübisüsteem muudab rakenduse koodi töökindlamaks, kuid ei kaitse vigade eest interpretaatoris endas. PHP2Shelli turvaaugud CVE-2026-109618 ja CVE-2026-109619 asuvad PHP mälu- ja päringuhalduses. Parandatud on need versioonides PHP 8.5.12, 8.4.27, 8.3.36 ja 8.2.35; pärast seda peavad kõik PHP protsessid uuesti käivituma.

Tüübisüsteemil on siiski oma roll, nimelt uuendamisel. Rakendused, mis on veel PHP 8.1 või vanema külge kinni, ei saa PHP projektilt enam ametlikke uuendusi. Hästi tüpiseeritud koodi on tunduvalt lihtsam tõsta toetatud versioonile, sest tööriistad leiavad sobimatused varakult. Vanemate projektide puhul toetab meie [üleminek toetatud PHP versioonile](https://phpsos.de/et/leistungen/php-migration-legacy/).

> **Näpunäide:**
> Aktiveerige `strict_types` järk-järgult uutes ja ümbertehtud failides. Nii kasvab tüübiturvalisus, ilma et vana kood korraga katki läheks.

## Kuidas PHP SOS konkreetselt aitab?

- Kontrollime, millist PHP versiooni teie rakendus vähemalt vajab, ja võrdleme seda parandatud versioonidega.
- Laseme koodil käia staatilise analüüsi läbi ja märgime kohad, kus turvakontrollides on lõdvad võrdlused.
- Planeerime uuendused nii, et muutunud võrdlusreeglid saavad eelnevalt testitud.
- Paigaldame PHP uuenduse, käivitame kõik workerid uuesti ja dokumenteerime seisu.


## Korduma kippuvad küsimused

**Kas PHP on tugevalt või nõrgalt tüpiseeritud?**  
PHP on dünaamiliselt tüpiseeritud: muutuja tüüp selgub alles täitmisajal. Ilma strict_types'ita teisendab PHP väärtusi vajaduse korral. Tüübideklaratsioonide ja strict_types'iga saab koodi siiski väga rangeks muuta.

**Mida teeb declare(strict_types=1)?**  
See lülitab väljakutsete jaoks vastavast failist välja skalaarsete väärtuste automaatse teisendamise. Kui väärtus ei sobi deklareeritud tüübiga, viskab PHP vea TypeError. Ainus erand on täisarv seal, kus oodatakse ujukomaarvu.

**Miks on 0 == "a" PHP 8-s väär, PHP 7-s aga tõene?**  
Kuni PHP 7-ni teisendati mittenumbriline sõne arvuga võrdlemisel arvuks, „a“ muutus nulliks. Alates PHP 8.0-st ei võrdle PHP sellisel juhul enam numbriliselt ja tulemus on false.

**Kas tüübid kaitsevad PHP enda turvaaukude eest?**  
Ei. Tüübid takistavad vigu teie rakenduse koodis. Interpretaatori turvaauke nagu PHP2Shell suleb ainult PHP uuendus. Kaasaegsed tüübifunktsioonid eeldavad siiski ajakohaseid PHP versioone ja on seega hea põhjus uuendamiseks.

## Allikad

- [PHP käsiraamat: tüübideklaratsioonid](https://www.php.net/manual/de/language.types.declarations.php)
- [PHP käsiraamat: sissejuhatus tüüpidesse](https://www.php.net/manual/de/language.types.intro.php)
- [PHP käsiraamat: võrdlusoperaatorid](https://www.php.net/manual/de/language.operators.comparison.php)
- [PHP 8.0 väljalase](https://www.php.net/releases/8.0/en.php)
