# Namespaces και autoloading (PSR-4)

> Namespaces και autoloading PHP με PSR-4: από το όνομα κλάσης στη διαδρομή αρχείου, spl_autoload_register, autoloader του Composer και έλεγχος μετά από περιστατικά.

Πηγή: https://phpsos.de/el/php/namespaces-autoloading/  
Ημερομηνία: 25/10/2026  
Πάροχος: PHP SOS, Επείγουσα βοήθεια PHP και ασφάλεια διακομιστών. Άμεση βοήθεια μέσω WhatsApp: https://wa.me/491736494914?text=%CE%93%CE%B5%CE%B9%CE%B1%20%CF%83%CE%B1%CF%82%2C%20PHP%20SOS%2C%20%CF%87%CF%81%CE%B5%CE%B9%CE%B1%CE%B6%CF%8C%CE%BC%CE%B1%CF%83%CF%84%CE%B5%20%CE%B2%CE%BF%CE%AE%CE%B8%CE%B5%CE%B9%CE%B1%20%CE%BC%CE%B5%20%CF%84%CE%BF%CE%BD%20%CE%B4%CE%B9%CE%B1%CE%BA%CE%BF%CE%BC%CE%B9%CF%83%CF%84%CE%AE%20PHP%20%CE%BC%CE%B1%CF%82.%20%CE%95%CF%84%CE%B1%CE%B9%CF%81%CE%B5%CE%AF%CE%B1%3A%20%E2%80%A6%20%CE%99%CF%83%CF%84%CF%8C%CF%84%CE%BF%CF%80%CE%BF%CF%82%3A%20%E2%80%A6

**Εν συντομία:** Τα namespaces είναι στην PHP κάτι σαν φάκελοι για ονόματα κλάσεων: οι `App\Rechnung\Pdf` και `Bibliothek\Pdf` μπορούν να συνυπάρχουν χωρίς να συγκρούονται. Το autoloading φροντίζει ώστε η PHP να φορτώνει μια κλάση μόνο όταν τη χρειαστεί για πρώτη φορά. Το πρότυπο PSR-4 ορίζει πώς από ένα όνομα κλάσης προκύπτει μια διαδρομή αρχείου· στη συνέχεια ο Composer δημιουργεί τον κατάλληλο autoloader. Επειδή αυτός ο autoloader εκτελείται σε κάθε αίτημα, ανήκει μετά από περιστατικό ασφαλείας στα πρώτα πράγματα που ελέγχονται.

## Γιατί η PHP χρειάζεται namespaces

Τα namespaces υπάρχουν από την PHP 5.3.0. Πριν, όλες οι κλάσεις και οι συναρτήσεις μοιράζονταν έναν ενιαίο καθολικό χώρο ονομάτων. Αν δύο βιβλιοθήκες ονομάζονταν `Logger`, υπήρχε σύγκρουση. Οι προγραμματιστές βοηθούσαν τον εαυτό τους με μακριά ονόματα όπως `Firma_Modul_Unterbereich_Logger`.

Το εγχειρίδιο της PHP αναφέρει δύο προβλήματα που λύνουν τα namespaces: συγκρούσεις ονομάτων μεταξύ του δικού σας κώδικα, των εσωτερικών κλάσεων της PHP και βιβλιοθηκών τρίτων, καθώς και υπερβολικά μακριά ονόματα που δημιουργήθηκαν μόνο για την παράκαμψη αυτών των συγκρούσεων. Για όσους αποφασίζουν αυτό σημαίνει: μόνο τα namespaces κατέστησαν πρακτικό τον συνδυασμό δεκάδων ξένων πακέτων σε ένα έργο, όπως είναι σήμερα συνηθισμένο με τον [Composer](https://phpsos.de/el/php/composer/).

## Namespaces στην πράξη: namespace, use, aliases

Ένα αρχείο δηλώνει το namespace του στην πρώτη εντολή. Με το `use` φέρνετε κλάσεις από άλλα namespaces, αν θέλετε με συντομότερο όνομα.

```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);
    }
}
```

Το πλήρες όνομα αυτής της κλάσης είναι `App\Rechnung\PdfErzeuger`. Η αρχική ανάστροφη κάθετος στο `\sprintf` παραπέμπει ρητά στην καθολική συνάρτηση της PHP.

## Autoloading: φόρτωση κλάσεων όταν χρειάζονται

Χωρίς autoloading, κάθε σενάριο θα έπρεπε να συμπεριλαμβάνει όλα τα απαιτούμενα αρχεία με `require`. Με την `spl_autoload_register()` καταχωρίζετε αντίθετα μια συνάρτηση που καλεί η PHP μόλις χρησιμοποιηθεί μια άγνωστη κλάση, διεπαφή, trait ή enum. Η συνάρτηση λαμβάνει το όνομα της κλάσης και φορτώνει το κατάλληλο αρχείο.

```php
<?php
spl_autoload_register(function (string $klasse): void {
    $praefix = 'App\\';
    $basis   = __DIR__ . '/src/';

    if (!str_starts_with($klasse, $praefix)) {
        return; // δεν είναι αρμοδιότητά μας, σειρά έχει ο επόμενος autoloader
    }
    $datei = $basis . str_replace('\\', '/', substr($klasse, strlen($praefix))) . '.php';
    if (is_file($datei)) {
        require $datei;
    }
});
```

Η `spl_autoload_register()` μπορεί να κληθεί πολλές φορές. Η PHP ρωτά τότε τους καταχωρισμένους autoloaders με τη σειρά, μέχρι να φορτώσει κάποιος την κλάση. Στην πράξη οι μεγάλες εφαρμογές έχουν συχνά περισσότερους από έναν: τον autoloader του Composer για βιβλιοθήκες, έναν δικό του του CMS και άλλους από πρόσθετα ή modules. Για τους διαχειριστές αυτό σημαίνει: ποιος κώδικας φορτώνεται πραγματικά σε ένα αίτημα προκύπτει από τη συνεργασία όλων αυτών των autoloaders και όχι μόνο από τη δομή των φακέλων.

Το εγχειρίδιο αποτρέπει έντονα την ρίψη exceptions μέσα σε έναν autoloader· το PSR-4 το απαγορεύει ρητά. Η παλαιότερη συνάρτηση `__autoload()` χαρακτηρίστηκε παρωχημένη με την PHP 7.2.0 και αφαιρέθηκε με την PHP 8.0.0.

## PSR-4: από το όνομα κλάσης στη διαδρομή αρχείου

Το PSR-4 είναι πρότυπο του PHP-FIG. Ένα πλήρες όνομα κλάσης ξεκινά με ένα namespace κατασκευαστή. Ένα πρόθεμα του namespace αντιστοιχίζεται σε έναν βασικό κατάλογο, το υπόλοιπο του ονόματος δίνει υποφακέλους και το αρχείο τελειώνει σε `.php`. Τα κεφαλαία και μικρά γράμματα πρέπει να ταιριάζουν ακριβώς. Έτσι μοιάζει η αντιστοίχιση στο `composer.json`:

```json
{
    "autoload": {
        "psr-4": { "App\\": "src/" }
    }
}
```

| Όνομα κλάσης | Αρχείο |
|---|---|
| `App\Kunde\Kunde` | `src/Kunde/Kunde.php` |
| `App\Rechnung\PdfErzeuger` | `src/Rechnung/PdfErzeuger.php` |
| `App\Rechnung\Pdf\Vorlage` | `src/Rechnung/Pdf/Vorlage.php` |

Ένα κλασικό εμπόδιο είναι η διάκριση κεφαλαίων και πεζών. Σε υπολογιστές ανάπτυξης με Windows ή macOS το σύστημα αρχείων συχνά δεν κάνει διάκριση μεταξύ `Kunde.php` και `kunde.php`, σε έναν διακομιστή Linux όμως κάνει. Μια εφαρμογή που τρέχει τοπικά δεν βρίσκει τότε μια κλάση στον διακομιστή. Ο κανόνας του PSR-4 να χρησιμοποιούνται τα ονόματα ακριβώς με τη σωστή γραφή αποτρέπει τέτοιες εκπλήξεις κατά την παράδοση.

Εκτός από το `psr-4`, ο Composer γνωρίζει το `classmap` για κώδικα χωρίς τυπική δομή και το `files` για αρχεία που φορτώνονται σε κάθε αίτημα, όπως βοηθητικές συναρτήσεις. Περισσότερα πρότυπα του PHP-FIG περιγράφει η σελίδα [Πρότυπα PSR](https://phpsos.de/el/php/psr-standards/).

## Βελτιστοποίηση του autoloader στην παραγωγή

Στην παραγωγή ο autoloader δεν αναζητά καλύτερα στο σύστημα αρχείων, αλλά ανατρέχει σε μια έτοιμη λίστα. Ο Composer προσφέρει γι' αυτό δύο στάδια:

1. Το `composer install --no-dev --optimize-autoloader` μετατρέπει τους κανόνες PSR-4 σε λίστα κλάσεων. Σύμφωνα με την τεκμηρίωση του Composer, αυτό συνιστάται για την παραγωγή.
2. Το `--classmap-authoritative` προχωρά περισσότερο: οι κλάσεις φορτώνονται αποκλειστικά από τη λίστα. Αρχεία που δεν αναφέρονται δεν τα φορτώνει τότε καθόλου ο autoloader.
3. Σε κάθε παράδοση η λίστα δημιουργείται εκ νέου, ώστε να βρίσκονται οι νέες κλάσεις.

## Autoloading και ασφάλεια μετά το PHP2Shell

Το PHP2Shell αφορά τον διερμηνέα της PHP, όχι τον autoloader. Παραμένουν υποχρεωτικές η ενημέρωση στην PHP 8.5.12, 8.4.27, 8.3.36 ή 8.2.35 και η επανεκκίνηση όλων των workers. Μετά από ένα πιθανό περιστατικό, ο autoloader αξίζει όμως ιδιαίτερη προσοχή: το `vendor/autoload.php` και όλα τα αρχεία που έχουν καταχωριστεί στο `files` εκτελούνται σε κάθε αίτημα. Μια γραμμή που έχει εισαχθεί εκεί επηρεάζει επομένως ολόκληρο τον ιστότοπο, χωρίς να βρίσκεται κάποιο ύποπτο νέο αρχείο στον φάκελο μεταφορτώσεων.

Ελέγξτε γι' αυτό αν ο φάκελος `vendor` και τα αρχεία autoload ταιριάζουν με την ελεγμένη κατάσταση από τον έλεγχο εκδόσεων. Χρήσιμα είναι τα άρθρα [Εντοπισμός πρόσφατα τροποποιημένων αρχείων](https://phpsos.de/el/blog/geaenderte-dateien-finden/) και [Σύγκριση των αρχείων πυρήνα του CMS με το πρωτότυπο](https://phpsos.de/el/blog/cms-kerndateien-vergleichen/). Σε περίπτωση αμφιβολίας, ένας φάκελος `vendor` που δημιουργείται εκ νέου από το lock αρχείο είναι ασφαλέστερος από κάθε μεμονωμένη επιδιόρθωση.

## Πώς βοηθά συγκεκριμένα η PHP SOS;

- Συγκρίνουμε το `vendor`, τον autoloader και τα αρχεία εισόδου με την ελεγμένη κατάσταση και επισημαίνουμε κάθε απόκλιση.
- Αποκαθιστούμε εκ νέου το σύνολο πακέτων από το lock αρχείο και ρυθμίζουμε έναν βελτιστοποιημένο autoloader.
- Ελέγχουμε αν στο webroot βρίσκεται μόνο ο δημόσιος φάκελος και αν ο πηγαίος κώδικας δεν είναι προσβάσιμος απευθείας μέσω URL.
- Σε περίπτωση μόλυνσης αναλαμβάνουμε τον καθαρισμό στο πλαίσιο της [αφαίρεσης κακόβουλου λογισμικού](https://phpsos.de/el/leistungen/malware-entfernung/) και τεκμηριώνουμε το αποτέλεσμα.


## Συχνές ερωτήσεις

**Από πότε υπάρχουν namespaces στην PHP;**  
Από την PHP 5.3.0. Σύμφωνα με το εγχειρίδιο λύνουν δύο προβλήματα: τις συγκρούσεις ονομάτων μεταξύ του δικού σας κώδικα, της PHP και βιβλιοθηκών τρίτων, καθώς και τα υπερβολικά μακριά ονόματα κλάσεων που δημιουργήθηκαν μόνο για να αποφεύγονται τέτοιες συγκρούσεις.

**Ποια είναι η διαφορά μεταξύ PSR-0 και PSR-4;**  
Και τα δύο αντιστοιχίζουν ονόματα κλάσεων σε διαδρομές αρχείων. Στο PSR-4 το πρόθεμα του namespace δεν επαναλαμβάνεται στη διαδρομή του αρχείου, γεγονός που δίνει πιο επίπεδους καταλόγους. Το PSR-0 έχει χαρακτηριστεί ως παρωχημένο από το PHP-FIG, ενώ το PSR-4 είναι το συνιστώμενο πρότυπο.

**Λειτουργεί ακόμη η __autoload();**  
Όχι. Η __autoload() χαρακτηρίστηκε παρωχημένη με την PHP 7.2.0 και αφαιρέθηκε με την PHP 8.0.0. Σήμερα οι autoloaders καταχωρίζονται με την spl_autoload_register(), στην πράξη συνήθως μέσω του autoloader που δημιουργεί ο Composer.

**Πρέπει να δημιουργήσω ξανά τον autoloader μετά από τη δημιουργία μιας νέας κλάσης;**  
Με καθαρούς κανόνες PSR-4 όχι· σύμφωνα με την τεκμηρίωση του Composer αυτό είναι ακριβώς ένα πλεονέκτημα του PSR-4. Όποιος χρησιμοποιεί στην παραγωγή μια βελτιστοποιημένη λίστα κλάσεων, πρέπει να τη δημιουργεί εκ νέου σε κάθε παράδοση.

## Πηγές

- [PHP-FIG: Autoloader PSR-4](https://www.php-fig.org/psr/psr-4/)
- [Εγχειρίδιο PHP: Namespaces, επισκόπηση](https://www.php.net/manual/de/language.namespaces.rationale.php)
- [Εγχειρίδιο PHP: Autoloading](https://www.php.net/manual/de/language.oop5.autoload.php)
- [Composer: Το σχήμα του composer.json](https://getcomposer.org/doc/04-schema.md)
