Приложение

Application container

Класс-контейнер обратного управления IoC (Inversion of Control) - мощное средство для управления зависимостями классов. Внедрение зависимостей - это способ исключения вшитых (hardcoded) взаимосвязей классов. Вместо этого зависимости определяются во время выполнения, что даёт бОльшую гибкость благодаря тому, что они могут быть легко изменены.

Помещение в контейнер

Есть два способа, которыми IoC-контейнер разрешает зависимости: через функцию-замыкание и через автоматическое определение.

Для начала давайте посмотрим замыкания. Поместим нечто в контейнер и назовём это foo:

App::bind('foo', function($app) {
    return new FooBar;
});

Извлечение из контейнера

$value = App::make('foo');

При вызове метода App::make вызывается соответствующая функция-замыкание и возвращается результат её вызова.

Помещение shared ("разделяемого") типа в контейнер

Иногда вам может понадобиться поместить в контейнер нечто, что должно быть создано только один раз, а все последующие вызовы должны возвратить тот же объект.

App::singleton('foo', function() {
    return new FooBar;
});

Помещение готового экземпляра в контейнер

Вы также можете поместить уже созданный экземпляр объекта в контейнер, используя метод instance:

$foo = new Foo;

App::instance('foo', $foo);

Связывание интерфейса и реализации

В некоторых случаях класс может принимать экземпляр интерфейса, а не сам объект. В этом случае нужно использовать метод App::bind для извещения контейнера о том, какая именно зависимость должна быть внедрена.

App::bind('UserRepositoryInterface', 'DbUserRepository');

Теперь посмотрим на следующий контроллер:

$users = App::make('UserRepositoryInterface');

Благодаря тому, что мы связали UserRepositoryInterface с "настоящим" классом, DbUserRepository, он будет автоматически встроен в контроллер при его создании.

Где регистрировать связывания?

Вышеописанные биндинги (связывание) в IoC, как и обработчики событий, обычно попадают в категорию «код начальной загрузки». Другими словами, они подготавливают ваше приложение для обработки запросов и должны быть выполнены перед вызовом маршрутизации или контроллера. Поэтому наиболее подходящее для них место - метод boot в файле регистрации плагина. Также Вы можете использовать файл init.php, который должен находится в корне папки плагина, для того, чтобы описать логику регистрации IoC.

Service providers

Сервис-провайдеры (service providers, "поставщики услуг") - отличный способ группировки схожих регистраций в IoC в одном месте. Их можно рассматривать как начальный запуск компонентов вашего приложения. Внутри поставщика услуг вы можете зарегистрировать драйвер авторизации, классы-хранилища вашего приложения или даже собственную консольную Artisan-команду.

Фактически, файлы регистрации плагина наследуют сервис-провайдеры, а большинство основных компонентов включают их в себя. Все зарегистрированные сервис-провайдеры для вашего приложения перечислены в массиве providers в файле с настройками config/app.php.

Создание сервис-провайдера

Для создания нового сервис-провайдера просто наследуйте класс October\Rain\Support\ServiceProvider и определите метод register:

use October\Rain\Support\ServiceProvider;

class FooServiceProvider extends ServiceProvider
{

    public function register()
    {
        $this->app->bind('foo', function() {
            return new Foo;
        });
    }

}

Заметьте, что внутри метода register IoC-контейнер приложения доступен в свойстве $this->app. Как только вы создали провайдера и готовы зарегистрировать его в своём приложении, просто добавьте его в массив providers в файле с настройками приложения.

Регистрация сервис-провайдеров во время выполнения

Вы можете зарегистрировать сервис-провайдеры "на лету", используя метод App::register:

App::register('FooServiceProvider');

Application events

События запроса

Вы можете зарегистрировать специальные события до того, как запрос будет отправлен при помощи методов before и after:

App::before(function ($request) {
    // Code to execute before the request is routed
});

App::after(function ($request) {
    // Code to execute after the request is routed
});

События контейнера

IoC-контейнер запускает событие каждый раз при извлечении объекта. Вы можете отслеживать его с помощью метода resolving:

App::resolving(function ($object, $app) {
    // Called when container resolves object of any type...
});

App::resolving('foo', function ($fooBar, $app) {
    // Called when container resolves objects using hint "foo"...
});

App::resolving('Acme\Blog\Classes\FooBar', function ($fooBar, $app) {
    // Called when container resolves objects of type "FooBar"...
});

Созданный объект передаётся в функцию-замыкание в виде параметра.

Application helpers

Получение текущей среды приложения

Вы можете использовать метод environment для получения текущей среды:

// production
App::environment();

Определение контекста выполнения

Используйте метод runningInBackend, чтобы узнать: выполняется ли текущий запрос в административной части сайта:

App::runningInBackend();

Используйте метод runningInConsole, чтобы проверить: выполняется ли текущий запрос в командной строке:

App::runningInConsole();