FFCMS Wiki

Официальная документация разработчика и администратора

Инструменты пользователя

Инструменты сайта


core:mvc:controller

Общее представление

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

Каркас контроллера

В FFCMS контроллеры должны быть расположены в директории приложений: /Apps/Controller/ в соответствующей директории рабочего окружения (для основного интерфейса - Front, полный путь - /Apps/Controller/Front/). Контроллеры должны наследовать основной класс-родитель: Ffcms\Core\Arch\Controller или более расширенные его реализации(к примеру, Extend\Core\Arch\AdminController). Стандарт именования файлов должен соответствовать логике PSR-0 автозагрузки.

Наследование реализации

Как уже говорилось выше, контроллеры обязаны наследовать базовую реализацию логики контроллеров в среде FFCMS. При конструировании приложения необходимо использовать следующие наследования для интерфейсов:

Название контроллера

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

К примеру, создадим контроллер с именем Demo, который будет вызываться для обработки запросов /demo/* для рабочего окружения Front:

namespace Apps\Controller\Front;
 
use Extend\Core\Arch\FrontAppController as Controller;
 
class Demo extends Controller 
{
// empty body
}

Примеры обработки URL и обращения к контроллерам:

  • site/mypath/ ⇒ Apps\Controller\Front\Mypath; (имя класса - Mypath)
  • site/admin/mypath ⇒ Apps\Controller\Admin\Mypath;
  • site/SomeStuPpiDCaSe ⇒ Apps\Controller\Front\Somestuppidcase;

Действия

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

Действия определяются в URI запроса пользователя к сайту, так же как и имя вызываемого контроллера. К примеру, запрос вида site/demo/hello приведет к инициации действия actionHello() контроллера Demo. Пример реализации такого контроллера и действия приведен ниже:

namespace Apps\Controller\Front;
 
use Extend\Core\Arch\FrontAppController as Controller;
 
class Demo extends Controller 
{
    public function actionHello()
    {
        // alternative: $this->response = "Hello, world";
        return "Hello, World";
    }
}

Каждое действие должно возвращать «результат» обработки return «response», который будет в дальнейшем отображен в позиции $body основного каркаса (по умолчанию - Apps/Views/Front[или др]/layout/main.php. Аналогично, результат обработки может быть назначен в переменную $this→response = «response» без точки возврата.

Действия контроллеров могут принимать до 2 вспомогательных аргументов, которые могут быть указаны в URI запроса. К примеру, запрос вида site.domain/demo/hello/ivan/ivanov может быть обработан при помощи класса Demo, действия actionHello с 2мя аргументами - $id и $add:

namespace Apps\Controller\Front;
 
use Extend\Core\Arch\FrontAppController as Controller;
use Ffcms\Core\App;
 
class Demo extends Controller 
{
    // bad practice inside! This must be done in View's!
    public function actionHello($name, $familia)
    {
        $name = App::$Security->strip_tags($name);
        $familia = App::$Security->strip_tags($familia);
 
        return 'Hello <b>' . $name . ' ' . $familia . '</b>';
    }
}

* Стоит отметить, что в данной демонстрации применены далеко не лучшие практики - в контроллерах нет места для обработки результата вывода, это должны делать представления! Этот код приведен лишь для начального уровня изучения FFCMS.

Специфические взаимодействия

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

Вызов перед выполнением

Существует стандартный метод контроллеров, позволяющий выполнить некоторые действия до выполнения основного действия(целевого):

namespace Apps\Controller\Front;
 
use Extend\Core\Arch\FrontAppController as Controller;
use Ffcms\Core\App;
use Ffcms\Core\Exceptions\ForbiddenException;
 
 
class Demo extends Controller 
{
    public function before()
    {
        // some actions
        if (!App::$User->isAuth()) {
            throw new ForbiddenException();
        }
    }
}

Стандартное действие

В случае, если в URI запроса не указано действие, к примеру site.domain/demo/ будет вызвано стандартное действие для данного контроллера actionIndex:

namespace Apps\Controller\Front;
 
use Extend\Core\Arch\FrontAppController as Controller;
 
class Demo extends Controller 
{
    public function actionIndex()
    {
         return 'Hello, i\'m index!';
    }
}

Исключения

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

namespace Apps\Controller\Front;
 
use Extend\Core\Arch\FrontAppController as Controller;
use Ffcms\Core\App;
use Ffcms\Core\Exceptions\ForbiddenException;
 
class Demo extends Controller 
{
    public function actionIndex()
    {
         if (!App::$User->isAuth()) {
             throw new ForbiddenException('You must be authorized user!');
         }
         return 'Hello, i\'m index!';
    }
}

В данном случае, если пользователь не авторизован будет выброшена ошибка типа Forbidden и пользователь получит уведомление с текстом You must be authorized user!.

Сквозное выполнение - загрузчик (boot)

Разрабатывая полноценные приложения для ffcms вам может потребоваться «сквозной» инициируемый метод, для выполнения тех или иных действий вашего приложения вне зависимости от того обрабатывается ли контроллер вашего приложения в текущей сессии пользователя. Во всех контроллерах в ffcms, подверженных правилам автозагрузки psr-0, psr-4 и унаследованных от Ffcms\Core\Arch\Controller или его потомков может быть объявлен метод автоматической загрузки static boot(), который будет выполнятся при каждой инициации сессии в текущем интерфейсе.

Иными словами, boot - это классическая реализация «внедрения» в загрузчик окружения. Объясняя данный механизм простыми словами, на стадии загрузки ядра ffcms, до стадии инициации конкретного контроллера будут вызваны ВСЕ статические статический методы boot() во всех контроллерах текущего интерфейса (front, admin, api, и т.д.).

Как пример реализации рассмотрим метод boot() в контроллере Statistic интерфейса Front, который отвечает за сбор информации об ip-адресах всех пользователей сайта при каждой инициации сессии пользователем (а не только в рамках приложения Statistic):

namespace Apps\Controller\Front;
 
use Ffcms\Core\Arch\Controller;
use Ffcms\Core\App;
use Ffcms\Core\Helper\FileSystem\File;
 
class Statistic extends Controller
{
    // hook bootable procedure
    public static function boot()
    {
        $ip = App::$Request->getClientIp();
        File::write('/log.txt', $ip);
    }
}

Таким образом, вызов каллбэка Statistic::boot() будет осуществляться каждый раз, когда инициируется любое выполнение приложения в интерфейсе Front.

Важно помнить, что не стоит сильно перегружать методы boot сложными и трудоемкими процедурами - этот метод является сквозным загрузчиком, и каждая реализация в нем будет замедлять генерацию html-кода для пользователя.

Лучшие концепции

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

Для контроллеров применимы следующие правила:

  • могут иметь доступ к данным запроса;
  • могут вызывать методы моделей и других компонентов системы с(или без) данными запроса
  • могут использовать представления для формирования ответа
  • не должны заниматься обработкой данных, это должно происходить в моделях
  • должны избегать использования HTML или другой разметки, лучше это делать в представлениях
core/mvc/controller.txt · Последние изменения: 2017/01/19 06:21 (внешнее изменение)