Aktuellt läge: PHP2Shell. Två kritiska PHP-sårbarheter (CVSS 9,2) tillåter skadlig kod utan inloggning. Patchar sedan den 21 oktober 2026.Vad som bör göras nu →

PHP:s typsystem

PHP är dynamiskt typat men har sedan PHP 7 fått ett allt striktare typsystem. Här ser ni typerna, de viktigaste versionerna och varför strikta jämförelser förhindrar säkerhetsfel.

Aktualitet 5 min läsningPHP-kunskap

Kort sagt: PHP är dynamiskt typat: Ett värdes typ fastställs först vid körning, och utan ytterligare föreskrifter omvandlar PHP värden automatiskt vid behov. Sedan PHP 7 kan dock parametrar, returvärden och egenskaper förses med typer, och declare(strict_types=1) gör kontrollen sträng. Den som kan reglerna och använder strikta jämförelser med === undviker en hel klass av logik- och säkerhetsfel.

Dynamiskt typat, men inte utan typer

I PHP behöver man inte ange någon typ vid $preis = 19.90;. PHP ser att det är ett flyttal. Om värdet senare kopplas ihop med en sträng omvandlar PHP det. Det beteendet kallas type juggling, alltså automatisk typomvandling. Det gör starten enkel men kan ge överraskande resultat.

För beslutsfattare är det relevant eftersom många äldre PHP-applikationer skrevs utan typangivelser. Sådan kod är svårare att granska och modernisera. Nyare projekt använder typer konsekvent, vilket gör fel synliga tidigare och först gör den statiska analysen med verktyg som PHPStan eller Psalm riktigt effektiv.

PHP:s typer i överblick

PHP-manualen nämner nio interna typer som varje uttryck kan ha. Vanligtvis delas de in i tre grupper:

Grupp Typer Exempel
Skalära typer bool, int, float, string true, 42, 3.5, "Text"
Sammansatta typer array, object, callable [1, 2], new DateTime()
Särskilda typer null, resource null, en öppnad fil

För typkontroller rekommenderar manualen is_*()-funktionerna som is_int(). För att undersöka ett värde passar get_debug_type(), som sedan PHP 8.0.0 ger de gängse typnamnen, medan det äldre gettype() till exempel returnerar "integer" och "double".

Vid sidan av den automatiska omvandlingen finns den uttryckliga: Med en cast som (int) $wert eller med settype() bestämmer koden själv vilken typ ett värde ska ha. Det är vanligt för inmatning från formulär, eftersom allt som kommer in via $_GET eller $_POST först är en sträng eller en array. En cast kontrollerar dock inte om värdet var vettigt: Av "abc" blir tyst 0. För inmatning är en riktig kontroll med filter_var() därför oftast det bättre valet.

Klasser och gränssnitt är också typer i PHP. En funktion kan alltså kräva att en parameter är ett objekt av en viss klass eller uppfyller ett visst gränssnitt. Hur klasser, gränssnitt och enums samverkar förklarar sidan Objektorientering i PHP.

Typdeklarationer: från PHP 7.1 till 8.3

Typdeklarationer anger vilka värden en funktion tar emot och returnerar. Typsystemet har vuxit över många versioner. Enligt manualens ändringslogg tillkom bland annat följande möjligheter:

Version Nytt
7.1.0 nullbara typer (?int), void, iterable
7.2.0 object
7.4.0 typade klassegenskaper
8.0.0 unionstyper (flera tillåtna typer i en angivelse), mixed, returtypen static
8.1.0 intersektionstyper (A&B), returtypen never
8.2.0 DNF-typer, literaltypen true, null och false som självständiga typer
8.3.0 typade konstanter i klasser, gränssnitt, traits och enums

DNF står för disjunktiv normalform och tillåter kombinationer som (A&B)|null. Den som planerar PHP-versioner ser av den här tabellen också vilka språkmedel en applikation förutsätter.

strict_types: omvandling eller TypeError

Utan ytterligare angivelse arbetar PHP i omvandlande läge. En funktion med int-parametrar tar då även emot 1.5 och gör om det till 1; sedan PHP 8.1 är den förlustbehäftade omvandlingen markerad som föråldrad. Med declare(strict_types=1) i filens början kastar PHP i stället ett 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 stället för tyst 3

Två finesser är viktiga. För det första gäller strict_types för anrop från filen där det står, inte för de funktioner som definieras där. Anropar en fil utan strict_types samma funktion sker omvandling. För det andra är ett heltal där ett flyttal förväntas tillåtet även i strikt läge.

Lösa och strikta jämförelser

Operatorn == jämför efter typomvandling, === jämför värde och typ utan omvandling. Manualen rekommenderar i de flesta fall === och !==, eftersom omvandlingsreglerna inte alltid är uppenbara.

<?php
var_dump(0 == "a");    // PHP 7: true,  PHP 8: false
var_dump("1" == "01"); // true, båda är numeriska strängar
var_dump("1" === "01");// false, samma typ men olika sträng
var_dump(1 == true);   // true
var_dump(1 === true);  // false

Med PHP 8.0 blev jämförelser mellan tal och icke-numeriska strängar mer rimliga. Äldre applikationer kan bete sig annorlunda efter uppgraderingen, till exempel i switch-block. Uttrycket match, som också infördes med PHP 8.0, jämför alltid strikt. Hur lösa jämförelser leder till säkerhetsluckor, till exempel vid kontroll av token eller lösenord, beskriver inlägget Type juggling: lösa jämförelser som säkerhetsrisk.

Typer, uppgraderingar och PHP2Shell

Ett strikt typsystem gör applikationskod mer robust, men det skyddar inte mot fel i själva tolken. PHP2Shell-sårbarheterna CVE-2026-109618 och CVE-2026-109619 ligger i PHP:s minnes- och förfrågningshantering. De är åtgärdade i PHP 8.5.12, 8.4.27, 8.3.36 och 8.2.35; därefter måste alla PHP-processer startas om.

Typsystemet spelar ändå en roll, nämligen vid uppgraderingen. Applikationer som fortfarande sitter fast på PHP 8.1 eller äldre får inga officiella uppdateringar längre från PHP-projektet. Väl typad kod går betydligt lättare att lyfta till en version som stöds, eftersom verktyg hittar inkompatibiliteter tidigt. För äldre projekt hjälper vår migrering till en PHP-version som stöds.

Tips

Aktivera strict_types stegvis i nya och omarbetade filer. Då växer typsäkerheten utan att gammal kod går sönder på en gång.

Hur hjälper PHP SOS konkret?

  • Vi kontrollerar vilken PHP-version er applikation minst behöver och jämför med de åtgärdade versionerna.
  • Vi kör statisk analys över koden och markerar ställen med lösa jämförelser i säkerhetsrelevanta kontroller.
  • Vi planerar uppgraderingar så att ändrade jämförelseregler testas i förväg.
  • Vi installerar PHP-uppdateringen, startar om alla workers och dokumenterar läget.

Vanliga frågor

Är PHP starkt eller svagt typat?

PHP är dynamiskt typat: En variabels typ fastställs först vid körning. Utan strict_types omvandlar PHP värden vid behov. Med typdeklarationer och strict_types kan koden ändå göras mycket sträng.

Vad gör declare(strict_types=1)?

Det stänger av den automatiska omvandlingen av skalära värden för anrop från just den filen. Passar ett värde inte den deklarerade typen kastar PHP ett TypeError. Det enda undantaget är ett heltal där ett flyttal förväntas.

Varför är 0 == "a" falskt i PHP 8 men sant i PHP 7?

Till och med PHP 7 omvandlades en icke-numerisk sträng vid jämförelse med ett tal till ett tal, och "a" blev 0. Sedan PHP 8.0 jämför PHP i det fallet inte längre numeriskt, och resultatet är false.

Skyddar typer mot säkerhetsluckor i själva PHP?

Nej. Typer förhindrar fel i er applikationskod. Luckor i tolken som PHP2Shell stängs bara av en PHP-uppdatering. Moderna typfunktioner kräver dock aktuella PHP-versioner och är därmed ett bra tillfälle att uppgradera.

Källor

Direktkontakt

Varje timme räknas. Skriv till oss nu.

Beskriv kort system, PHP-version och observation. Vi hör av oss, klarlägger läget och arbetar på distans tills incidenten är avslutad och dokumenterad.

Direkthjälp