# PHP tipų sistema

> PHP tipų sistema paaiškinta: duomenų tipai, tipų deklaracijos nuo PHP 7.1 iki 8.3, strict_types ir laisvi palyginimai su pavyzdžiais bei ryšiu su saugumu.

Šaltinis: https://phpsos.de/lt/php/typsystem/  
Būsena: 2026-10-25  
Teikėjas: PHP SOS, PHP avarinė pagalba ir serverio sauga. Skubi pagalba per „WhatsApp“: https://wa.me/491736494914?text=Sveiki%2C%20PHP%20SOS%2C%20mums%20reikia%20pagalbos%20su%20m%C5%ABs%C5%B3%20PHP%20serveriu.%20%C4%AEmon%C4%97%3A%20%E2%80%A6%20Svetain%C4%97%3A%20%E2%80%A6

**Trumpai:** PHP yra dinamiškai tipizuota: reikšmės tipas paaiškėja tik vykdymo metu, o be papildomų nurodymų PHP prireikus reikšmes konvertuoja automatiškai. Tačiau nuo PHP 7 parametrams, grąžinamoms reikšmėms ir savybėms galima priskirti tipus, o `declare(strict_types=1)` patikrą padaro griežtą. Kas žino taisykles ir naudoja griežtus palyginimus su `===`, išvengia ištisos loginių ir saugumo klaidų klasės.

## Dinamiškai tipizuota, bet ne be tipų

PHP rašant `$preis = 19.90;` tipo nurodyti nereikia. PHP pati atpažįsta, kad tai slankiojo kablelio skaičius. Jei reikšmė vėliau sujungiama su eilute, PHP ją konvertuoja. Toks elgesys vadinamas Type Juggling, t. y. automatiniu tipų konvertavimu. Jis palengvina pradžią, bet gali duoti netikėtų rezultatų.

Sprendimų priėmėjams tai svarbu, nes daug senesnių PHP programų parašyta be tipų nurodymų. Tokį kodą sunkiau tikrinti ir modernizuoti. Naujesni projektai tipus naudoja nuosekliai, todėl klaidos išryškėja anksčiau, o [statinė analizė](https://phpsos.de/lt/php/statische-analyse/) su įrankiais, tokiais kaip PHPStan ar Psalm, tik tada tampa tikrai veiksminga.

## PHP tipų apžvalga

PHP vadovas nurodo devynis vidinius tipus, kuriuos gali turėti bet kuri išraiška. Paprastai jie skirstomi į tris grupes:

| Grupė | Tipai | Pavyzdys |
|---|---|---|
| Skaliariniai tipai | `bool`, `int`, `float`, `string` | `true`, `42`, `3.5`, `"Text"` |
| Sudėtiniai tipai | `array`, `object`, `callable` | `[1, 2]`, `new DateTime()` |
| Ypatingi tipai | `null`, `resource` | `null`, atidarytas failas |

Tipų patikrai vadovas rekomenduoja `is_*()` funkcijas, pavyzdžiui, `is_int()`. Tyrinėjimui tinka `get_debug_type()`, kuri nuo PHP 8.0.0 grąžina įprastus tipų pavadinimus, o senesnė `gettype()` grąžina, pavyzdžiui, `"integer"` ir `"double"`.

Be automatinio konvertavimo yra ir aiškus: su tipo keitimu (cast), pavyzdžiui, `(int) $wert`, arba su `settype()` kodas pats nustato, kokio tipo turi būti reikšmė. Tai įprasta formų įvesčiai, nes viskas, kas ateina per `$_GET` ar `$_POST`, iš pradžių yra eilutė arba masyvas. Tačiau cast netikrina, ar reikšmė buvo prasminga: iš `"abc"` tyliai tampa `0`. Todėl įvestims dažniausiai geresnis pasirinkimas yra tikra patikra su `filter_var()`.

Klasės ir sąsajos PHP taip pat yra tipai. Funkcija gali reikalauti, kad parametras būtų tam tikros klasės objektas arba įgyvendintų tam tikrą sąsają. Kaip kartu veikia klasės, sąsajos ir enum, paaiškinta puslapyje [Objektinis programavimas PHP](https://phpsos.de/lt/php/objektorientierung/).

## Tipų deklaracijos: nuo PHP 7.1 iki 8.3

Tipų deklaracijos nustato, kokias reikšmes funkcija priima ir grąžina. Tipų sistema augo per daugelį versijų. Pasak vadovo pakeitimų žurnalo, be kita ko, atsirado šios galimybės:

| Versija | Naujiena |
|---|---|
| 7.1.0 | nullable tipai (`?int`), `void`, `iterable` |
| 7.2.0 | `object` |
| 7.4.0 | tipizuotos klasės savybės |
| 8.0.0 | sąjungos tipai (keli leidžiami tipai viename nurodyme), `mixed`, grąžinamas tipas `static` |
| 8.1.0 | sankirtos tipai (`A&B`), grąžinamas tipas `never` |
| 8.2.0 | DNF tipai, literalo tipas `true`, `null` ir `false` kaip savarankiški tipai |
| 8.3.0 | tipizuotos klasių, sąsajų, trait ir enum konstantos |

DNF reiškia disjunktyviąją normalinę formą ir leidžia deriniais, pavyzdžiui, `(A&B)|null`. Kas planuoja PHP versijas, iš šios lentelės mato ir tai, kokių kalbos priemonių reikia programai.

## strict_types: konvertavimas arba TypeError

Be papildomo nurodymo PHP veikia konvertavimo režimu. Funkcija su `int` parametrais tuomet priima ir `1.5` ir paverčia jį `1`; nuo PHP 8.1 toks nuostolingas konvertavimas pažymėtas kaip pasenęs. Su `declare(strict_types=1)` failo pradžioje PHP vietoj to išmeta `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, vietoj tylaus 3
```

Svarbūs du niuansai. Pirma, `strict_types` galioja iškvietimams iš failo, kuriame jis nurodytas, o ne ten apibrėžtoms funkcijoms. Jei failas be `strict_types` iškviečia tą pačią funkciją, konvertuojama. Antra, sveikasis skaičius ten, kur tikimasi slankiojo kablelio skaičiaus, leidžiamas ir griežtame režime.

## Laisvi ir griežti palyginimai

Operatorius `==` lygina po tipų konvertavimo, `===` lygina reikšmę ir tipą be konvertavimo. Vadovas daugeliu atvejų rekomenduoja `===` ir `!==`, nes konvertavimo taisyklės ne visada akivaizdžios.

```php
<?php
var_dump(0 == "a");    // PHP 7: true,  PHP 8: false
var_dump("1" == "01"); // true, abi yra skaitinės eilutės
var_dump("1" === "01");// false, tas pats tipas, bet kita eilutė
var_dump(1 == true);   // true
var_dump(1 === true);  // false
```

Su PHP 8.0 palyginimai tarp skaičių ir neskaitinių eilučių tapo prasmingesni. Senesnių programų elgsena po atnaujinimo gali pasikeisti, pavyzdžiui, `switch` blokuose. Taip pat su PHP 8.0 įvesta `match` išraiška visada lygina griežtai. Kaip laisvi palyginimai sukelia saugumo spragas, pavyzdžiui, tikrinant žetonus ar slaptažodžius, aprašo straipsnis [Type Juggling: laisvi palyginimai kaip saugumo rizika](https://phpsos.de/lt/blog/type-juggling-php/).

## Tipai, atnaujinimai ir PHP2Shell

Griežta tipų sistema daro programos kodą patikimesnį, bet neapsaugo nuo klaidų paties interpretatoriaus viduje. PHP2Shell spragos CVE-2026-109618 ir CVE-2026-109619 slypi PHP atminties ir užklausų valdyme. Ištaisytos PHP 8.5.12, 8.4.27, 8.3.36 ir 8.2.35; po to visi PHP procesai turi būti paleisti iš naujo.

Tipų sistema vis dėlto vaidina vaidmenį, būtent atnaujinant. Programos, įstrigusios ties PHP 8.1 ar senesne versija, iš PHP projekto oficialių atnaujinimų nebegauna. Gerai tipizuotą kodą gerokai lengviau perkelti į palaikomą versiją, nes įrankiai nesuderinamumus randa anksti. Senesniems projektams padeda mūsų [perkėlimas į palaikomą PHP versiją](https://phpsos.de/lt/leistungen/php-migration-legacy/).

> **Patarimas:**
> Įjunkite `strict_types` palaipsniui naujuose ir perdarytuose failuose. Taip tipų saugumas auga, o senas kodas vienu metu nesugenda.

## Kaip PHP SOS padeda konkrečiai?

- Tikriname, kokios minimalios PHP versijos jūsų programai reikia, ir lyginame su ištaisytomis versijomis.
- Paleidžiame kodo statinę analizę ir pažymime vietas su laisvais palyginimais saugumui svarbiose patikrose.
- Atnaujinimus planuojame taip, kad pasikeitusios palyginimo taisyklės būtų išbandytos iš anksto.
- Įdiegiame PHP atnaujinimą, paleidžiame iš naujo visus darbinius procesus (worker) ir dokumentuojame būseną.


## Dažni klausimai

**Ar PHP yra stipriai, ar silpnai tipizuota?**  
PHP yra dinamiškai tipizuota: kintamojo tipas paaiškėja tik vykdymo metu. Be strict_types PHP prireikus reikšmes konvertuoja. Su tipų deklaracijomis ir strict_types kodą tačiau galima padaryti labai griežtą.

**Ką daro declare(strict_types=1)?**  
Jis išjungia automatinį skaliarinių reikšmių konvertavimą iškvietimams iš to failo. Jei reikšmė neatitinka deklaruoto tipo, PHP išmeta TypeError. Vienintelė išimtis yra sveikasis skaičius ten, kur tikimasi slankiojo kablelio skaičiaus.

**Kodėl 0 == "a" PHP 8 yra neteisinga, o PHP 7 teisinga?**  
Iki PHP 7 neskaitinė eilutė lyginant su skaičiumi buvo paverčiama skaičiumi, iš „a“ tapdavo 0. Nuo PHP 8.0 šiuo atveju PHP skaitiniu būdu nebelygina, rezultatas yra false.

**Ar tipai saugo nuo pačios PHP saugumo spragų?**  
Ne. Tipai apsaugo nuo klaidų jūsų programos kode. Interpretatoriaus spragas, tokias kaip PHP2Shell, uždaro tik PHP atnaujinimas. Tačiau šiuolaikinėms tipų galimybėms reikia naujų PHP versijų, todėl jos yra gera proga atnaujinti.

## Šaltiniai

- [PHP vadovas: tipų deklaracijos](https://www.php.net/manual/de/language.types.declarations.php)
- [PHP vadovas: tipų įvadas](https://www.php.net/manual/de/language.types.intro.php)
- [PHP vadovas: palyginimo operatoriai](https://www.php.net/manual/de/language.operators.comparison.php)
- [PHP 8.0 leidimas](https://www.php.net/releases/8.0/en.php)
