RobotLoader: autoloading κλάσεων
Το RobotLoader είναι ένα εργαλείο που σας εξασφαλίζει την άνεση της αυτόματης φόρτωσης κλάσεων για ολόκληρη την εφαρμογή σας, συμπεριλαμβανομένων των βιβλιοθηκών τρίτων.
- θα απαλλαγούμε από όλα τα
require
- θα φορτώνονται μόνο τα απαραίτητα scripts
- δεν απαιτεί αυστηρές συμβάσεις ονομασίας καταλόγων ή αρχείων
- εξαιρετικά γρήγορο
- καμία χειροκίνητη ενημέρωση της cache, όλα γίνονται αυτόματα
- ώριμη, σταθερή και ευρέως χρησιμοποιούμενη βιβλιοθήκη
Μπορούμε λοιπόν να ξεχάσουμε αυτά τα γνωστά μπλοκ κώδικα:
require_once 'Utils/Page.php';
require_once 'Utils/Style.php';
require_once 'Utils/Paginator.php';
// ...
Εγκατάσταση
Μπορείτε να κατεβάσετε το RobotLoader ως ένα αυτόνομο αρχείο
RobotLoader.php
, το οποίο εισάγετε με require
στο script σας και
αμέσως έχετε διαθέσιμο άνετο autoloading για ολόκληρη την εφαρμογή.
require '/path/to/RobotLoader.php';
$loader = new Nette\Loaders\RobotLoader;
// ...
Αν χτίζετε μια εφαρμογή που χρησιμοποιεί Composer, μπορείτε να το εγκαταστήσετε μέσω αυτού:
composer require nette/robot-loader
Χρήση
Παρόμοια με τον τρόπο που το ρομπότ της Google διασχίζει και ευρετηριάζει ιστοσελίδες, έτσι και το RobotLoader διασχίζει όλα τα PHP scripts και καταγράφει ποιες κλάσεις, interfaces, traits και enums βρήκε σε αυτά. Στη συνέχεια, αποθηκεύει τα αποτελέσματα της έρευνας στην cache και τα χρησιμοποιεί στο επόμενο request. Αρκεί λοιπόν να καθορίσετε ποιους καταλόγους πρέπει να διασχίσει και πού να αποθηκεύσει την cache:
$loader = new Nette\Loaders\RobotLoader;
// κατάλογοι που θα ευρετηριάσει ο RobotLoader (συμπεριλαμβανομένων των υποκαταλόγων)
$loader->addDirectory(__DIR__ . '/app');
$loader->addDirectory(__DIR__ . '/libs');
// ορίζουμε την αποθήκευση στην cache στον κατάλογο 'temp'
$loader->setTempDirectory(__DIR__ . '/temp');
$loader->register(); // εκκινούμε τον RobotLoader
Και αυτό είναι όλο, από εδώ και στο εξής δεν χρειάζεται να
χρησιμοποιούμε require
. Υπέροχα!
Αν το RobotLoader συναντήσει ένα διπλότυπο όνομα κλάσης κατά την ευρετηρίαση, ρίχνει μια εξαίρεση και σας ενημερώνει γι' αυτό. Το RobotLoader ενημερώνει επίσης αυτόματα την cache όταν πρέπει να φορτώσει μια κλάση που δεν γνωρίζει. Συνιστούμε να απενεργοποιήσετε αυτή τη λειτουργία στους διακομιστές παραγωγής, βλ. Cachování.
Αν θέλετε το RobotLoader να παραλείψει κάποιους καταλόγους,
χρησιμοποιήστε το $loader->excludeDirectory('temp')
(μπορεί να κληθεί
πολλαπλές φορές ή να περάσετε περισσότερους καταλόγους).
Από προεπιλογή, το RobotLoader αναφέρει σφάλματα στα αρχεία PHP ρίχνοντας
την εξαίρεση ParseError
. Αυτό μπορεί να κατασταλεί χρησιμοποιώντας
το $loader->reportParseErrors(false)
.
Εφαρμογή Nette
Μέσα σε μια εφαρμογή Nette, όπου χρησιμοποιείται το αντικείμενο
$configurator
στο αρχείο εκκίνησης Bootstrap.php
, η σύνταξη μπορεί να
απλοποιηθεί:
$configurator = new Nette\Bootstrap\Configurator;
// ...
$configurator->setTempDirectory(__DIR__ . '/../temp');
$configurator->createRobotLoader()
->addDirectory(__DIR__)
->addDirectory(__DIR__ . '/../libs')
->register();
Αναλυτής αρχείων PHP
Το RobotLoader μπορεί επίσης να χρησιμοποιηθεί καθαρά για την αναζήτηση κλάσεων, interfaces, traits και enums σε αρχεία PHP χωρίς τη χρήση της λειτουργίας autoloading:
$loader = new Nette\Loaders\RobotLoader;
$loader->addDirectory(__DIR__ . '/app');
// σαρώνει τους καταλόγους για κλάσεις / interfaces / traits / enums
$loader->rebuild();
// επιστρέφει έναν πίνακα ζευγών κλάση => όνομα αρχείου
$res = $loader->getIndexedClasses();
Ακόμη και σε αυτή τη χρήση, μπορείτε να χρησιμοποιήσετε την cache. Χάρη σε αυτό, κατά την επαναλαμβανόμενη σάρωση, τα αμετάβλητα αρχεία δεν θα αναλυθούν ξανά:
$loader = new Nette\Loaders\RobotLoader;
$loader->addDirectory(__DIR__ . '/app');
// ορίζουμε την αποθήκευση στην cache στον κατάλογο 'temp'
$loader->setTempDirectory(__DIR__ . '/temp');
// σαρώνει τους καταλόγους χρησιμοποιώντας την cache
$loader->refresh();
// επιστρέφει έναν πίνακα ζευγών κλάση => όνομα αρχείου
$res = $loader->getIndexedClasses();
Caching
Το RobotLoader είναι πολύ γρήγορο γιατί χρησιμοποιεί έξυπνα την cache.
Κατά την ανάπτυξη, πρακτικά δεν έχετε ιδέα ότι τρέχει στο παρασκήνιο. Ενημερώνει συνεχώς την cache, γιατί υπολογίζει ότι οι κλάσεις και τα αρχεία μπορούν να δημιουργηθούν, να εξαφανιστούν, να μετονομαστούν, κ.λπ. Και δεν σαρώνει επανειλημμένα αρχεία που δεν έχουν αλλάξει.
Κατά την ανάπτυξη σε διακομιστή παραγωγής, αντίθετα, συνιστούμε να
απενεργοποιήσετε την ενημέρωση της cache χρησιμοποιώντας το
$loader->setAutoRefresh(false)
(στην Εφαρμογή Nette αυτό γίνεται αυτόματα),
επειδή τα αρχεία δεν αλλάζουν. Ταυτόχρονα, είναι απαραίτητο να
διαγράψετε την cache κατά το ανέβασμα μιας νέας έκδοσης στο hosting.
Η αρχική σάρωση των αρχείων, όταν η cache δεν υπάρχει ακόμα, μπορεί φυσικά να διαρκέσει λίγο για μεγαλύτερες εφαρμογές. Το RobotLoader έχει ενσωματωμένη πρόληψη κατά του cache stampede. Πρόκειται για μια κατάσταση όπου ένας μεγάλος αριθμός ταυτόχρονων requests συναντιούνται στον διακομιστή παραγωγής, τα οποία εκκινούν το RobotLoader, και επειδή η cache δεν υπάρχει ακόμα, όλα θα άρχιζαν να σαρώνουν αρχεία. Κάτι που θα επιβάρυνε δυσανάλογα τον διακομιστή. Ευτυχώς, το RobotLoader λειτουργεί έτσι ώστε, σε περίπτωση πολλαπλών ταυτόχρονων requests, μόνο το πρώτο νήμα ευρετηριάζει τα αρχεία, δημιουργεί την cache, τα υπόλοιπα περιμένουν και στη συνέχεια χρησιμοποιούν την cache.
PSR-4
Σήμερα, μπορείτε να χρησιμοποιήσετε το Composer για
autoloading τηρώντας το PSR-4. Με απλά λόγια, πρόκειται για ένα σύστημα όπου
τα namespaces και τα ονόματα των κλάσεων αντιστοιχούν στη δομή των
καταλόγων και στα ονόματα των αρχείων, δηλαδή π.χ. το
App\Core\RouterFactory
θα βρίσκεται στο αρχείο
/path/to/App/Core/RouterFactory.php
.
Το RobotLoader δεν είναι συνδεδεμένο με καμία σταθερή δομή, γι' αυτό ταιριάζει σε καταστάσεις όπου δεν σας ταιριάζει απόλυτα να έχετε την ίδια σχεδιασμένη δομή καταλόγων με τα namespaces στην PHP, ή όταν αναπτύσσετε μια εφαρμογή που ιστορικά δεν χρησιμοποιεί τέτοιες συμβάσεις. Είναι επίσης δυνατό να χρησιμοποιείτε και τους δύο loaders μαζί.