Situația actuală: PHP2Shell. Două vulnerabilități critice PHP (CVSS 9.2) permit cod malițios fără autentificare. Patchuri din 21.10.2026.Ce este de făcut acum →

Namespace-uri și autoloading (PSR-4)

Namespace-urile ordonează codul PHP, iar autoloading-ul încarcă clasele exact când sunt necesare. Aici vedeți cum PSR-4 asociază numele de clase cu fișiere și de ce autoloaderul trebuie verificat după un incident.

Stadiu 5 min de cititCunoștințe PHP

Pe scurt: Namespace-urile sunt în PHP un fel de foldere pentru numele de clase: App\Rechnung\Pdf și Bibliothek\Pdf pot exista unul lângă altul, fără să se deranjeze. Autoloading-ul face ca PHP să încarce o clasă abia când este nevoie de ea pentru prima dată. Standardul PSR-4 stabilește cum devine un nume de clasă o cale de fișier; Composer generează apoi autoloaderul potrivit. Deoarece acest autoloader rulează la fiecare cerere, el se numără după un incident de securitate printre primele lucruri verificate.

De ce are PHP nevoie de namespace-uri

Namespace-uri există din PHP 5.3.0. Înainte, toate clasele și funcțiile împărțeau un singur spațiu de nume global. Dacă două biblioteci se numeau Logger, totul se oprea. Dezvoltatorii se descurcau cu nume lungi, precum Firma_Modul_Unterbereich_Logger.

Manualul PHP menționează două probleme pe care le rezolvă namespace-urile: coliziunile de nume între codul propriu, clasele interne ale PHP și bibliotecile terților, precum și numele prea lungi, apărute doar pentru ocolirea acestor coliziuni. Pentru factorii de decizie, aceasta înseamnă: abia namespace-urile au făcut practică combinarea a zeci de pachete străine într-un proiect, așa cum este astăzi uzual cu Composer.

Namespace-uri în practică: namespace, use, alias-uri

Un fișier își declară namespace-ul în prima instrucțiune. Cu use se aduc clase din alte namespace-uri, la cerere sub un nume mai scurt.

<?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);
    }
}

Numele complet al acestei clase este App\Rechnung\PdfErzeuger. Backslash-ul de la început din \sprintf trimite în mod explicit la funcția PHP globală.

Autoloading: încărcarea claselor la nevoie

Fără autoloading, fiecare script ar trebui să includă toate fișierele necesare cu require. Cu spl_autoload_register() se înregistrează în schimb o funcție pe care PHP o apelează de îndată ce este folosită o clasă, o interfață, un trait sau un enum necunoscut. Ea primește numele clasei și încarcă fișierul potrivit.

<?php
spl_autoload_register(function (string $klasse): void {
    $praefix = 'App\\';
    $basis   = __DIR__ . '/src/';

    if (!str_starts_with($klasse, $praefix)) {
        return; // nu este responsabil, urmează următorul autoloader
    }
    $datei = $basis . str_replace('\\', '/', substr($klasse, strlen($praefix))) . '.php';
    if (is_file($datei)) {
        require $datei;
    }
});

spl_autoload_register() poate fi apelată de mai multe ori. PHP interoghează atunci autoloaderele înregistrate pe rând, până când unul încarcă clasa. În practică, aplicațiile mari au adesea mai multe: autoloaderul Composer pentru biblioteci, unul propriu al CMS-ului și altele ale plugin-urilor sau modulelor. Pentru administratori aceasta înseamnă: ce cod este efectiv încărcat la o cerere rezultă din conlucrarea tuturor acestor autoloadere, nu doar din structura folderelor.

Manualul descurajează ferm aruncarea de excepții într-un autoloader; PSR-4 o interzice explicit. Mai vechea funcție __autoload() a fost marcată ca depășită în PHP 7.2.0 și eliminată în PHP 8.0.0.

PSR-4: de la numele clasei la calea fișierului

PSR-4 este un standard al PHP-FIG. Un nume complet de clasă începe cu un namespace de producător. Un prefix al namespace-ului este asociat unui director de bază, restul numelui dă subfolderele, iar fișierul se termină în .php. Majusculele și minusculele trebuie să coincidă exact. Așa arată asocierea în composer.json:

{
    "autoload": {
        "psr-4": { "App\\": "src/" }
    }
}
Numele clasei Fișier
App\Kunde\Kunde src/Kunde/Kunde.php
App\Rechnung\PdfErzeuger src/Rechnung/PdfErzeuger.php
App\Rechnung\Pdf\Vorlage src/Rechnung/Pdf/Vorlage.php

O piedică clasică este diferența dintre majuscule și minuscule. Pe calculatoarele de dezvoltare cu Windows sau macOS, sistemul de fișiere nu face adesea distincție între Kunde.php și kunde.php, dar pe un server Linux o face. O aplicație care rulează local nu găsește atunci o clasă pe server. Regula din PSR-4 de a folosi numele exact în grafia corectă previne asemenea surprize la livrare.

Pe lângă psr-4, Composer cunoaște classmap pentru cod fără structură standard și files pentru fișiere încărcate la fiecare cerere, de exemplu funcții ajutătoare. Alte standarde ale PHP-FIG descrie pagina Standardele PSR.

Optimizarea autoloaderului în producție

În producție, autoloaderul nu ar trebui să mai caute în sistemul de fișiere, ci să consulte o listă gata făcută. Composer oferă pentru aceasta două trepte:

  1. composer install --no-dev --optimize-autoloader transformă regulile PSR-4 într-o listă de clase. Potrivit documentației Composer, aceasta este recomandată pentru producție.
  2. --classmap-authoritative merge mai departe: clasele sunt încărcate exclusiv din listă. Fișierele nemenționate nu sunt încărcate deloc de autoloader.
  3. La fiecare livrare lista este regenerată, pentru ca noile clase să fie găsite.

Autoloading și securitate după PHP2Shell

PHP2Shell afectează interpretorul PHP, nu autoloaderul. Rămân obligatorii actualizarea la PHP 8.5.12, 8.4.27, 8.3.36 sau 8.2.35 și repornirea tuturor workerilor. După un posibil incident, autoloaderul merită însă o atenție deosebită: vendor/autoload.php și toate fișierele înscrise la files sunt executate la fiecare cerere. O linie strecurată acolo acționează deci asupra întregului site, fără ca un fișier nou, suspect, să se afle în folderul de upload.

Verificați de aceea dacă vendor și fișierele de autoload corespund stării verificate din controlul versiunilor. Utile sunt articolele Găsirea fișierelor modificate recent și Compararea fișierelor de bază ale CMS-ului cu originalul. În caz de dubiu, un vendor proaspăt generat din fișierul lock este mai sigur decât orice reparație punctuală.

Cum ajută PHP SOS concret?

  • Comparăm vendor, autoloaderul și fișierele de intrare cu starea verificată și marcăm orice abatere.
  • Refacem inventarul de pachete din fișierul lock și configurăm un autoloader optimizat.
  • Verificăm dacă în webroot se află doar folderul public și dacă codul sursă nu este accesibil direct prin URL.
  • În caz de infectare, preluăm curățarea în cadrul eliminării malware-ului și documentăm rezultatul.

Întrebări frecvente

De când există namespace-uri în PHP?

Din PHP 5.3.0. Potrivit manualului, ele rezolvă două probleme: coliziunile de nume între codul propriu, PHP și bibliotecile terților, precum și numele de clase prea lungi, apărute doar pentru a evita asemenea coliziuni.

Care este diferența dintre PSR-0 și PSR-4?

Ambele asociază numele de clase cu căi de fișiere. La PSR-4, prefixul namespace-ului nu se repetă în calea fișierului, ceea ce dă directoare mai plate. PSR-0 este considerat depășit de PHP-FIG, iar PSR-4 este standardul recomandat.

Mai funcționează __autoload()?

Nu. __autoload() a fost marcată ca depășită în PHP 7.2.0 și eliminată în PHP 8.0.0. Astăzi autoloaderele se înregistrează cu spl_autoload_register(), în practică de obicei prin autoloaderul generat de Composer.

Trebuie să regenerez autoloaderul după crearea unei clase noi?

La reguli exclusiv PSR-4, nu; potrivit documentației Composer, tocmai acesta este un avantaj al PSR-4. Cine folosește în producție o listă optimizată de clase trebuie să o regenereze la fiecare livrare.

Surse

Contact imediat

Fiecare oră contează. Scrieți-ne acum.

Descrieți pe scurt sistemul, versiunea PHP și ce ați observat. Ne vom face auziți, clarificăm situația și lucrăm la distanță până când incidentul este încheiat și documentat.

Ajutor imediat