Zoeken…


Syntaxis

  • vereisen
  • spl_autoload_require

Opmerkingen

Autoloading, als onderdeel van een raamwerkstrategie, vermindert de hoeveelheid boilerplate-code die u moet schrijven.

Inline klassedefinitie, laden niet nodig

// zoo.php
class Animal {
    public function eats($food) {
        echo "Yum, $food!";
    }
}

$animal = new Animal();
$animal->eats('meat');

PHP weet wat Animal is voordat het new Animal uitvoert, omdat PHP bronbestanden van boven naar beneden leest. Maar wat als we op veel plaatsen nieuwe dieren wilden maken, niet alleen in het bronbestand waar het is gedefinieerd? Om dat te doen, moeten we de definitie van de klasse te laden.

Handmatig laden van klassen met vereist

// Animal.php
class Animal {
    public function eats($food) {
         echo "Yum, $food!";
    }
}

// zoo.php
require 'Animal.php';
$animal = new Animal;
$animal->eats('slop');

// aquarium.php
require 'Animal.php';
$animal = new Animal;
$animal->eats('shrimp');

Hier hebben we drie bestanden. Eén bestand ("Animal.php") definieert de klasse. Dit bestand heeft geen bijwerkingen naast het definiëren van de klasse en houdt alle kennis over een "dier" netjes bij elkaar. Het is gemakkelijk versiebeheer. Het wordt gemakkelijk hergebruikt.

Twee bestanden verbruiken het "Animal.php" -bestand door het bestand handmatig te require . Nogmaals, PHP leest bronbestanden van boven naar beneden, dus de vereiste gaat en vindt het "Animal.php" -bestand en maakt de definitie van de klasse Animal beschikbaar voordat new Animal aangeroepen.

Stel je nu voor dat we tientallen of honderden gevallen hadden waarin we een new Animal wilden spelen. Dat zou (met de woordspeling bedoelde) veel require , vele uitspraken require die erg vervelend zijn voor code.

Autoloading vervangt het handmatig laden van klassendefinities

// autoload.php
spl_autoload_register(function ($class) {
    require_once "$class.php";
});

// Animal.php
class Animal {
    public function eats($food) {
         echo "Yum, $food!";
    }
}

// zoo.php
require 'autoload.php';
$animal = new Animal;
$animal->eats('slop');

// aquarium.php
require 'autoload.php';
$animal = new Animal;
$animal->eats('shrimp');

Vergelijk dit met de andere voorbeelden. Merk op require "Animal.php" is vervangen door require "autoload.php" . We nemen tijdens de uitvoering nog steeds een extern bestand op, maar in plaats van een specifieke klassedefinitie, nemen we logica op die elke klasse kan bevatten. Het is een niveau van indirection dat onze ontwikkeling vergemakkelijkt. In plaats van een require te schrijven voor elke klas die we nodig hebben, schrijven we een require voor alle klassen. We kunnen N require vervangen door 1 require .

De magie gebeurt met spl_autoload_register . Deze PHP-functie neemt een afsluiting en voegt de afsluiting toe aan een wachtrij met afsluitingen. Wanneer PHP een klasse tegenkomt waarvoor geen definitie bestaat, geeft PHP de klassenaam aan elke afsluiting in de wachtrij. Als de klasse bestaat nadat een afsluiting is opgeroepen, keert PHP terug naar zijn vorige activiteiten. Als de klasse niet bestaat nadat je de hele wachtrij hebt geprobeerd, crasht PHP met "Class 'Whatever' not found."

Autoloading als onderdeel van een raamwerkoplossing

// autoload.php
spl_autoload_register(function ($class) {
    require_once "$class.php";
});

// Animal.php
class Animal {
    public function eats($food) {
         echo "Yum, $food!";
    }
}

// Ruminant.php
class Ruminant extends Animal {
    public function eats($food) {
        if ('grass' === $food) {
            parent::eats($food);
        } else {
            echo "Yuck, $food!";
        }
    }
}

// Cow.php
class Cow extends Ruminant {
}

// pasture.php
require 'autoload.php';
$animal = new Cow;
$animal->eats('grass');

Dankzij onze generieke autoloader hebben we toegang tot elke klasse die voldoet aan onze naamgevingsconventie voor autoloader. In dit voorbeeld is onze conventie eenvoudig: de gewenste klasse moet een bestand hebben in dezelfde map met de naam van de klasse en eindigend op ".php". Merk op dat de klassenaam exact overeenkomt met de bestandsnaam.

Zonder autoloading zouden we handmatig basisklassen require hebben. Als we een hele dierentuin met dieren zouden bouwen, zouden er duizenden verklaringen nodig zijn die gemakkelijker kunnen worden vervangen door een enkele autoloader.

Uiteindelijk is PHP-autoloading een mechanisme om u te helpen minder mechanische code te schrijven, zodat u zich kunt concentreren op het oplossen van bedrijfsproblemen. Het enige dat u hoeft te doen, is een strategie definiëren die de klassenaam toewijst aan de bestandsnaam . U kunt uw eigen strategie voor automatisch laden uitvoeren, zoals hier wordt gedaan. Of u kunt elk van de standaardprogramma's gebruiken die de PHP-community heeft gebruikt: PSR-0 of PSR-4 . Of u kunt componist gebruiken om deze afhankelijkheden algemeen te definiëren en te beheren.

Autoloading met Composer

Composer genereert een vendor/autoload.php bestand.

U kunt dit bestand gewoon opnemen en u krijgt gratis autoloading.

require __DIR__ . '/vendor/autoload.php';

Dit maakt het werken met afhankelijkheden van derden zeer eenvoudig.


Je kunt ook je eigen code toevoegen aan de Autoloader door een autoload-sectie toe te voegen aan je composer.json .

{
    "autoload": {
        "psr-4": {"YourApplicationNamespace\\": "src/"}
    }
}

In deze sectie definieert u de autoload-toewijzingen. In dit voorbeeld is het een PSR-4- toewijzing van een naamruimte aan een map: de map /src bevindt zich in de hoofdmap van uw project, op hetzelfde niveau als de map /vendor . Een voorbeeld van een bestandsnaam is src/Foo.php met de klasse YourApplicationNamespace\Foo .

Belangrijk: na het toevoegen van nieuwe items aan de sectie autoload, moet u de opdracht dump-autoload opnieuw uitvoeren om het bestand vendor/autoload.php opnieuw te genereren en bij te werken met de nieuwe informatie.

Naast PSR-4 autoloading, ondersteunt Composer ook PSR-0 , classmap en autoloading van files . Zie de autoload-referentie voor meer informatie.


Wanneer u het bestand /vendor/autoload.php , retourneert dit een exemplaar van de Composer Autoloader. U kunt de retourwaarde van de include-aanroep opslaan in een variabele en meer naamruimten toevoegen. Dit kan bijvoorbeeld handig zijn voor het automatisch laden van klassen in een testpakket.

$loader = require __DIR__ . '/vendor/autoload.php';
$loader->add('Application\\Test\\', __DIR__);


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow