Использование контроллеров
Действия — это методы контроллера, обрабатывающие запросы. По умолчанию все публичные методы контроллера отображаются как действия и доступны по URL. Действия отвечают за интерпретацию запроса и создание ответа. Обычно ответы представляют собой отрисованный вид, но есть и другие способы создания ответов.
Например, при обращении к URL, такому как: http://localhost/blog/posts/show/2015/the-post-title Phalcon по умолчанию разобьёт каждый элемент, как показано ниже:
| Директория Phalcon | blog |
| Контроллер | posts |
| Действие | show |
| Параметр | 2015 |
| Параметр | the-post-title |
В данном случае за этот запрос отвечает PostsController. Нет специального места для размещения контроллеров в приложении; их можно загружать с помощью автозагрузчиков, поэтому вы можете организовать контроллеры как вам нужно.
Контроллеры должны иметь суффикс «Controller», а действия — суффикс «Action». Пример контроллера:
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
}
public function showAction($year, $postTitle)
{
}
}
Дополнительные параметры URI определяются как параметры действия, чтобы к ним можно было легко получить доступ, используя локальные переменные. Контроллер может необязательно расширять Phalcon\Mvc\Controller. Сделав это, контроллер может легко получить доступ к сервисам приложения.
Параметры без значения по умолчанию обрабатываются как обязательные. Установка необязательных значений для параметров выполняется как обычно в PHP:
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
}
public function showAction($year = 2015, $postTitle = "some default title")
{
}
}
Параметры присваиваются в том же порядке, в котором они были переданы в маршруте. Вы можете получить произвольный параметр по его имени следующим образом:
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
}
public function showAction()
{
$year = $this->dispatcher->getParam("year");
$postTitle = $this->dispatcher->getParam("postTitle");
}
}
Цикл диспетчеризации
Цикл диспетчеризации будет выполняться внутри диспетчера, пока не останется действий для выполнения. В предыдущем примере было выполнено только одно действие. Сейчас мы увидим, как метод forward() может обеспечить более сложный ход выполнения в цикле диспетчеризации, перенаправив выполнение в другой контроллер/действие.
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
}
public function showAction($year, $postTitle)
{
$this->flash->error(
"You don't have permission to access this area"
);
// Forward flow to another action
$this->dispatcher->forward(
[
"controller" => "users",
"action" => "signin",
]
);
}
}
Если пользователи не имеют разрешения на доступ к определённому действию, они будут перенаправлены на действие «signin» в контроллере Users.
use Phalcon\Mvc\Controller;
class UsersController extends Controller
{
public function indexAction()
{
}
public function signinAction()
{
}
}
В вашем приложении нет ограничений на количество «перенаправлений», пока они не приведут к циклическим ссылкам, в этом случае ваше приложение остановится. Если других действий для диспетчеризации нет, диспетчер автоматически вызовет слой представления MVC, управляемый Phalcon\Mvc\View.
Инициализация контроллеров
Phalcon\Mvc\Controller предлагает метод initialize(), который выполняется первым, до выполнения любого действия в контроллере. Использование метода __construct() не рекомендуется.
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public $settings;
public function initialize()
{
$this->settings = [
"mySetting" => "value",
];
}
public function saveAction()
{
if ($this->settings["mySetting"] === "value") {
// ...
}
}
}
Методinitialize()вызывается только в том случае, если событие «beforeExecuteRoute» выполнено успешно. Это предотвращает выполнение логики приложения в инициализаторе без авторизации.
Если вы хотите выполнить некоторую логику инициализации сразу после создания объекта контроллера, вы можете реализовать метод onConstruct():
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function onConstruct()
{
// ...
}
}
Обратите внимание, что методonConstruct()выполняется даже в том случае, если действие, которое должно быть выполнено, не существует в контроллере или пользователь не имеет к нему доступа (в соответствии с пользовательским управлением доступом, предоставленным разработчиком).
Вставка сервисов
Если контроллер расширяет Phalcon\Mvc\Controller, то он легко получает доступ к контейнеру сервисов в приложении. Например, если мы зарегистрировали сервис так:
use Phalcon\Di;
$di = new Di();
$di->set(
"storage",
function () {
return new Storage(
"/some/directory"
);
},
true
);
Затем мы можем получить доступ к этому сервису несколькими способами:
use Phalcon\Mvc\Controller;
class FilesController extends Controller
{
public function saveAction()
{
// Injecting the service by just accessing the property with the same name
$this->storage->save("/some/file");
// Accessing the service from the DI
$this->di->get("storage")->save("/some/file");
// Another way to access the service using the magic getter
$this->di->getStorage()->save("/some/file");
// Another way to access the service using the magic getter
$this->getDi()->getStorage()->save("/some/file");
// Using the array-syntax
$this->di["storage"]->save("/some/file");
}
}
Если вы используете Phalcon как полнофункциональный фреймворк, вы можете прочитать сервисы, предоставляемые по умолчанию в фреймворке.
Запрос и ответ
Предполагая, что фреймворк предоставляет набор предварительно зарегистрированных сервисов. Мы объясняем, как взаимодействовать с HTTP-средой. Сервис «request» содержит экземпляр Phalcon\Http\Request, а сервис «response» содержит Phalcon\Http\Response, представляющий то, что будет отправлено клиенту.
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
}
public function saveAction()
{
// Check if request has made with POST
if ($this->request->isPost()) {
// Access POST data
$customerName = $this->request->getPost("name");
$customerBorn = $this->request->getPost("born");
}
}
}
Объект ответа обычно не используется напрямую, но строится перед выполнением действия, иногда — например, в событии afterDispatch — полезно получить доступ к ответу напрямую:
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
}
public function notFoundAction()
{
// Send a HTTP 404 response header
$this->response->setStatusCode(404, "Not Found");
}
}
Узнайте больше об HTTP-среде в посвящённых статьях запрос и ответ.
Данные сессии
Сессии позволяют нам сохранять постоянные данные между запросами. Вы можете получить доступ к Phalcon\Session\Bag из любого контроллера, чтобы упаковать данные, которые нужно сохранить:
use Phalcon\Mvc\Controller;
class UserController extends Controller
{
public function indexAction()
{
$this->persistent->name = "Michael";
}
public function welcomeAction()
{
echo "Welcome, ", $this->persistent->name;
}
}
Использование сервисов как контроллеров
Сервисы могут действовать как контроллеры; классы контроллеров всегда запрашиваются из контейнера сервисов. Соответственно, любой другой класс, зарегистрированный под своим именем, может легко заменить контроллер:
// Register a controller as a service
$di->set(
"IndexController",
function () {
$component = new Component();
return $component;
}
);
// Register a namespaced controller as a service
$di->set(
"Backend\\Controllers\\IndexController",
function () {
$component = new Component();
return $component;
}
);
События в контроллерах
Контроллеры автоматически действуют как обработчики событий диспетчера диспетчер; реализация методов с этими именами событий позволяет реализовать точки подключения до/после выполнения действий:
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function beforeExecuteRoute($dispatcher)
{
// This is executed before every found action
if ($dispatcher->getActionName() === "save") {
$this->flash->error(
"You don't have permission to save posts"
);
$this->dispatcher->forward(
[
"controller" => "home",
"action" => "index",
]
);
return false;
}
}
public function afterExecuteRoute($dispatcher)
{
// Executed after every found action
}
}
© 2011–2017 Phalcon Framework Team
Licensed under the Creative Commons Attribution License 3.0.
https://docs.phalconphp.com/en/latest/reference/controllers.html