Aktuel situation: PHP2Shell. To kritiske PHP-sårbarheder (CVSS 9,2) tillader skadelig kode uden login. Rettelser siden 21.10.2026.Hvad der skal gøres nu →

PHP's typesystem

PHP er dynamisk typet, men har siden PHP 7 fået et stadig strengere typesystem. Her ser I typerne, de vigtigste versioner og hvorfor strikte sammenligninger forebygger sikkerhedsfejl.

Status 5 min. læsetidPHP-viden

Kort sagt: PHP er dynamisk typet: En værdis type fastlægges først under kørslen, og uden yderligere angivelser omdanner PHP værdier automatisk efter behov. Siden PHP 7 kan parametre, returværdier og egenskaber dog forsynes med typer, og declare(strict_types=1) gør kontrollen streng. Den, der kender reglerne og bruger strikte sammenligninger med ===, undgår en hel klasse af logik- og sikkerhedsfejl.

Dynamisk typet, men ikke typeløs

I PHP behøver man ikke angive en type ved $preis = 19.90;. PHP genkender, at der er tale om et kommatal. Forbindes værdien senere med en tekststreng, omdanner PHP den. Denne adfærd kaldes type juggling, altså automatisk typeomdannelse. Det gør starten let, men kan føre til overraskende resultater.

For beslutningstagere er det relevant, fordi mange ældre PHP-applikationer blev skrevet uden typeangivelser. Sådan kode er sværere at kontrollere og modernisere. Nyere projekter bruger typer konsekvent, hvilket gør fejl synlige tidligere og først for alvor lader den statiske analyse virke med værktøjer som PHPStan eller Psalm.

PHP's typer i overblik

PHP-manualen nævner ni interne typer, som ethvert udtryk kan have. Sædvanligvis inddeles de i tre grupper:

Gruppe Typer Eksempel
Skalare typer bool, int, float, string true, 42, 3.5, "Text"
Sammensatte typer array, object, callable [1, 2], new DateTime()
Særlige typer null, resource null, en åbnet fil

Til typekontrol anbefaler manualen is_*()-funktionerne som is_int(). Til undersøgelse egner sig get_debug_type(), som siden PHP 8.0.0 leverer de gængse typenavne, mens den ældre gettype() for eksempel returnerer "integer" og "double".

Ud over den automatiske omdannelse findes den udtrykkelige: Med en cast som (int) $wert eller med settype() fastlægger koden selv, hvilken type en værdi skal have. Det er sædvanligt ved input fra formularer, for alt, der kommer ind via $_GET eller $_POST, er først en tekststreng eller et array. En cast kontrollerer dog ikke, om værdien var meningsfuld: Af "abc" bliver der stiltiende 0. Til input er en ægte kontrol med filter_var() derfor som regel det bedre valg.

Klasser og interfaces er også typer i PHP. En funktion kan altså kræve, at en parameter er et objekt af en bestemt klasse eller opfylder et bestemt interface. Hvordan klasser, interfaces og enums spiller sammen, forklarer siden Objektorientering i PHP.

Typedeklarationer: fra PHP 7.1 til 8.3

Typedeklarationer fastlægger, hvilke værdier en funktion modtager og returnerer. Typesystemet er vokset over mange versioner. Ifølge manualens ændringslog kom blandt andet disse muligheder til:

Version Nyt
7.1.0 nullable typer (?int), void, iterable
7.2.0 object
7.4.0 typede klasseegenskaber
8.0.0 union-typer (flere tilladte typer i én angivelse), mixed, returtypen static
8.1.0 intersection-typer (A&B), returtypen never
8.2.0 DNF-typer, literaltypen true, null og false som selvstændige typer
8.3.0 typede konstanter i klasser, interfaces, traits og enums

DNF står for disjunktiv normalform og tillader kombinationer som (A&B)|null. Den, der planlægger PHP-versioner, kan ud fra denne tabel også se, hvilke sprogmidler en applikation forudsætter.

strict_types: omdannelse eller TypeError

Uden yderligere angivelse arbejder PHP i omdannende tilstand. En funktion med int-parametre modtager så også 1.5 og gør det til 1; siden PHP 8.1 er denne tabsgivende omdannelse markeret som forældet. Med declare(strict_types=1) i begyndelsen af filen kaster PHP i stedet en 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, i stedet for stiltiende 3

