Jestem pewien, że to wiesz, kiedy programując skrypty PHP, dzielimy kod na wiele plików i aby mieć dostępne wszystkie części, ładujemy je za pomocą serii wywołań include, require lub najlepiej require_once, co gwarantuje załadowanie tylko raz.
W kodzie wygląda to następująco:
require_once 'Router.php';require_once 'Strona.php';require_once 'Paginator.php';
Główną wadą tego podejścia jest to, że programista musi stale upewniać się, że wszystko jest zawsze załadowane. Jeśli jednak użytkownik dużo ładuje, niepotrzebnie traci wydajność i wielokrotnie trafia na dysk. Z rozwiązaniem podręcznikowym wiążą się więc same problemy.
Na szczęście w PHP istnieje natywne wsparcie dla tak zwanego Class Autoloading, czyli logiki w kodzie, która ładuje plik klasy tylko wtedy, gdy jest on po raz pierwszy potrzebny (zazwyczaj przy pierwszym utworzeniu instancji).
Prosta implementacja może wyglądać następująco:
spl_autoload_register(function (string $className): void {include 'src/' . $className . '.php';});$obj = new MyClass1();$obj2 = new MyClass2();
Podczas tworzenia instancji klasy MyClass1, funkcja spl_autoload_register odczytuje plik MyClass1.php z katalogu src. W tej implementacji przyjęto, że każda klasa znajduje się w osobnym pliku nazwanym według nazwy klasy lub interfejsu.
W rzeczywistych zastosowaniach może wystąpić wiele nieprzyjemnych sytuacji, które komplikują na przykład pracę w trybie autoload:
Nie musimy jednak w tym celu programować własnego rozwiązania, lecz możemy wykorzystać istniejące, raz zaprojektowane.
Jeśli używasz Composera, prawdopodobnie korzystasz również z jego natywnego autoloadingu. Dzieje się tak, ponieważ podczas instalacji dowolnego pakietu Composer automatycznie generuje mapę klas, która jest przeglądem klas i ich fizycznych lokalizacji.
Następnie na początku kodu (zwykle w index.php) wystarczy użyć:
require __DIR__ . '/vendor/autoload.php';
Jednak autoloading jest generowany tylko raz, gdy wywoływana jest komenda composer dump, więc konieczne jest regenerowanie autoloadingu za każdym razem, gdy aplikacja się zmienia.
Do lokalnego rozwoju bardzo lubię pakiet nette/robot-loader, który automatycznie przemierza strukturę katalogów i buforuje lokalizacje klas. Jeśli więc wczytujemy klasę, najpierw sprawdzana jest ona w pamięci podręcznej, a dopiero jeśli nie istnieje, następuje automatyczne przeindeksowanie projektu. W związku z tym programista nie musi w ogóle śledzić, gdzie znajduje się dany plik lub klasa, i po prostu programuje.
Instalacja za pomocą aplikacji Composer:
composer require nette/robot-loader
Podstawowe objaśnienia funkcji są opisane w samej dokumentacji:
Podobnie jak robot Google indeksuje strony internetowe, RobotLoader przeszukuje wszystkie skrypty PHP i notuje, jakie klasy, interfejsy i cechy w nich znalazł. Następnie buforuje wyniki swoich badań i wykorzystuje je w następnym żądaniu. Wystarczy więc określić, które katalogi mają być indeksowane i gdzie mają być buforowane.
Jest on wtedy niezwykle łatwy w użyciu:
$loader = new Nette\Loaders\RobotLoader;// dodaj katalogi, które RobotLoader ma indeksować$loader->addDirectory(__DIR__ . '/app');$loader->addDirectory(__DIR__ . '/libs');// ustaw buforowanie na dysku w katalogu 'temp'.$loader->setTempDirectory(__DIR__ . '/temp');$loader->register(); // uruchom RobotLoader
Ustawienie $loader->setAutoRefresh(true lub false) określa, czy RobotLoader powinien przeindeksować pliki, gdy napotka nową klasę. Ta funkcja powinna być wyłączona na serwerach produkcyjnych.
Teraz już nigdy więcej nie będziesz musiał zmagać się z automatycznym ładowaniem.
Podczas tworzenia prawdziwego projektu stosuję rozwiązanie łączone.
W praktyce wygląda to tak, że ładuję zainstalowane pakiety przez Composer autoload (który jest bardzo wydajny) i to rozwiązuje problem ładowania wszystkich klas w katalogu vendor.
Kod dla danego projektu jest następnie umieszczany w katalogu app, gdzie za pomocą RobotLoader automatycznie ładuję tylko kilka klas. Ważne jest, aby konkretna aplikacja była jak najmniejsza i w jak największym stopniu korzystała z gotowych pakietów - to bardzo ułatwia ponowne wykorzystanie.
Struktura projektu wygląda następująco:
/appBootstrap.php <-- konfigurace/modelUserForm.php <-- projektové třídyRegisterFactory.php.../vendor... <-- knihovny/wwwindex.php <-- inicializace
Czasami może się zdarzyć, że nie wszystkie pliki zostaną załadowane i pojawią się problemy.
Do debugowania zalecam użycie funkcji get_included_files().
Jan Barášek Více o autorovi
Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.
Rád vám pomůžu:
Články a novinky nejen ze světa PHP a programování. Nenechte si ujít jediný článek.
Články píše Jan Barášek © 2009-2025 | Kontakt | Mapa webu
Status | Aktualizováno: ... | pl