Сервис контейнер
На примере небольшого тестового скрипта, сделаем логику и создадим простой валидатор даты. Реализуем скрипт проверки даты на корректность, который можно использовать абсолютно везде, как в контроллерах, так и в шаблонах.
В файловой структуре фреймворка, в каталоге app
создадим папку Services
и добавим в нее файл DateCheck.php
со следующим содержимым:
app/Services/DateCheck.php<?php
namespace App\Services;
class DateCheck {
public function isValid($strDate, $strFormat = "d/m/Y", $str_timezone = FALSE) {
$date = \DateTime::createFromFormat($strFormat,$strDate);
if($date && (int)$date->format('Y') < 1900) {
return false;
}
return $date && \DateTime::getLastErrors()["warning_count"] == 0 && \DateTime::getLastErrors()["error_count"] == 0;
}
}
Валидатор, состоит всего лишь из одного метода, который в случае корректной даты возвращает true
. При этом дата и ее формат, передаются в качестве соответствующих аргументов. Далее используя стандартный класс PHP DateTime
, мы пытаемся создать объект указанного класса, используя переданную дату. Если ошибок нет – возвращаем true
.
Теперь давайте попытаемся использовать код написанного класса. Для этого в контроллере создадим объект данного класса и вызовем на исполнение метод isValid()
незабывая указать пространство имен use App\Services\DateCheck;
:
app/Http/Controllers/SiteController.phpuse App\Services\DateCheck;
$ext = new DateCheck();
dump($ext->isValid('25/01/2018'));
Данный код работает, но не совсем отвечает методике и технике работы с фреймворком Laravel. Для правил фремворка, указанный код должен быть преобразован к следующему виду:
app/Http/Controllers/SiteController.phpuse App\Services\DateCheck;
dump (DateCheck::isValid('25/01/2018'));
Указанная проблема в полной мере решается с использованием Сервис контейнер
, это мощное средство для управления зависимостями классов и внедрения зависимостей. Это своего рода контейнер, для хранения объектов. Причем каждый объект в контейнере, располагается под своим ключом, что гарантирует быстрое получение необходимых данных.
Реализация скрипта через сервис контейнер Service Container
Следующий элемент который нам понадобиться, это Service Provider
которых еще называют поставщики услуг. Указанный элемент, как правило связывает некий объект с сервис контейнером Service Container
, добавляет в одну из его ячеек необходимый объект.
Поставщик услуг (Service Provider)
Регистрацию поставщика услуг Service Provider в контейнере сервисов Service Container, можно разделить на две части:
- Создание файла
DateCheckServiceProvider.php
которое позволит зарегистрироваться в контейнере сервисов Service Container - Добавление нового провайдера в массив
providers
в файле конфигурацииconfig\app.php
Давайте создадим сервис провайдер и реализуем метод register()
, который изначально пустой:
php artisan make:provider DateCheckServiceProvider
app/Providers/DateCheckServiceProvider.php<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class DateCheckServiceProvider extends ServiceProvider {
public function register () {
$this->app->bind('dateCheck','App\Services\DateCheck');
}
}
При создании провайдера, обязательно необходимо наследовать класс Illuminate\Support\ServiceProvider
, а так же реализовать метод register
, в котором при помощи метода bind
добавляется в сервис контейнер Service Container, объект класса App\Services\DateCheck
в ячейку с ключом dateCheck
.
Исполняемый файл
В файловой структуре фреймворка, в каталоге app
создадим папку Services
и добавим в нее файл DateCheck.php
со следующим содержимым:
app/Services/DateCheck.php<?php
namespace App\Services;
class DateCheck {
public function isValid($strDate, $strFormat = "d/m/Y", $str_timezone = FALSE) {
$date = \DateTime::createFromFormat($strFormat,$strDate);
if($date && (int)$date->format('Y') < 1900) {
return false;
}
return $date && \DateTime::getLastErrors()["warning_count"] == 0 && \DateTime::getLastErrors()["error_count"] == 0;
}
}
Фасад (Facade)
Фасад Facade предоставляют легкий доступ к классам, зарегистрированным в сервис контейнере Service Container. В целом, можно обходиться и без них, внедряя зависимость в отдельные методы. Кроме того, чтобы получить объект сервиса, можно использовать хелпер app()
или глобальный объект App
. Фасады есть смысл создавать для часто используемых сервисов, чтобы упростить доступ к их методам:
app/Http/Controllers/SiteController.php<?php
namespace App\Http\Controllers;
use App\Models\Start;
use App\Services\DateCheck;
class SiteController extends Controller
{
public function index()
{
$saver = app(DateCheck::class);
$res = $saver->isValid('25/01/2018');
dump($res);
return view('skelet.index', ['product' => Start::index()[0]]);
}
}
В каталоге app
, создадим папку Facades
и добавим в нее файл DateService.php
:
app/Facades/DateService.php<?php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class DateService extends Facade {
protected static function getFacadeAccessor() {
return 'dateCheck';
}
}
При создании фасада обязательно следует наследовать Illuminate\Support\Facades\Facade
, а так же переопределять метод getFacadeAccessor()
, данный метод должен возвращать ключ в виде строки, к которому привязывается класс у поставщика услуг Service Provider. Ключ может быть абсолютно любой строкой, при работе с фасадом обращаться нужно будет не к ключу, а к алиасу указанному в файле config/app.php
в массиве aliases
.
Добавление провайдера
В конфигурационном фале config/app.php
добавляем созданный провайдер в массив providers
, для инициализации с загрузкой фреймворка, теперь во всем фремворке будет автоматом подгружаться класс файла DateCheckServiceProvider.php:
config/app.phpApp\Providers\DateCheckServiceProvider::class
Теперь мы можем обращаться к фасаду и наследоваться от него без добавления псевдонима:
app/Http/Controllers/SiteController.php<?php
namespace App\Http\Controllers;
use App\Models\Start;
use App\Facades\DateService;
class SiteController extends Controller
{
public function index()
{
dump(DateService::isValid('25/01/2018'));
return view('skelet.index', ['product' => Start::index()[0]]);
}
}
Добавление псевдонима
Добавляем альяс в конфигурационном фале config/app.php
в массив aliases
по которому и будем обращаться к фасаду:
config/app.php'DateService' => App\Facades\DateService::class
При работе с фасадом мы используем алиас DateService
, который существует в глобальной области видимости. Другими словами, доступ к алиасу возможен везде, внедрять зависимость не нужно, ведь фасады это как раз альтернатива внедрению зависимостей:
Http/Controllers/SiteController.php<?php
namespace App\Http\Controllers;
use App\Models\Start;
use DateService;
class SiteController extends Controller
{
public function index()
{
dump(DateService::isValid('25/01/2018'));
return view('skelet.index', ['product' => Start::index()[0]]);
}
}