Dabartinė padėtis: PHP2Shell. Du kritiniai PHP pažeidžiamumai (CVSS 9,2) leidžia vykdyti kenkėjišką kodą be prisijungimo. Pataisos nuo 2026-10-21.Ką dabar daryti →

PHP tipų sistema

PHP yra dinamiškai tipizuota, tačiau nuo PHP 7 gavo vis griežtesnę tipų sistemą. Čia matote tipus, svarbiausias versijas ir kodėl griežti palyginimai padeda išvengti saugumo klaidų.

Būsena 4 min. skaitymoPHP žinios

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ė 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.

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
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
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.

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ą.

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

Skubus kontaktas

Kiekviena valanda svarbi. Parašykite mums dabar.

Trumpai aprašykite sistemą, PHP versiją ir pastebėjimus. Mes atsakysime, išsiaiškinsime padėtį ir dirbsime nuotoliu, kol incidentas bus užbaigtas ir dokumentuotas.

Skubi pagalba