# Imenski prostori in samodejno nalaganje (PSR-4)

> Imenski prostori PHP in samodejno nalaganje s PSR-4: od imena razreda do poti datoteke, spl_autoload_register, nalagalnik Composer in preverjanje po incidentih.

Vir: https://phpsos.de/sl/php/namespaces-autoloading/  
Stanje: 25.10.2026  
Ponudnik: PHP SOS, Nujna pomoč za PHP in varnost strežnikov. Takojšnja pomoč po WhatsAppu: https://wa.me/491736494914?text=Pozdravljeni%2C%20PHP%20SOS%2C%20potrebujemo%20pomo%C4%8D%20z%20na%C5%A1im%20stre%C5%BEnikom%20PHP.%20Podjetje%3A%20%E2%80%A6%20Spletna%20stran%3A%20%E2%80%A6

**Na kratko:** Imenski prostori so v PHP nekaj podobnega mapam za imena razredov: `App\Rechnung\Pdf` in `Bibliothek\Pdf` lahko obstajata drug ob drugem, ne da bi si ovirala pot. Samodejno nalaganje poskrbi, da PHP razred naloži šele, ko ga prvič potrebuje. Standard PSR-4 določa, kako iz imena razreda nastane pot datoteke; Composer nato ustvari ustrezen nalagalnik. Ker ta nalagalnik teče ob vsaki zahtevi, sodi po varnostnem incidentu med prve stvari, ki jih je treba preveriti.

## Zakaj PHP potrebuje imenske prostore

Imenski prostori obstajajo od PHP 5.3.0. Prej so si vsi razredi in funkcije delili en sam globalni imenski prostor. Če sta se dve knjižnici imenovali `Logger`, je počilo. Razvijalci so si pomagali z dolgimi imeni, kot je `Firma_Modul_Unterbereich_Logger`.

Priročnik PHP navaja dve težavi, ki ju rešujejo imenski prostori: trke imen med lastno kodo, notranjimi razredi PHP in knjižnicami tretjih ponudnikov ter predolga imena, ki so nastala samo za zaobhod teh trkov. Za odločevalce to pomeni: šele imenski prostori so omogočili praktično združevanje na desetine tujih paketov v enem projektu, kot je danes običajno s [Composerjem](https://phpsos.de/sl/php/composer/).

## Imenski prostori v praksi: namespace, use, vzdevki

Datoteka svoj imenski prostor deklarira v prvem ukazu. Z `use` se razredi iz drugih imenskih prostorov prinesejo noter, po želji pod krajšim imenom.

```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);
    }
}
```

Polno ime tega razreda je `App\Rechnung\PdfErzeuger`. Vodilna poševnica nazaj pri `\sprintf` izrecno kaže na globalno funkcijo PHP.

## Samodejno nalaganje: nalaganje razredov po potrebi

Brez samodejnega nalaganja bi moral vsaka skripta vse potrebne datoteke vključiti z `require`. Z `spl_autoload_register()` se namesto tega registrira funkcija, ki jo PHP pokliče, brž ko se uporabi neznan razred, vmesnik, trait ali enum. Prejme ime razreda in naloži ustrezno datoteko.

```php
<?php
spl_autoload_register(function (string $klasse): void {
    $praefix = 'App\\';
    $basis   = __DIR__ . '/src/';

    if (!str_starts_with($klasse, $praefix)) {
        return; // ni pristojen, na vrsti je naslednji nalagalnik
    }
    $datei = $basis . str_replace('\\', '/', substr($klasse, strlen($praefix))) . '.php';
    if (is_file($datei)) {
        require $datei;
    }
});
```

`spl_autoload_register()` je mogoče poklicati večkrat. PHP nato registrirane nalagalnike sprašuje zaporedoma, dokler eden ne naloži razreda. V praksi imajo velike aplikacije pogosto več nalagalnikov: nalagalnik Composer za knjižnice, lasten nalagalnik sistema CMS in druge od vtičnikov ali modulov. Za skrbnike to pomeni: katera koda se ob zahtevi dejansko naloži, izhaja iz sodelovanja vseh teh nalagalnikov, ne samo iz strukture map.

Priročnik izrecno odsvetuje sprožanje izjem v nalagalniku; PSR-4 to izrecno prepoveduje. Starejša funkcija `__autoload()` je bila s PHP 7.2.0 označena kot zastarela in s PHP 8.0.0 odstranjena.

## PSR-4: od imena razreda do poti datoteke

PSR-4 je standard PHP-FIG. Polno ime razreda se začne z imenskim prostorom ponudnika. Predpona imenskega prostora se preslika v osnovni imenik, preostanek imena da podmape, datoteka pa se konča z `.php`. Velike in male črke se morajo natančno ujemati. Tako je videti preslikava v `composer.json`:

```json
{
    "autoload": {
        "psr-4": { "App\\": "src/" }
    }
}
```

| Ime razreda | Datoteka |
|---|---|
| `App\Kunde\Kunde` | `src/Kunde/Kunde.php` |
| `App\Rechnung\PdfErzeuger` | `src/Rechnung/PdfErzeuger.php` |
| `App\Rechnung\Pdf\Vorlage` | `src/Rechnung/Pdf/Vorlage.php` |

Klasična spodrsljaja so velike in male črke. Na razvojnih računalnikih z Windows ali macOS datotečni sistem pogosto ne razlikuje med `Kunde.php` in `kunde.php`, na strežniku Linux pa ju. Aplikacija, ki lokalno deluje, na strežniku razreda ne najde. Pravilo PSR-4, da se imena uporabljajo v natančno pravilnem zapisu, take presenečenja ob dostavi preprečuje.

Poleg `psr-4` Composer pozna `classmap` za kodo brez standardne strukture in `files` za datoteke, ki se naložijo ob vsaki zahtevi, na primer pomožne funkcije. Druge standarde PHP-FIG opisuje stran [Standardi PSR](https://phpsos.de/sl/php/psr-standards/).

## Optimizacija nalagalnika v produkciji

V produkciji nalagalnik najbolje ne išče več v datotečnem sistemu, temveč išče v že pripravljenem seznamu. Composer za to ponuja dve stopnji:

1. `composer install --no-dev --optimize-autoloader` pravila PSR-4 pretvori v seznam razredov. To je po dokumentaciji Composerja za produkcijo priporočeno.
2. `--classmap-authoritative` gre dlje: razredi se nalagajo izključno s seznama. Nalagalnik datotek, ki niso navedene, sploh ne naloži.
3. Ob vsaki dostavi se seznam ustvari znova, da se najdejo novi razredi.

## Samodejno nalaganje in varnost po PHP2Shell

PHP2Shell zadeva interpreter PHP, ne nalagalnika. Obvezna ostaneta posodobitev na PHP 8.5.12, 8.4.27, 8.3.36 ali 8.2.35 in ponovni zagon vseh workerjev. Po morebitnem incidentu pa si nalagalnik zasluži posebno pozornost: `vendor/autoload.php` in vse datoteke, vpisane pod `files`, se izvedejo ob vsaki zahtevi. Tja vrinjena vrstica torej deluje na celotni spletni strani, ne da bi v mapi za nalaganje ležala kakšna opazna nova datoteka.

Zato preverite, ali `vendor` in datoteke nalagalnika ustrezajo preverjenemu stanju iz upravljanja različic. Koristna sta prispevka [Iskanje nedavno spremenjenih datotek](https://phpsos.de/sl/blog/geaenderte-dateien-finden/) in [Primerjava jedrnih datotek CMS z izvirnikom](https://phpsos.de/sl/blog/cms-kerndateien-vergleichen/). Če ste v dvomih, je sveže ustvarjen `vendor` iz datoteke lock varnejši od vsakega posameznega popravila.

## Kako PHP SOS pomaga konkretno?

- `vendor`, nalagalnik in vstopne datoteke primerjamo s preverjenim stanjem in označimo vsako odstopanje.
- Nabor paketov znova vzpostavimo iz datoteke lock in nastavimo optimiran nalagalnik.
- Preverimo, ali v korenu spleta (webroot) leži samo javna mapa in izvorna koda ni neposredno dosegljiva prek URL.
- Pri okužbi prevzamemo čiščenje v okviru [odstranjevanja zlonamerne programske opreme](https://phpsos.de/sl/leistungen/malware-entfernung/) in dokumentiramo rezultat.


## Pogosta vprašanja

**Od kdaj obstajajo imenski prostori v PHP?**  
Od PHP 5.3.0. Po priročniku rešujejo dve težavi: trke imen med lastno kodo, PHP in knjižnicami tretjih ponudnikov ter predolga imena razredov, ki so nastala samo zato, da bi se takim trkom izognili.

**Kakšna je razlika med PSR-0 in PSR-4?**  
Oba preslikata imena razredov v poti datotek. Pri PSR-4 se predpona imenskega prostora v poti datoteke ne ponavlja, kar da bolj ploske imenike. PHP-FIG je PSR-0 uvrstil med zastarele, PSR-4 je priporočeni standard.

**Ali __autoload() še deluje?**  
Ne. __autoload() je bil s PHP 7.2.0 označen kot zastarel, s PHP 8.0.0 pa odstranjen. Danes se nalagalniki registrirajo s spl_autoload_register(), v praksi večinoma prek nalagalnika, ki ga ustvari Composer.

**Ali moram po ustvarjanju novega razreda nalagalnik ustvariti znova?**  
Pri čistih pravilih PSR-4 ne, po dokumentaciji Composerja je to ravno prednost PSR-4. Kdor v produkciji uporablja optimiran seznam razredov, ga mora ob vsaki dostavi ustvariti znova.

## Viri

- [PHP-FIG: nalagalnik PSR-4](https://www.php-fig.org/psr/psr-4/)
- [Priročnik PHP: imenski prostori, pregled](https://www.php.net/manual/de/language.namespaces.rationale.php)
- [Priročnik PHP: samodejno nalaganje](https://www.php.net/manual/de/language.oop5.autoload.php)
- [Composer: The composer.json schema](https://getcomposer.org/doc/04-schema.md)
