# Sistemul de tipuri al PHP

> Sistemul de tipuri PHP explicat: tipuri de date, declarații de tip de la PHP 7.1 la 8.3, strict_types și comparații laxe, cu exemple și legătura cu securitatea.

Sursa: https://phpsos.de/ro/php/typsystem/  
Stadiu: 25.10.2026  
Furnizor: PHP SOS, Asistență de urgență PHP și securitatea serverelor. Ajutor imediat pe WhatsApp: https://wa.me/491736494914?text=Bun%C4%83%20ziua%2C%20PHP%20SOS%2C%20avem%20nevoie%20de%20ajutor%20cu%20serverul%20nostru%20PHP.%20Firma%3A%20%E2%80%A6%20Site%3A%20%E2%80%A6

**Pe scurt:** PHP este tipizat dinamic: tipul unei valori se stabilește abia la execuție, iar fără alte indicații PHP convertește automat valorile la nevoie. Începând cu PHP 7, parametrii, valorile returnate și proprietățile pot fi însă prevăzute cu tipuri, iar `declare(strict_types=1)` face verificarea strictă. Cine cunoaște regulile și folosește comparații stricte cu `===` evită o întreagă clasă de erori de logică și de securitate.

## Tipizat dinamic, dar nu fără tipuri

În PHP nu trebuie indicat niciun tip la `$preis = 19.90;`. PHP recunoaște că este un număr în virgulă mobilă. Dacă valoarea este ulterior combinată cu un șir de caractere, PHP o convertește. Acest comportament se numește type juggling, adică conversie automată de tip. Face începutul ușor, dar poate duce la rezultate surprinzătoare.

Pentru factorii de decizie este relevant, deoarece multe aplicații PHP mai vechi au fost scrise fără indicații de tip. Un astfel de cod este mai greu de verificat și de modernizat. Proiectele mai noi folosesc tipurile consecvent, ceea ce face erorile vizibile mai devreme și permite [analizei statice](https://phpsos.de/ro/php/statische-analyse/) cu instrumente precum PHPStan sau Psalm să devină cu adevărat eficientă.

## Tipurile PHP, pe scurt

Manualul PHP menționează nouă tipuri interne pe care le poate avea orice expresie. De obicei ele sunt împărțite în trei grupuri:

| Grup | Tipuri | Exemplu |
|---|---|---|
| Tipuri scalare | `bool`, `int`, `float`, `string` | `true`, `42`, `3.5`, `"Text"` |
| Tipuri compuse | `array`, `object`, `callable` | `[1, 2]`, `new DateTime()` |
| Tipuri speciale | `null`, `resource` | `null`, un fișier deschis |

Pentru verificări de tip, manualul recomandă funcțiile `is_*()`, precum `is_int()`. Pentru examinare este potrivită `get_debug_type()`, care din PHP 8.0.0 returnează denumirile uzuale ale tipurilor, în timp ce mai vechea `gettype()` returnează, de exemplu, `"integer"` și `"double"`.

Pe lângă conversia automată există și cea explicită: cu un cast precum `(int) $wert` sau cu `settype()`, codul stabilește singur ce tip trebuie să aibă o valoare. Aceasta este uzual pentru datele din formulare, deoarece tot ce vine prin `$_GET` sau `$_POST` este mai întâi un șir de caractere sau un array. Un cast nu verifică însă dacă valoarea era rezonabilă: din `"abc"` rezultă pe tăcute `0`. Pentru date de intrare, o verificare reală cu `filter_var()` este de aceea, de obicei, alegerea mai bună.

Clasele și interfețele sunt de asemenea tipuri în PHP. O funcție poate deci cere ca un parametru să fie un obiect al unei anumite clase sau să implementeze o anumită interfață. Cum conlucrează clasele, interfețele și enum-urile explică pagina [Programarea orientată pe obiecte în PHP](https://phpsos.de/ro/php/objektorientierung/).

## Declarații de tip: de la PHP 7.1 la 8.3

Declarațiile de tip stabilesc ce valori acceptă și returnează o funcție. Sistemul de tipuri a crescut de-a lungul multor versiuni. Potrivit jurnalului de modificări al manualului, au fost adăugate, printre altele, aceste posibilități:

| Versiune | Noutate |
|---|---|
| 7.1.0 | tipuri nullable (`?int`), `void`, `iterable` |
| 7.2.0 | `object` |
| 7.4.0 | proprietăți de clasă tipizate |
| 8.0.0 | tipuri union (mai multe tipuri permise într-o singură indicație), `mixed`, tipul returnat `static` |
| 8.1.0 | tipuri intersection (`A&B`), tipul returnat `never` |
| 8.2.0 | tipuri DNF, tipul literal `true`, `null` și `false` ca tipuri de sine stătătoare |
| 8.3.0 | constante tipizate de clasă, interfață, trait și enum |

DNF înseamnă formă normală disjunctivă și permite combinații precum `(A&B)|null`. Cine planifică versiunile PHP vede din acest tabel și ce mijloace ale limbajului presupune o aplicație.

## strict_types: conversie sau TypeError

Fără alte indicații, PHP lucrează în modul cu conversie. O funcție cu parametri `int` acceptă atunci și `1.5` și face din el `1`; din PHP 8.1, această conversie cu pierderi este marcată ca depășită. Cu `declare(strict_types=1)` la începutul fișierului, PHP aruncă în schimb un `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, în loc de 3 pe tăcute
```

Două subtilități sunt importante. În primul rând, `strict_types` se aplică apelurilor din fișierul în care este scris, nu funcțiilor definite acolo. Dacă un fișier fără `strict_types` apelează aceeași funcție, se face conversie. În al doilea rând, un număr întreg este permis acolo unde se așteaptă un număr în virgulă mobilă și în modul strict.

## Comparații laxe și stricte

Operatorul `==` compară după conversia tipului, `===` compară valoarea și tipul, fără conversie. Manualul recomandă în majoritatea cazurilor `===` și `!==`, deoarece regulile de conversie nu sunt întotdeauna evidente.

```php
<?php
var_dump(0 == "a");    // PHP 7: true,  PHP 8: false
var_dump("1" == "01"); // true, ambele sunt șiruri numerice
var_dump("1" === "01");// false, același tip, dar alt șir de caractere
var_dump(1 == true);   // true
var_dump(1 === true);  // false
```

Cu PHP 8.0, comparațiile între numere și șiruri de caractere nenumerice au devenit mai rezonabile. Aplicațiile mai vechi se pot comporta diferit după upgrade, de exemplu în blocurile `switch`. Expresia `match`, introdusă tot cu PHP 8.0, compară întotdeauna strict. Cum duc comparațiile laxe la vulnerabilități, de exemplu la verificarea token-urilor sau a parolelor, descrie articolul [Type juggling: comparațiile laxe ca risc de securitate](https://phpsos.de/ro/blog/type-juggling-php/).

## Tipuri, upgrade-uri și PHP2Shell

Un sistem de tipuri strict face codul aplicației mai robust, dar nu protejează împotriva erorilor din interpretorul însuși. Vulnerabilitățile PHP2Shell CVE-2026-109618 și CVE-2026-109619 se află în gestionarea memoriei și a cererilor din PHP. Au fost remediate în PHP 8.5.12, 8.4.27, 8.3.36 și 8.2.35; după aceea, toate procesele PHP trebuie repornite.

Sistemul de tipuri joacă totuși un rol, și anume la upgrade. Aplicațiile care sunt încă blocate pe PHP 8.1 sau mai vechi nu mai primesc actualizări oficiale de la proiectul PHP. Un cod bine tipizat poate fi ridicat mult mai ușor la o versiune acceptată, deoarece instrumentele găsesc devreme incompatibilitățile. La proiectele mai vechi, vă sprijină [migrarea la o versiune PHP acceptată](https://phpsos.de/ro/leistungen/php-migration-legacy/).

> **Sfat:**
> Activați `strict_types` treptat, în fișierele noi și în cele revizuite. Astfel crește siguranța tipurilor, fără ca vechiul cod să se strice dintr-odată.

## Cum ajută PHP SOS concret?

- Verificăm ce versiune PHP are nevoie minimă aplicația dumneavoastră și o comparăm cu versiunile remediate.
- Rulăm analiza statică peste cod și marcăm locurile cu comparații laxe în verificări relevante pentru securitate.
- Planificăm upgrade-urile astfel încât regulile de comparație modificate să fie testate în prealabil.
- Instalăm actualizarea PHP, repornim toți workerii și documentăm starea.


## Întrebări frecvente

**Este PHP tipizat puternic sau slab?**  
PHP este tipizat dinamic: tipul unei variabile se stabilește abia la execuție. Fără strict_types, PHP convertește valorile la nevoie. Cu declarații de tip și strict_types, codul poate fi însă făcut foarte strict.

**Ce face declare(strict_types=1)?**  
Dezactivează conversia automată a valorilor scalare pentru apelurile din fișierul respectiv. Dacă o valoare nu se potrivește cu tipul declarat, PHP aruncă un TypeError. Singura excepție este un număr întreg acolo unde se așteaptă un număr în virgulă mobilă.

**De ce este 0 == "a" fals în PHP 8, dar adevărat în PHP 7?**  
Până la PHP 7, la compararea cu un număr, un șir de caractere nenumeric era convertit într-un număr, iar din "a" rezulta 0. Din PHP 8.0, în acest caz PHP nu mai compară numeric, iar rezultatul este false.

**Protejează tipurile împotriva vulnerabilităților din PHP însuși?**  
Nu. Tipurile previn erorile din codul aplicației dumneavoastră. Vulnerabilitățile din interpretor, precum PHP2Shell, se închid doar printr-o actualizare PHP. Funcțiile moderne de tipizare presupun însă versiuni PHP actuale și sunt astfel un bun prilej de upgrade.

## Surse

- [Manualul PHP: declarații de tip](https://www.php.net/manual/de/language.types.declarations.php)
- [Manualul PHP: introducere în tipuri](https://www.php.net/manual/de/language.types.intro.php)
- [Manualul PHP: operatori de comparație](https://www.php.net/manual/de/language.operators.comparison.php)
- [Lansarea PHP 8.0](https://www.php.net/releases/8.0/en.php)
