Aktuālā situācija: PHP2Shell. Divas kritiskas PHP ievainojamības (CVSS 9.2) ļauj izpildīt ļaunprātīgu kodu bez pieteikšanās. Ielāpi kopš 21.10.2026.Kas jādara tagad →

Nosaukumvietas un autoloading (PSR-4)

Nosaukumvietas sakārto PHP kodu, autoloading ielādē klases tieši tad, kad tās vajadzīgas. Šeit redzams, kā PSR-4 klašu nosaukumus attēlo failos un kāpēc autoloader pēc incidenta jāpārbauda.

Aktuāls uz 4 min lasīšanas laiksPHP zināšanas

Īsi: nosaukumvietas PHP ir kaut kas līdzīgs mapēm klašu nosaukumiem: App\Rechnung\Pdf un Bibliothek\Pdf var pastāvēt blakus, netraucējot cits citam. Autoloading nodrošina, ka PHP klasi ielādē tikai tad, kad tā pirmo reizi vajadzīga. Standarts PSR-4 nosaka, kā no klases nosaukuma rodas faila ceļš; Composer pēc tam izveido atbilstošu autoloader. Tā kā šis autoloader darbojas katrā pieprasījumā, pēc drošības incidenta tas ir starp pirmajām lietām, kas jāpārbauda.

Kāpēc PHP vajadzīgas nosaukumvietas

Nosaukumvietas ir kopš PHP 5.3.0. Iepriekš visas klases un funkcijas dalīja vienu globālu nosaukumu telpu. Ja divas bibliotēkas saucās Logger, sākās problēmas. Izstrādātāji palīdzēja sev ar gariem nosaukumiem, piemēram, Firma_Modul_Unterbereich_Logger.

PHP rokasgrāmata min divas problēmas, ko nosaukumvietas atrisina: nosaukumu sadursmes starp paša kodu, PHP iekšējām klasēm un trešo pušu bibliotēkām, kā arī pārāk garus nosaukumus, kas radās tikai šo sadursmju apiešanai. Lēmumu pieņēmējiem tas nozīmē: tikai nosaukumvietas ļāva praktiski apvienot vienā projektā desmitiem svešu pakotņu, kā tas šodien ir ierasts ar Composer.

Nosaukumvietas praksē: namespace, use, aizstājvārdi

Fails savu nosaukumvietu deklarē pirmajā priekšrakstā. Ar use var ievilkt klases no citām nosaukumvietām, ja vēlas, ar īsāku nosaukumu.

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

Šīs klases pilnais nosaukums ir App\Rechnung\PdfErzeuger. Sākuma atpakaļsvītra pie \sprintf skaidri norāda uz globālo PHP funkciju.

Autoloading: klašu ielāde pēc vajadzības

Bez autoloading katram skriptam visi nepieciešamie faili būtu jāpievieno ar require. Ar spl_autoload_register() tā vietā reģistrē funkciju, ko PHP izsauc, tiklīdz tiek izmantota nezināma klase, interfeiss, trait vai enum. Tā saņem klases nosaukumu un ielādē atbilstošo failu.

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

    if (!str_starts_with($klasse, $praefix)) {
        return; // nav atbildīgs, nākamais autoloader
    }
    $datei = $basis . str_replace('\\', '/', substr($klasse, strlen($praefix))) . '.php';
    if (is_file($datei)) {
        require $datei;
    }
});

spl_autoload_register() var izsaukt vairākkārt. PHP tad jautā reģistrētajiem autoloader pa vienam, līdz kāds klasi ielādē. Praksē lielām lietojumprogrammām to bieži ir vairāki: Composer autoloader bibliotēkām, paša CMS autoloader un citi no spraudņiem vai moduļiem. Administratoriem tas nozīmē: kāds kods pieprasījumā patiešām tiek ielādēts, izriet no visu šo autoloader sadarbības, nevis tikai no mapju struktūras.

Rokasgrāmata stingri iesaka autoloader nemest izņēmumus; PSR-4 to skaidri aizliedz. Vecākā funkcija __autoload() ar PHP 7.2.0 tika atzīta par novecojušu un ar PHP 8.0.0 noņemta.

PSR-4: no klases nosaukuma uz faila ceļu

PSR-4 ir PHP-FIG standarts. Pilns klases nosaukums sākas ar ražotāja nosaukumvietu. Nosaukumvietas prefikss tiek piesaistīts bāzes direktorijam, pārējā nosaukuma daļa dod apakšmapes, un fails beidzas ar .php. Lielajiem un mazajiem burtiem jāsakrīt precīzi. Šādi piesaiste izskatās failā composer.json:

{
    "autoload": {
        "psr-4": { "App\\": "src/" }
    }
}
Klases nosaukums Fails
App\Kunde\Kunde src/Kunde/Kunde.php
App\Rechnung\PdfErzeuger src/Rechnung/PdfErzeuger.php
App\Rechnung\Pdf\Vorlage src/Rechnung/Pdf/Vorlage.php