To finesser er vigtige. For det første gælder strict_types for kald fra den fil, hvor det står, ikke for de funktioner, der er defineret dér. Kalder en fil uden strict_types den samme funktion, omdannes der. For det andet er et heltal tilladt, hvor der forventes et kommatal, også i den strenge tilstand.

Løse og strikte sammenligninger

Operatoren == sammenligner efter typeomdannelse, === sammenligner værdi og type uden omdannelse. Manualen anbefaler i de fleste tilfælde === og !==, fordi omdannelsesreglerne ikke altid er indlysende.

<?php
var_dump(0 == "a");    // PHP 7: true,  PHP 8: false
var_dump("1" == "01"); // true, begge er numeriske tekststrenge
var_dump("1" === "01");// false, samme type, men en anden tekststreng
var_dump(1 == true);   // true
var_dump(1 === true);  // false

Med PHP 8.0 blev sammenligninger mellem tal og ikke-numeriske tekststrenge mere fornuftige. Ældre applikationer kan efter opgraderingen opføre sig anderledes, f.eks. i switch-blokke. Udtrykket match, der også kom med PHP 8.0, sammenligner altid strikt. Hvordan løse sammenligninger fører til sårbarheder, for eksempel ved kontrol af tokens eller adgangskoder, beskriver indlægget Type juggling: løse sammenligninger som sikkerhedsrisiko.

Typer, opgraderinger og PHP2Shell

Et strengt typesystem gør applikationskode mere robust, men det beskytter ikke mod fejl i selve fortolkeren. PHP2Shell-sårbarhederne CVE-2026-109618 og CVE-2026-109619 ligger i PHP's hukommelses- og forespørgselshåndtering. De er rettet i PHP 8.5.12, 8.4.27, 8.3.36 og 8.2.35; derefter skal alle PHP-processer genstartes.

Typesystemet spiller alligevel en rolle, nemlig ved opgraderingen. Applikationer, der stadig sidder fast på PHP 8.1 eller ældre, får ikke længere officielle opdateringer fra PHP-projektet. Velskrevet kode med typer kan løftes betydeligt lettere til en understøttet version, fordi værktøjer finder uforeneligheder tidligt. Ved ældre projekter hjælper vores migrering til en understøttet PHP-version.

Tip

Aktivér strict_types trinvis i nye og gennemarbejdede filer. Så vokser typesikkerheden, uden at gammel kode går i stykker på én gang.

Hvordan hjælper PHP SOS konkret?

  • Vi undersøger, hvilken PHP-version jeres applikation mindst har brug for, og sammenholder det med de rettede versioner.
  • Vi lader statisk analyse køre over koden og markerer steder med løse sammenligninger i sikkerhedsrelevante kontroller.
  • Vi planlægger opgraderinger, så ændrede sammenligningsregler testes på forhånd.
  • Vi indspiller PHP-opdateringen, genstarter alle workers og dokumenterer status.

Ofte stillede spørgsmål

Er PHP stærkt eller svagt typet?

PHP er dynamisk typet: En variabels type fastlægges først under kørslen. Uden strict_types omdanner PHP værdier efter behov. Med typedeklarationer og strict_types kan koden dog gøres meget streng.

Hvad gør declare(strict_types=1)?

Det slår den automatiske omdannelse af skalare værdier fra for kald fra den pågældende fil. Passer en værdi ikke til den deklarerede type, kaster PHP en TypeError. Eneste undtagelse er et heltal, hvor der forventes et kommatal.

Hvorfor er 0 == "a" falsk i PHP 8, men sand i PHP 7?

Til og med PHP 7 blev en ikke-numerisk tekststreng omdannet til et tal ved sammenligning med et tal, så »a« blev til 0. Siden PHP 8.0 sammenligner PHP i dette tilfælde ikke længere numerisk, og resultatet er false.

Beskytter typer mod sårbarheder i selve PHP?

Nej. Typer forhindrer fejl i jeres applikationskode. Sårbarheder i fortolkeren som PHP2Shell lukkes kun ved en PHP-opdatering. Moderne typefunktioner forudsætter dog aktuelle PHP-versioner og er dermed en god anledning til at opgradere.

Kilder

Akut kontakt

Hver time tæller. Skriv til os nu.

Beskriv kort system, PHP-version og observation. Vi vender tilbage, afklarer situationen og arbejder på afstand, indtil hændelsen er afsluttet og dokumenteret.

Akut hjælp