Переход к официальным ресурсам:      Codeigniter4 / Документация / Github / Форум / CodeIgniter3
Привет! В настоящий момент я временно прекратил перевод документации по причине того, что она она содержит целый ряд неточностей, а также еще дорабатывается со стороны разработчиков. Если ты заинтересован в изучении фреймворка CodeIgniter 4, то приглашаю тебя на свой канал на YouTube (Перейти на канал), где я более подробно выкладываю занятия по данному фреймворку.


Службы

Небольшое отступление. Английский язык очень многовариантен и одно и тоже слово может иметь несколько значений. В официальном руководстве используется термин Services, который можно перевести как Сервисы или как Службы. Я выбрал второй вариант, но это вовсе не значит, что он верный. Решай сам, какой из них тебе ближе.

Итак, что это такое - Службы?

Все классы, реализуемые в Codeigniter, могут быть вызваны в качестве Службы. Это означает, что вместо того, чтобы жестко прописывать в коде имя вызываемого класса при создании объекта, ты можешь реализовать это через специальный класс Служб, в небольшом конфигурационном файле /app/Config/Services.php. Этот файл работает по типу "обёртки" (wrapper'a), который самостоятельно создает объекты от зарегистрированных классов. Некая "фабрика" объектов.

Например, в разных Контроллерах твоего приложения тебе необходимо создавать объекты от класса Timer. В этом случае, ты должен будешь жестко прописывать в коде примерно такой вызов:

$timer = new \CodeIgniter\Debug\Timer(); // Или какой-то свой класс

Этот код прекрасно отработает и ты получишь то, что хотел. А что будет, если ты создал десятки объектов от этого класса в разных Контроллерах своего приложения и потом решил вместо класса Timer попробовать использовать другой класс, например какой-то расширенный таймер с именем класса ExtendedTimer? Или, например, в одном месте кода ты хочешь создать объект от класса Timer по одному условию, а в другом месте объект от классаExtendedTimer по другому условию. Как ты будешь это реализовывать? Писать проверки в коде? Это плохое решение. Поэтому, при таком подходе, тебе придется искать все места в коде, где происходит создание объектов от класса Timer и вносить соответствующие корректировки. В таких ситуациях на помощь приходят Службы (Services).

Итак, Службы - это просто конфигурационный файл, который представлен в виде класса, в котором ты создаешь свои собственные (простые статические) методы, которые, в свою очередь, сами создают объекты от нужного тебе класса или классов. Помимо этого, содавая свой метод в классе Служб, ты можешь передавать в него свои параметры, которые и будут определять дальнейшее поведение при создании объекта. Посмотри на примере:

    class Services extends CoreServices
    {
	    public static function Timer($type = 'Timer', $getShared = true)
	    {
                if ($getShared = true)
                {
                    return static::getSharedInstance($type);
                }

            	return ($type === 'ExtendedTimer' ) 
                	? new \CodeIgniter\Debug\ExtendedTimer() 
                        : new \CodeIgniter\Debug\Timer();
    }

Вот и всё! Мы только что создали свой собственный метод, который будет максимально универсальным! Что мы здесь сделали? Мы создали новый метод с именем Timer, но ты можешь придумать свое собственное название. Далее, мы передаем в него 2 аргумента. Первый аргумент у нас будет определять от какого класса мы будем создавать объект, а второй аргумент нужен для того, чтобы определить, существует ли уже созданный объект. Если такой объект уже создан и существует, зачем еще раз создавать новый? Верно? Поэтому мы просто получаем уже созданный объект и возвращаем его в код для работы. Дальше, если объект не создан, то нам нужно определить, какой из Таймеров мы хотим использовать? Если в первом аргументе пришел параметр 'ExtendedTimer', тогда мы создаем новый объект от РасширенногоТаймера (от класса ExtendedTimer), в противном случае, создаем объект простого Таймера. Это действительно очень классно, удобно и просто. Теперь, чтобы начать использование непосредственно в коде, ты можешь обратиться к своему методу через Службу вот так:

// В каком-то месте Контроллера ты создаешь простой таймер, вызвав его без аргументов
$timer = \Config\Services::Timer();

// Тут еще какой-то код
... 

// А здесь тебе понадобился расширенный таймер, ну так и вызывай его
$timer = \Config\Services::Timer('ExtendedTimer');

Как я и говорил выше, таких участков кода может быть миллион. Теперь, если тебе необходимо задействовать другой класс Таймера, ты просто открываешь файл Служб app/Config/Services.php и в своем методе указываешь тот класс, от которого необходимо создавать объекты. Как только ты внёс изменения, всё приложение автоматически "перестроит" свою работу.

ВНИМАНИЕ! Разработчики настоятельно рекомендуют использовать Службы только исключительно в Контроллерах!

Пара удобных функций

Не всегда бывает удобным обращаться к службам через указание пространства имён, например так \Config\Services::. Для этого были введены 2 дополнительные функции: service() и single_service(), через которые можно осуществлять обращение к методам.

При первом вызове, функция service() будет создавать новый объект и возвращать его. При повторных обращениях она всегда будет возвращать ссылку на уже созданный объект. В качестве обязательного аргумента должно быть передано имя требуемой службы, которое должно быть в точности таким же, как в файле app/Config/Services.php. Если твоя служба требует передачи дополнительных параметров (например, как в примерах выше), то ты можешь передать эти параметры вторым аргументом. Пример вызова:

// Передаем дополнительные параметры
$timer = service('Timer', 'ExtendedTimer');

// Пример повторного вызова
$timer1 = service('Timer', 'ExtendedTimer');
$timer2 = service('Timer', 'ExtendedTimer');

// Уничтожаем объект и создаем заново
unset($timer1); 
$timer1 = service('Timer', 'ExtendedTimer');

echo ($timer1 === $timer2) ? 'Один и тот же объект' : 'Разные объекты';  // Результат: Один и тот же объект

Вторая функция single_service() полностью аналогична предыдущей, за исключением того, что она возвращает всегда НОВЫЙ объект. Смотри пример:

// Пример повторного вызова
$timer1 = service('Timer');
$timer2 = single_service('Timer');

echo ($timer1 === $timer2) ? 'Один и тот же объект' : 'Разные объекты';  // Результат: Разные объекты

Требования при создании Служб

Очень важным моментом, о котором всегда необходимо помнить, является то, что все классы, которые ты определяешь в Службе, должны всегда реализовывать один и тот же Интерфейс (условно). Если пренебречь этой рекомендацией, то очень просто можно "положить" работу всего приложения. Не понимаешь о чем речь? Смотри пример:

    // В Контроллере создаем объект
    $timer = service('Timer');
    
    // Вызываем его метод
    echo $timer->start();  // Казалось бы все хорошо

Спустя какое-то время ты решил использовать другой класс, например с именем ExtendedTimer, который очень похож на Timer, но, к сожалению, в нём метод start() не отсутствует, но называется по другому, например startTimer(). Несложно догадаться, что в примере выше возникнет ошибка! Поэтому, еще раз напоминаю, что для Служб очень важно соблюдать требования: "Используемые классы должны реализовывать один и тот же Интерфейс".

Если в файле Служб будет реализовано несколько методов с одинаковыми именами, тогда будет возвращен первый найденный метод!


Комментарии к разделу:

Пока ещё никто не оставил своего комментария. Оставить свой!

Добавить комментарий к статье:


Ваше имя:
Ваша почта:

  Закрыть