Klasisks klupšanas akmens ir lielo un mazo burtu rakstība. Izstrādes datoros ar Windows vai macOS failu sistēma bieži nešķir Kunde.php un kunde.php, Linux serverī gan. Lietojumprogramma, kas lokāli darbojas, serverī tad klasi neatrod. PSR-4 noteikums lietot nosaukumus tieši pareizā rakstībā novērš šādus pārsteigumus piegādes laikā.

Līdzās psr-4 Composer pazīst classmap kodam bez standarta struktūras un files failiem, kas tiek ielādēti katrā pieprasījumā, piemēram, palīgfunkcijām. Citus PHP-FIG standartus apraksta lapa PSR standarti.

Autoloader optimizēšana produkcijā

Produkcijā autoloader vislabāk vairs nemeklē failu sistēmā, bet skatās gatavā sarakstā. Composer tam piedāvā divus līmeņus:

  1. composer install --no-dev --optimize-autoloader pārveido PSR-4 noteikumus klašu sarakstā. Saskaņā ar Composer dokumentāciju tas ir ieteicams produkcijai.
  2. --classmap-authoritative iet tālāk: klases tiek ielādētas tikai no saraksta. Sarakstā neminētos failus autoloader tad nemaz neielādē.
  3. Katrā piegādē saraksts tiek izveidots no jauna, lai jaunās klases tiktu atrastas.

Autoloading un drošība pēc PHP2Shell

PHP2Shell attiecas uz PHP interpretatoru, nevis uz autoloader. Obligāti paliek atjauninājums uz PHP 8.5.12, 8.4.27, 8.3.36 vai 8.2.35 un visu darbprocesu pārstartēšana. Pēc iespējama incidenta autoloader tomēr pelna īpašu uzmanību: vendor/autoload.php un visi zem files ierakstītie faili tiek izpildīti katrā pieprasījumā. Tur ievadīta rinda tātad iedarbojas uz visu vietni, un augšupielāžu mapē nav jābūt redzamam jaunam failam.

Tāpēc pārbaudiet, vai vendor un autoload faili atbilst pārbaudītajam stāvoklim no versiju pārvaldības. Noder raksti Nesen mainīto failu atrašana un CMS kodola failu salīdzināšana ar oriģinālu. Šaubu gadījumā no lock faila no jauna izveidots vendor ir drošāks nekā jebkurš atsevišķs labojums.

Kā PHP SOS palīdz konkrēti?

  • Mēs salīdzinām vendor, autoloader un ieejas failus ar pārbaudīto stāvokli un atzīmējam katru novirzi.
  • Mēs atjaunojam pakotņu kopumu no lock faila un iestatām optimizētu autoloader.
  • Mēs pārbaudām, vai webroot atrodas tikai publiskā mape un avota kods nav tieši sasniedzams pa URL.
  • Inficēšanas gadījumā mēs veicam attīrīšanu ļaunprogrammatūras noņemšanas ietvaros un dokumentējam rezultātu.

Biežāk uzdotie jautājumi

Kopš kura laika PHP ir nosaukumvietas?

Kopš PHP 5.3.0. Saskaņā ar rokasgrāmatu tās atrisina divas problēmas: nosaukumu sadursmes starp paša kodu, PHP un trešo pušu bibliotēkām, kā arī pārāk garus klašu nosaukumus, kas radās tikai, lai izvairītos no šādām sadursmēm.

Kāda ir atšķirība starp PSR-0 un PSR-4?

Abi attēlo klašu nosaukumus faila ceļos. PSR-4 gadījumā nosaukumvietas prefikss faila ceļā netiek atkārtots, tāpēc direktoriju struktūra ir plakanāka. PHP-FIG PSR-0 ir atzinusi par novecojušu, PSR-4 ir ieteicamais standarts.

Vai __autoload() joprojām darbojas?

Nē. __autoload() ar PHP 7.2.0 tika atzīta par novecojušu un ar PHP 8.0.0 noņemta. Šodien autoloader reģistrē ar spl_autoload_register(), praksē lielākoties ar Composer izveidoto autoloader.

Vai pēc jaunas klases izveides autoloader jāģenerē no jauna?

Tīru PSR-4 noteikumu gadījumā nē, saskaņā ar Composer dokumentāciju tā ir tieši PSR-4 priekšrocība. Kas produkcijā izmanto optimizētu klašu sarakstu, tas katrā piegādē jāizveido no jauna.

Avoti

Tūlītējs kontakts

Katra stunda ir svarīga. Rakstiet mums tūlīt.

Īsi aprakstiet sistēmu, PHP versiju un novēroto. Mēs sazināsimies, noskaidrosim situāciju un strādāsim attālināti, līdz incidents ir slēgts un dokumentēts.

Tūlītēja palīdzība