Поиск…


Синтаксис

  • требовать
  • spl_autoload_require

замечания

Автозагрузка, как часть рамочной стратегии, уменьшает количество кода шаблона, который вы должны написать.

Определение встроенного класса, не требуется загрузка

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

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

PHP знает, что такое Animal перед выполнением new Animal , потому что PHP читает исходные файлы сверху вниз. Но что, если мы хотим создавать новые Животные во многих местах, а не только в исходном файле, где он определен? Для этого нам нужно загрузить определение класса.

Ручная загрузка класса с требованием

// 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');

Здесь у нас есть три файла. Один файл («Animal.php») определяет класс. Этот файл не имеет побочных эффектов, кроме определения класса и аккуратно хранит все знания о «животном» в одном месте. Это легко контролируется версией. Это легко использовать повторно.

Два файла потребляют файл «Animal.php» вручную, require файла. Опять же, PHP читает исходные файлы сверху вниз, поэтому запрос выполняется и находит файл «Animal.php» и делает определение класса Animal доступным до вызова new Animal .

Теперь представьте, что у нас были десятки или сотни случаев, когда мы хотели выполнить new Animal . Для этого потребуется (каламбур) много, многие require утверждений, которые очень утомительны для кода.

Автозагрузка заменяет загрузку класса ручного класса

// 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');

Сравните это с другими примерами. Обратите внимание, что require "Animal.php" require "autoload.php" . Мы все еще включаем внешний файл во время выполнения, но вместо того, чтобы включать определение определенного класса, мы включаем логику, которая может включать любой класс. Это уровень косвенности, который облегчает наше развитие. Вместо того, чтобы писать каждый из них require для каждого класса, который нам нужен, мы пишем одно require для всех классов. Мы можем заменить N require на 1 require .

Магия происходит с spl_autoload_register . Эта функция PHP принимает замыкание и добавляет замыкание в очередь замыканий. Когда PHP встречает класс, для которого он не имеет определения, PHP передает имя класса каждому закрытию в очереди. Если класс существует после вызова замыкания, PHP возвращается к своей предыдущей работе. Если класс не может существовать после попытки всей очереди, PHP вылетает с «классом». «Не найден».

Автозагрузка как часть рамочного решения

// 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');

Благодаря нашему универсальному автозагрузчику у нас есть доступ к любому классу, который следует за нашим соглашением об именах автозагрузчиков. В этом примере наше соглашение прост: требуемый класс должен иметь файл в том же каталоге, что и для класса, и заканчивается на «.php». Обратите внимание, что имя класса точно совпадает с именем файла.

Без автозагрузки нам пришлось бы вручную require базовые классы. Если бы мы построили целый зоопарк животных, у нас было бы тысячи заявлений о необходимости, которые можно было бы с легкостью заменить одним автозагрузчиком.

В конечном счете, автозагрузка PHP - это механизм, который поможет вам писать меньше механического кода, чтобы вы могли сосредоточиться на решении бизнес-задач. Все, что вам нужно сделать, это определить стратегию, сопоставляющую имя класса с именем файла . Вы можете запустить свою собственную стратегию автозагрузки, как это делается здесь. Или вы можете использовать любой из стандартных, которые приняли сообщество PHP: PSR-0 или PSR-4 . Или вы можете использовать композитор для общего определения и управления этими зависимостями.

Автозагрузка с композитором

Composer создает файл vendor/autoload.php .

Вы можете просто включить этот файл, и вы получите автозагрузку бесплатно.

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

Это делает работу с сторонними зависимостями очень простой.


Вы также можете добавить свой собственный код в автозагрузчик, добавив раздел автозагрузки к вашему composer.json .

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

В этом разделе вы определяете сопоставления автозагрузки. В этом примере это сопоставление PSR-4 пространства имен в каталоге: каталог /src находится в корневой папке ваших проектов на том же уровне, что и каталог /vendor . Примером имени файла будет src/Foo.php содержащий YourApplicationNamespace\Foo .

Важно: после добавления новых записей в раздел автозагрузки вам необходимо повторно запустить команду dump-autoload для повторного создания и обновления файла vendor/autoload.php с новой информацией.

В дополнение к автозагрузке PSR-4 , Composer также поддерживает автозагрузку PSR-0 , classmap и files . Для получения дополнительной информации см. Ссылку на автозагрузку .


Когда вы /vendor/autoload.php файл /vendor/autoload.php он вернет экземпляр автозагрузчика композитора. Вы можете сохранить возвращаемое значение входящего вызова в переменной и добавить больше пространств имен. Это может быть полезно, например, для автозагрузки классов в тестовом наборе.

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


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow