Aktuális helyzet: PHP2Shell. Két kritikus PHP-rés (CVSS 9,2) lehetővé teszi kártékony kód futtatását bejelentkezés nélkül. Javítások 2026. 10. 21. óta.Mi a teendő most →

Névterek és autoloading (PSR-4)

A névterek rendezik a PHP-kódot, az autoloading pedig pontosan akkor tölti be az osztályokat, amikor szükség van rájuk. Itt látja, hogyan képezi le a PSR-4 az osztályneveket fájlokra, és miért kell incidens után ellenőrizni az autoloadert.

Állapot 5 perc olvasási időPHP-tudástár

Röviden: A névterek a PHP-ban az osztálynevek mappáihoz hasonlítanak: az App\Rechnung\Pdf és a Bibliothek\Pdf egymás mellett létezhet anélkül, hogy zavarnák egymást. Az autoloading gondoskodik arról, hogy a PHP egy osztályt csak akkor töltsön be, amikor először szükség van rá. A PSR-4 szabvány meghatározza, hogyan lesz az osztálynévből fájlútvonal; a Composer ehhez létrehozza a megfelelő autoloadert. Mivel ez az autoloader minden kérésnél lefut, biztonsági incidens után az elsők között kell ellenőrizni.

Miért van szüksége a PHP-nak névterekre

Névterek a PHP 5.3.0 óta léteznek. Előtte minden osztály és függvény egyetlen globális névtéren osztozott. Ha két programkönyvtárat is Logger-nek hívtak, baj lett. A fejlesztők hosszú nevekkel segítettek magukon, mint a Firma_Modul_Unterbereich_Logger.

A PHP-kézikönyv két problémát nevez meg, amelyeket a névterek megoldanak: a saját kód, a PHP belső osztályai és a harmadik fél programkönyvtárai közötti névütközéseket, valamint a túl hosszú neveket, amelyek csak ezeknek az ütközéseknek a megkerülésére keletkeztek. A döntéshozók számára ez azt jelenti: csak a névterek tették járhatóvá, hogy egy projektben több tucat idegen csomagot kombináljanak, ahogyan ez a Composerrel ma megszokott.

Névterek a gyakorlatban: namespace, use, aliasok

Egy fájl az első utasításban deklarálja a névterét. A use segítségével más névterekből hozhat be osztályokat, kívánság szerint rövidebb néven.

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

Ennek az osztálynak a teljes neve App\Rechnung\PdfErzeuger. A \sprintf előtti vezető fordított törtvonal kifejezetten a globális PHP-függvényre hivatkozik.

Autoloading: osztályok betöltése szükség esetén

Autoloading nélkül minden szkriptnek require-rel kellene beágyaznia az összes szükséges fájlt. Az spl_autoload_register() segítségével ehelyett egy olyan függvényt regisztrálnak, amelyet a PHP akkor hív meg, amint egy ismeretlen osztályt, interfészt, trait-et vagy enumot használnak. A függvény megkapja az osztálynevet, és betölti a megfelelő fájlt.

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

    if (!str_starts_with($klasse, $praefix)) {
        return; // nem illetékes, a következő autoloader jön
    }
    $datei = $basis . str_replace('\\', '/', substr($klasse, strlen($praefix))) . '.php';
    if (is_file($datei)) {
        require $datei;
    }
});

Az spl_autoload_register() többször is hívható. A PHP ilyenkor egymás után kérdezi a regisztrált autoloadereket, amíg egy be nem tölti az osztályt. A gyakorlatban a nagy alkalmazásoknak gyakran több is van belőlük: a Composer-autoloader a programkönyvtáraknak, a CMS saját autoloadere, és további autoloaderek a bővítményektől vagy modulokból. Az adminisztrátorok számára ez azt jelenti: hogy egy kérésnél valójában melyik kód töltődik be, az mindezen autoloaderek együttműködéséből adódik, nem pusztán a mappaszerkezetből.

A kézikönyv határozottan lemond arról, hogy egy autoloaderben kivételt dobjanak; a PSR-4 ezt kifejezetten tiltja. A régebbi __autoload() függvényt a PHP 7.2.0 elavultnak jelölte, a PHP 8.0.0-ban pedig eltávolították.

PSR-4: az osztálynévtől a fájl útvonaláig

A PSR-4 a PHP-FIG szabványa. A teljes osztálynév gyártói névtérrel kezdődik. A névtér egy előtagját egy alapkönyvtárhoz rendelik, a név többi része almappákat ad, a fájl pedig .php kiterjesztéssel végződik. A kis- és nagybetűknek pontosan egyezniük kell. Így néz ki a hozzárendelés a composer.json-ban:

{
    "autoload": {
        "psr-4": { "App\\": "src/" }
    }
}
Osztálynév Fájl
App\Kunde\Kunde src/Kunde/Kunde.php
App\Rechnung\PdfErzeuger src/Rechnung/PdfErzeuger.php
App\Rechnung\Pdf\Vorlage src/Rechnung/Pdf/Vorlage.php

Klasszikus buktató a kis- és nagybetűk kérdése. A Windowsos vagy macOS-es fejlesztői gépeken a fájlrendszer gyakran nem különbözteti meg a Kunde.php-t és a kunde.php-t, egy Linux-szerveren viszont igen. Egy helyben működő alkalmazás ilyenkor a szerveren nem találja az osztályt. A PSR-4 szabálya, hogy a neveket pontosan a helyes írásmóddal kell használni, megelőzi az ilyen meglepetéseket a kiszállításkor.

A psr-4 mellett a Composer ismeri a classmap-et a szabványos szerkezet nélküli kódhoz, és a files-t azokhoz a fájlokhoz, amelyek minden kérésnél betöltődnek, például segédfüggvényekhez. A PHP-FIG további szabványait a PSR-szabványok oldal írja le.

Az autoloader optimalizálása éles üzemben

Éles üzemben az autoloader a legjobb, ha már nem a fájlrendszerben keres, hanem egy kész listában néz utána. A Composer ehhez két fokozatot kínál:

  1. A composer install --no-dev --optimize-autoloader a PSR-4 szabályokat osztálylistává alakítja. Ez a Composer dokumentációja szerint éles üzemre ajánlott.
  2. A --classmap-authoritative továbbmegy: az osztályokat kizárólag a listából tölti be. A fel nem sorolt fájlokat az autoloader ilyenkor egyáltalán nem tölti be.
  3. Minden kiszállításkor újra kell generálni a listát, hogy az új osztályokat megtalálja.

Autoloading és biztonság a PHP2Shell után

A PHP2Shell a PHP-értelmezőt érinti, nem az autoloadert. Továbbra is kötelező a frissítés a PHP 8.5.12, 8.4.27, 8.3.36 vagy 8.2.35 verzióra, és az összes worker újraindítása. Egy lehetséges incidens után azonban az autoloader különös figyelmet érdemel: a vendor/autoload.php és a files alatt felvett összes fájl minden kérésnél lefut. Az oda beszúrt egyetlen sor tehát az egész weboldalon hat, anélkül hogy feltűnő új fájl lenne a feltöltési mappában.

Ellenőrizze ezért, hogy a vendor és az autoload-fájlok egyeznek-e a verziókezelésből származó, ellenőrzött állapottal. Hasznosak a Nemrég módosított fájlok megkeresése és a CMS-magfájlok összehasonlítása az eredetivel cikkek. Kétség esetén a lock-fájlból frissen előállított vendor biztonságosabb bármely egyedi javításnál.

Hogyan segít konkrétan a PHP SOS?

  • Összevetjük a vendor-t, az autoloadert és a belépési fájlokat az ellenőrzött állapottal, és megjelölünk minden eltérést.
  • A csomagállományt újra előállítjuk a lock-fájlból, és optimalizált autoloadert állítunk be.
  • Ellenőrizzük, hogy csak a nyilvános mappa van-e a webgyökérben, és a forráskód nem érhető-e el közvetlenül URL-en.
  • Fertőzés esetén a kártevőeltávolítás keretében elvégezzük a tisztítást, és dokumentáljuk az eredményt.

Gyakori kérdések

Mióta léteznek névterek a PHP-ban?

A PHP 5.3.0 óta. A kézikönyv szerint két problémát oldanak meg: az saját kód, a PHP és a harmadik fél programkönyvtárai közötti névütközéseket, valamint a túl hosszú osztályneveket, amelyek csak az ilyen ütközések elkerülésére keletkeztek.

Mi a különbség a PSR-0 és a PSR-4 között?

Mindkettő osztályneveket képez le fájlútvonalakra. A PSR-4-nél a névtér-előtag nem ismétlődik a fájl útvonalában, így laposabb könyvtárszerkezet jön létre. A PSR-0-t a PHP-FIG elavultnak minősítette, a PSR-4 az ajánlott szabvány.

Működik még az __autoload()?

Nem. Az __autoload()-ot a PHP 7.2.0 elavultnak jelölte, a PHP 8.0.0-ban pedig eltávolították. Ma az autoloadereket az spl_autoload_register() függvénnyel regisztrálják, a gyakorlatban többnyire a Composer által generált autoloaderen keresztül.

Újra kell generálni az autoloadert egy új osztály létrehozása után?

Tiszta PSR-4 szabályoknál nem, a Composer dokumentációja szerint éppen ez a PSR-4 egyik előnye. Aki éles üzemben optimalizált osztálylistát használ, annak minden kiszállításkor újra kell generálnia.

Források

Azonnali kapcsolat

Minden óra számít. Írjon nekünk most.

Ismertesse röviden a rendszert, a PHP-verziót és a megfigyelését. Jelentkezünk, tisztázzuk a helyzetet, és távolról dolgozunk, amíg az incidens le nem zárul és dokumentálva nem lesz.

Azonnali segítség