Автозагрузка

Обзор

Автозагрузка — это концепция в PHP, где вы указываете директорию или директории для загрузки классов. Это гораздо полезнее, чем использование require или include для загрузки классов. Это также требование для использования пакетов Composer.

Понимание

По умолчанию любой класс Flight автозагружается автоматически благодаря composer. Однако, если вы хотите автозагружать свои собственные классы, вы можете использовать метод Flight::path() для указания директории, из которой будут загружаться классы.

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

Основное использование

Предположим, у нас есть дерево директорий, как в следующем примере:

# Пример пути
/home/user/project/my-flight-project/
├── app
│   ├── cache
│   ├── config
│   ├── controllers - содержит контроллеры для этого проекта
│   ├── translations
│   ├── UTILS - содержит классы только для этого приложения (все заглавные буквы специально для примера позже)
│   └── views
└── public
    └── css
    └── js
    └── index.php

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

Вы можете указать каждую директорию для загрузки следующим образом:


/**
 * public/index.php
 */

// Добавьте путь к автозагрузчику
Flight::path(__DIR__.'/../app/controllers/');
Flight::path(__DIR__.'/../app/utils/');

/**
 * app/controllers/MyController.php
 */

// пространство имен не требуется

// Все автозагружаемые классы рекомендуется называть в Pascal Case (каждое слово с заглавной буквы, без пробелов)
class MyController {

    public function index() {
        // сделайте что-то
    }
}

Пространства имен

Если у вас есть пространства имен, то их реализация становится очень простой. Вы должны использовать метод Flight::path() для указания корневой директории (не корневой директории документа или папки public/) вашего приложения.


/**
 * public/index.php
 */

// Добавьте путь к автозагрузчику
Flight::path(__DIR__.'/../');

Теперь вот как может выглядеть ваш контроллер. Посмотрите на пример ниже, но обратите внимание на комментарии для важной информации.

/**
 * app/controllers/MyController.php
 */

// пространства имен обязательны
// пространства имен такие же, как структура директорий
// пространства имен должны следовать тому же регистру, что и структура директорий
// пространства имен и директории не могут содержать подчеркивания (если не установлен Loader::setV2ClassLoading(false))
namespace app\controllers;

// Все автозагружаемые классы рекомендуется называть в Pascal Case (каждое слово с заглавной буквы, без пробелов)
// Начиная с 3.7.2, вы можете использовать Pascal_Snake_Case для имен классов, запустив Loader::setV2ClassLoading(false);
class MyController {

    public function index() {
        // сделайте что-то
    }
}

А если вы хотите автозагружать класс в директории utils, вы сделаете в основном то же самое:


/**
 * app/UTILS/ArrayHelperUtil.php
 */

// пространство имен должно соответствовать структуре директорий и регистру (обратите внимание, что директория UTILS в верхнем регистре
//     как в дереве файлов выше)
namespace app\UTILS;

class ArrayHelperUtil {

    public function changeArrayCase(array $array) {
        // сделайте что-то
    }
}

Подчеркивания в именах классов

Начиная с 3.7.2, вы можете использовать Pascal_Snake_Case для имен классов, запустив Loader::setV2ClassLoading(false);. Это позволит вам использовать подчеркивания в именах классов. Это не рекомендуется, но доступно для тех, кто в этом нуждается.

use flight\core\Loader;

/**
 * public/index.php
 */

// Добавьте путь к автозагрузчику
Flight::path(__DIR__.'/../app/controllers/');
Flight::path(__DIR__.'/../app/utils/');
Loader::setV2ClassLoading(false);

/**
 * app/controllers/My_Controller.php
 */

// пространство имен не требуется

class My_Controller {

    public function index() {
        // сделайте что-то
    }
}

См. также

  • Маршрутизация - Как сопоставлять маршруты с контроллерами и рендерить представления.
  • Зачем фреймворк? - Понимание преимуществ использования фреймворка вроде Flight.

Устранение неисправностей

  • Если вы не можете понять, почему ваши классы с пространствами имен не находятся, помните использовать Flight::path() к корневой директории в вашем проекте, а не к директории app/ или src/ или эквивалентной.

Класс не найден (автозагрузка не работает)

Для этого может быть несколько причин. Ниже приведены некоторые примеры, но обязательно проверьте также раздел автозагрузка.

Неправильное имя файла

Наиболее распространенная причина — имя класса не соответствует имени файла.

Если у вас есть класс с именем MyClass, то файл должен называться MyClass.php. Если у вас есть класс с именем MyClass, а файл называется myclass.php то автозагрузчик не сможет его найти.

Неправильное пространство имен

Если вы используете пространства имен, то пространство имен должно соответствовать структуре директорий.

// ...код...

// если ваш MyController находится в директории app/controllers и имеет пространство имен
// это не сработает.
Flight::route('/hello', 'MyController->hello');

// вам нужно выбрать один из этих вариантов
Flight::route('/hello', 'app\controllers\MyController->hello');
// или если у вас есть оператор use вверху

use app\controllers\MyController;

Flight::route('/hello', [ MyController::class, 'hello' ]);
// также может быть написано
Flight::route('/hello', MyController::class.'->hello');
// также...
Flight::route('/hello', [ 'app\controllers\MyController', 'hello' ]);

path() не определен

В скелетном приложении это определено внутри файла config.php, но чтобы ваши классы были найдены, вам нужно убедиться, что метод path() определен (вероятно, к корню вашей директории) до того, как вы попытаетесь его использовать.

// Добавьте путь к автозагрузчику
Flight::path(__DIR__.'/../');

Журнал изменений

  • v3.7.2 - Вы можете использовать Pascal_Snake_Case для имен классов, запустив Loader::setV2ClassLoading(false);
  • v2.0 - Добавлена функциональность автозагрузки.