Skip to content

Instantly share code, notes, and snippets.

@FoggyK
Last active August 21, 2017 05:55
Show Gist options
  • Save FoggyK/e63ea2ce01c1df67e1100b30a8371771 to your computer and use it in GitHub Desktop.
Save FoggyK/e63ea2ce01c1df67e1100b30a8371771 to your computer and use it in GitHub Desktop.

Имена шаблонов представления

Переопределение стандартных имен шаблонов представления

Когда вы возвращаете данные с контейнером переменных ViewModel из метода действия вашего контроллера, Zend Framework знает имя соответствующего файла шаблона представления. Например, для метода aboutAction() вашего IndexController'а, ZF3 автоматически использует шаблон представления about.phtml.

ZF3 определяет корректное имя шаблона представления по имени модуля, имени контроллера и имени действия. Например, действие IndexController::aboutAction(), принадлежащее модулю Application будет иметь шаблон представления application/index/about.phtml по умолчанию.

Если название вашего контроллера или действия состоит из нескольких слов в верблюжьем регистре (например, UserRegistrationController и registrationStep1Action), ему будет соответствовать шаблон представления application/user-registration/registration-step-1.phtml (имена в верблюжьем регистре преобразуются в нижний регистр, и слова разделяются дефисами).

// Метод для отображения главной страницы вашего сайта.
public function indexAction() 
{    
	// Использовать другой шаблон представления для рендеринга страницы.
	$viewModel = new ViewModel();
	$viewModel->setTemplate('application/index/about');
	return $viewModel;
}

В приведенном отрезке кода мы как обычно создали новый экземпляр класса ViewModel (строка 5). Затем мы вызвали метод setTemplate() для объекта модели представления (строка 6) и передали имя шаблона представления как его аргумент. Имя шаблона представления - это, по сути, относительный путь к файлу about.phtml, но без расширения файла.

Наконец, мы вернули объект модели представления из метода действия (строка 7).

Однако, вызывать метод setTemplate() в каждом методе действия необязательно. Если вы не сделаете этого, ZF3 определит имя шаблона представления автоматически, по текущему имени модуля, имени контроллера и имени метода действия.

Стратегии рендеринга представления

Стратегия рендеринга представления (rendering strategy) определяет то, как будет визуализирована страница. По умолчанию, чтобы получить HTML страницу, производится рендеринг шаблона представления .phtml с помощью класса PhpRenderer, живущего в простанстве имен Zend\View\Renderer. Эта стратегия работает хорошо в 99% случаев. Но иногда вам может понадобиться отобразить что-то кроме HTML страницы, например, ответ в формате JSON или новостную ленту (RSS feed).

Ответ в формате JSON обычно возвращается, когда вы реализуете какой либо API (Application Programming Interface). API используется для того, чтобы извлечь данные с веб-сайта в машинно-читаемом виде. Ответ в виде новостной ленты (RSS feed) обычно используется для публикации часто меняющейся информации, такой как посты блога или новости.

Итак, ZF3 из коробки предлагает три стратегии рендеринга представления:

  1. стратегия, используемая по умолчанию (также известная как PhpRenderingStrategy).
  2. стратегия JsonStrategy, выдающая ответ в формате JSON.
  3. и стратегия FeedStrategy, выдающая RSS feed. Например, давайте покажем как использовать стратегию JsonStrategy, чтобы вернуть ответ JSON из действия контроллера.

Сначала вам нужно зарегистрировать стратегию в файле конфигурации module.config.php:

<?php
return [
    //...
    
    'view_manager' => [
        //...
        
        'strategies' => [
            'ViewJsonStrategy',
        ],
    ],
];

Затем верните объект JsonModel (вместо обычного ViewModel) из метода действия контроллера:

namespace Application\Controller;
 
use Zend\Mvc\Controller\ActionController;
use Zend\View\Model\JsonModel;
 
class IndexController extends ActionController
{
    public function getJsonAction()
    {
        return new JsonModel([
            'status' => 'SUCCESS',
            'message'=>'Here is your data',
            'data' => [
                'full_name' => 'John Doe',
                'address' => '51 Middle st.'
            ]
        ]);
    }
}

Если вы откроете эту страницу в браузере, вы должны увидеть ответ в формате JSON:

{'status':'SUCCESS', 'message':'Here is your data', 'data':{'full_name:'John Doe', 'address':'51 Middle st.'}}

Страницы ошибок

Когда страница не может быть найдена или в вашем веб-приложении происходит какая-то другая ошибка, отображается стандартная страница ошибки. Появление страницы ошибки контролируется шаблонами ошибок. Существует два шаблона ошибок: error/404, который используется для ошибки "404 Page Not Found" , и error/index, который отображается, когда происходит общая ошибка (например, необработанное исключение выбрасывается внутрь приложения). Файл module.config.php содержит несколько параметров под ключом view_manager , которые вы можете использовать для конфигурации отображения ваших шаблонов ошибок:

<?php
return [
    //...
    
    'view_manager' => [    
        'display_not_found_reason' => true,
        'display_exceptions'       => true,
        //...
        'not_found_template'       => 'error/404',
        'exception_template'       => 'error/index',    
        'template_map' => [
            //...
            'error/404' => __DIR__ . '/../view/error/404.phtml',
            'error/index'=> __DIR__ . '/../view/error/index.phtml',
        ],
        //...
    ],
];
  1. Параметр display_not_found_reason контролирует, отображать ли детальную информацию о ошибке "Page not Found".
  2. Параметр display_exceptions определяет, отображать ли информацию о необработанных исключениях и его трассировки стека.
  3. not_found_template определяет имя шаблона для 404 ошибки.
  4. exception_template указывает имя шаблона для ошибки необработанного исключения.

Как правило, на production-сервере вы устанавливаете параметры display_not_found_reason и display_exceptions в false, потому что вы не хотите, чтобы ваши посетители видели детали ошибок на вашем сайте. Однако, вы все равно сможете извлекать детальную информацию из файла Apache error.log..

Контроллеры

Когда создавать новый контроллер?

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

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

Рекомендуется создавать новый класс контроллера для каждой модели (или для самых важных) вашей области бизнес-логики.

Например, вы можете создать UserController для управления пользователями вашего сайта. Этот контроллер будет иметь стандартное действие "index" для отображения страницы со всеми пользователями, действие "add" для добавления нового юзера, действие "edit" для изменения профиля пользователя и действие "delete" для удаление пользователя.

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

Регистрация контроллера

Все классы контроллера, принадлежащие модулю, должны быть зарегистрированы в файле конфигурации module.config.php. Если вашему контроллеру не нужно вызывать какие либо сервисы (если у него нет зависимостей), то вы можете зарегистрировать его следующим образом:

<?php
use Zend\ServiceManager\Factory\InvokableFactory;

return [
    // ...
    
    'controllers' => [
        'factories' => [
            Controller\IndexController::class => InvokableFactory::class
            // Вставьте сюда регистрацию других контроллеров
        ],
    ],
    
    // ...
];

В строке 7 у нас есть ключ controllers, который содержит подключ factories. Чтобы зарегистрировать класс контроллера, нужно добавить строку в виде пары key=>value. Ключом должно быть полностью квалифицированное имя класса контроллера, например, \Application\Controller\IndexController (мы можем использовать ключевое слово PHP ::class для разрешения имен) и значение должно быть именем фабричного класса. В нашем случае, мы используем стандартную фабрику InvokableFactory, но, если хотите, можете создать свою фабрику.

Используя InvokableFactory, вы говорите Zend Framework'у, что он может вызвать контроллер, инстанцировав его с помощью оператора new. Это самый простой способ инстанциации контроллера. В качестве альтернативы, вы можете создать свою фабрику для создания экземпляров контроллера и внедрить зависимости (inject dependencies) в контроллер.

Роутинги

Типы маршрутов

Маршрутизация (routing) - это механизм, позволяющий установить соответствие между URL запроса и контроллерами и их действиями. Благодаря маршрутизации, ZF3 знает, какой метод действия контроллера следует выполнить в результате запроса. Например, можно установить соответствие между URL "http://localhost/" и методом IndexController::indexAction(), и между URL "http://localhost/about" и методом IndexController::aboutAction().

Вы определяете соответствие между URL и контроллерами с помощью маршрутов (routes).

Zend Framework 3 предоставляет несколько стандартных типов маршрутов (см. таблицу 5.1). Эти типы реализованы в качестве классов и находятся в пространстве имен Zend\Router\Http.

Тип маршрута Описание
Literal Полное сопоставление с путем URL.
Segment Сопоставление с сегментом пути (или несколькими сегментами) URL.
Regex Сопоставление пути URL с шаблоном регулярного выражения.
Hostname Сопоставление имени хоста с каким-либо критерием.
Scheme Сопоставление схемы URL с каким-либо критерием.
Method Сопоставление метода HTTP (например, GET, POST, и т.д.) с каким-либо критерием.
Каждый тип маршрута в этой таблице (кроме типа Method) может быть сопоставлен с определенной частью (или несколькими частями) URL. Тип маршрута Method сопоставляется с HTTP-методом (либо GET, либо POST), извлеченным из HTTP-запроса.

Конфигурация маршрутизации по умолчанию в Zend Skeleton Application

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

<?php
use Zend\Router\Http\Literal;
use Zend\Router\Http\Segment;

return [
    'router' => [
        'routes' => [
            'home' => [
                'type' => Literal::class,
                'options' => [
                    'route'    => '/',
                    'defaults' => [
                        'controller' => Controller\IndexController::class,
                        'action'     => 'index',
                    ],
                ],
            ],
            'application' => [
                'type'    => Segment::class,
                'options' => [
                    'route'    => '/application[/:action]',
                    'defaults' => [
                        'controller'    => Controller\IndexController::class,
                        'action'        => 'index',
                    ],
                ],
            ],
        ],
    ],
    
    //...
];

В представленной конфигурации у нас есть два правила маршрутизации: сначала маршрут "home" (строка 8), а затем маршрут "application" (строка 18).

Маршрут "home" устанавливает соответствие между пустым путем URL и действием "index" контроллера IndexController. Например, введите "http://localhost/" в браузере и вы увидите домашнюю страницу вашего сайта. Этот маршрут - типа "Literal".

Маршрут "application" (типа "Segment") устанавливает соответствие между URL вида "http://localhost/application", "http://localhost/application/about", "http://localhost/application/news", и т.д. и соответствующим действием контроллера IndexController. Имя действия определяется параметром "action", значение этого параметра по умолчанию - "index". То есть, если вы не уточните действие, запрос будет послан действию "index".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment