# Namnrymder och autoloading (PSR-4)

> PHP-namnrymder och autoloading med PSR-4: från klassnamn till filsökväg, spl_autoload_register, Composers autoloader och kontroll efter incidenter.

Källa: https://phpsos.de/sv/php/namespaces-autoloading/  
Aktualitet: 2026-10-25  
Leverantör: PHP SOS, PHP-nödhjälp och serversäkerhet. Omedelbar hjälp via WhatsApp: https://wa.me/491736494914?text=Hej%20PHP%20SOS%2C%20vi%20beh%C3%B6ver%20hj%C3%A4lp%20med%20v%C3%A5r%20PHP-server.%20F%C3%B6retag%3A%20%E2%80%A6%20Webbplats%3A%20%E2%80%A6

**Kort sagt:** Namnrymder är i PHP något i stil med mappar för klassnamn: `App\Rechnung\Pdf` och `Bibliothek\Pdf` kan finnas sida vid sida utan att störa varandra. Autoloading ser till att PHP laddar en klass först när den används för första gången. Standarden PSR-4 anger hur ett klassnamn blir en filsökväg; Composer genererar sedan den passande autoloadern. Eftersom autoloadern körs vid varje förfrågan hör den till det första som kontrolleras efter en säkerhetsincident.

## Varför PHP behöver namnrymder

Namnrymder finns sedan PHP 5.3.0. Dessförinnan delade alla klasser och funktioner på ett enda globalt namnutrymme. Hette två bibliotek `Logger` uppstod en konflikt. Utvecklare hjälpte sig med långa namn som `Firma_Modul_Unterbereich_Logger`.

PHP-manualen nämner två problem som namnrymder löser: namnkollisioner mellan egen kod, PHP-interna klasser och tredjepartsbibliotek, samt överlånga namn som bara uppstod för att kringgå de kollisionerna. För beslutsfattare betyder det: Först namnrymder gjorde det praktiskt möjligt att kombinera dussintals externa paket i ett projekt, som det idag är vanligt med [Composer](https://phpsos.de/sv/php/composer/).

## Namnrymder i praktiken: namespace, use, alias

En fil deklarerar sin namnrymd i det första uttrycket. Med `use` hämtar man in klasser från andra namnrymder, om så önskas under ett kortare namn.

```php
<?php
declare(strict_types=1);

namespace App\Rechnung;

use App\Kunde\Kunde;
use Psr\Log\LoggerInterface as Log;

final class PdfErzeuger
{
    public function __construct(private Log $log) {}

    public function erzeugen(Kunde $kunde): string
    {
        $this->log->info('PDF erzeugt', ['kunde' => $kunde->id]);
        return \sprintf('Rechnung für %s', $kunde->name);
    }
}
```

Det fullständiga namnet på den här klassen är `App\Rechnung\PdfErzeuger`. Det inledande omvända snedstrecket vid `\sprintf` hänvisar uttryckligen till den globala PHP-funktionen.

## Autoloading: ladda klasser vid behov

Utan autoloading måste varje skript binda in alla nödvändiga filer med `require`. Med `spl_autoload_register()` registrerar man i stället en funktion som PHP anropar så snart en okänd klass, ett gränssnitt, en trait eller en enum används. Den får klassnamnet och laddar den passande filen.

```php
<?php
spl_autoload_register(function (string $klasse): void {
    $praefix = 'App\\';
    $basis   = __DIR__ . '/src/';

    if (!str_starts_with($klasse, $praefix)) {
        return; // inte ansvarig, nästa autoloader får ta över
    }
    $datei = $basis . str_replace('\\', '/', substr($klasse, strlen($praefix))) . '.php';
    if (is_file($datei)) {
        require $datei;
    }
});
```

`spl_autoload_register()` kan anropas flera gånger. PHP frågar då de registrerade autoloaderna efter varandra tills en av dem har laddat klassen. I praktiken har stora applikationer ofta flera: Composers autoloader för bibliotek, en egen för CMS:et och ytterligare från plugin eller moduler. För administratörer betyder det: Vilken kod som faktiskt laddas vid en förfrågan följer av samspelet mellan alla de här autoloaderna och inte bara av katalogstrukturen.

Manualen avråder bestämt från att kasta exceptions i en autoloader; PSR-4 förbjuder det uttryckligen. Den äldre funktionen `__autoload()` markerades som föråldrad med PHP 7.2.0 och togs bort med PHP 8.0.0.

## PSR-4: från klassnamn till filsökväg

PSR-4 är en standard från PHP-FIG. Ett fullständigt klassnamn börjar med en tillverkarnamnrymd. Ett prefix av namnrymden kopplas till en baskatalog, resten av namnet ger underkataloger, och filen slutar på `.php`. Skiftläget måste stämma exakt. Så ser kopplingen ut i `composer.json`:

```json
{
    "autoload": {
        "psr-4": { "App\\": "src/" }
    }
}
```

| Klassnamn | Fil |
|---|---|
| `App\Kunde\Kunde` | `src/Kunde/Kunde.php` |
| `App\Rechnung\PdfErzeuger` | `src/Rechnung/PdfErzeuger.php` |
| `App\Rechnung\Pdf\Vorlage` | `src/Rechnung/Pdf/Vorlage.php` |

Ett klassiskt snubbelstein är skiftläget. På utvecklingsdatorer med Windows eller macOS skiljer filsystemet ofta inte mellan `Kunde.php` och `kunde.php`, på en Linux-server gör det det. En applikation som fungerar lokalt hittar då inte en klass på servern. PSR-4-regeln att använda namn med exakt rätt stavning förhindrar sådana överraskningar vid leverans.

Vid sidan av `psr-4` har Composer `classmap` för kod utan standardstruktur och `files` för filer som laddas vid varje förfrågan, till exempel hjälpfunktioner. Fler standarder från PHP-FIG beskriver sidan [PSR-standarder](https://phpsos.de/sv/php/psr-standards/).

## Optimera autoloadern i produktion

I produktion bör autoloadern helst inte längre söka i filsystemet utan slå upp i en färdig lista. Composer erbjuder två nivåer för det:

1. `composer install --no-dev --optimize-autoloader` omvandlar PSR-4-reglerna till en klasslista. Enligt Composers dokumentation rekommenderas det för produktion.
2. `--classmap-authoritative` går längre: Klasser laddas uteslutande från listan. Filer som inte finns med laddar autoloadern då inte alls.
3. Vid varje leverans genereras listan om, så att nya klasser hittas.

## Autoloading och säkerhet efter PHP2Shell

PHP2Shell gäller PHP-tolken, inte autoloadern. Kravet kvarstår: uppdateringen till PHP 8.5.12, 8.4.27, 8.3.36 eller 8.2.35 och omstart av alla workers. Efter en möjlig incident förtjänar autoloadern ändå särskild uppmärksamhet: `vendor/autoload.php` och alla filer som anges under `files` körs vid varje förfrågan. En rad som smugglats in där verkar alltså på hela webbplatsen, utan att någon iögonfallande ny fil ligger i uppladdningsmappen.

Kontrollera därför om `vendor` och autoload-filerna stämmer med det granskade läget i versionshanteringen. Användbara är inläggen [Hitta nyligen ändrade filer](https://phpsos.de/sv/blog/geaenderte-dateien-finden/) och [Jämför CMS-kärnfiler med originalet](https://phpsos.de/sv/blog/cms-kerndateien-vergleichen/). Vid tvivel är en nygenererad `vendor` från låsfilen säkrare än varje enskild reparation.

## Hur hjälper PHP SOS konkret?

- Vi jämför `vendor`, autoloader och ingångsfiler med det granskade läget och markerar varje avvikelse.
- Vi återställer paketbeståndet från låsfilen och ställer in en optimerad autoloader.
- Vi kontrollerar att bara den publika mappen ligger i webbroten och att källkod inte kan nås direkt via URL.
- Vid angrepp tar vi hand om saneringen inom ramen för [skadlig kod-borttagning](https://phpsos.de/sv/leistungen/malware-entfernung/) och dokumenterar resultatet.


## Vanliga frågor

**Sedan när finns namnrymder i PHP?**  
Sedan PHP 5.3.0. Enligt manualen löser de två problem: namnkollisioner mellan egen kod, PHP och tredjepartsbibliotek samt överlånga klassnamn som bara uppstod för att undvika sådana kollisioner.

**Vad är skillnaden mellan PSR-0 och PSR-4?**  
Båda kopplar klassnamn till filsökvägar. Med PSR-4 upprepas inte namnrymdsprefixet i filsökvägen, vilket ger plattare kataloger. PSR-0 är klassat som föråldrat av PHP-FIG, PSR-4 är den rekommenderade standarden.

**Fungerar __autoload() fortfarande?**  
Nej. __autoload() markerades som föråldrad med PHP 7.2.0 och togs bort med PHP 8.0.0. Idag registrerar man autoloaders med spl_autoload_register(), i praktiken oftast via den autoloader som Composer genererar.

**Måste jag generera om autoloadern när jag skapar en ny klass?**  
Med rena PSR-4-regler behövs det inte, enligt Composers dokumentation är det just en fördel med PSR-4. Den som använder en optimerad klasslista i produktion måste generera om den vid varje leverans.

## Källor

- [PHP-FIG: PSR-4 Autoloader](https://www.php-fig.org/psr/psr-4/)
- [PHP-manualen: Namnrymder, översikt](https://www.php.net/manual/de/language.namespaces.rationale.php)
- [PHP-manualen: Autoloading](https://www.php.net/manual/de/language.oop5.autoload.php)
- [Composer: The composer.json schema](https://getcomposer.org/doc/04-schema.md)
