В ZF1 вам не нужно было включать модуль в URL-адрес; если он не был предоставлен, он по умолчанию будет … по умолчанию. Как это можно сделать в ZF2? Я использовал скелетное приложение для запуска и запуска, но кажется, что мне всегда нужно включать имя модуля, например /application/controller/action
.
Я решил, что смогу обойти это, создав маршрут с двумя «заполнителями»; контроллер и действие, а затем установите модуль по умолчанию в «приложение». Затем я поместил бы это в /config/autoload/global.php
(или, возможно, /config/application.config.php
), чтобы маршрут /config/application.config.php
для всего моего приложения. Тем не менее, я получаю сообщение об ошибке, что URL-адрес не может быть сопоставлен маршрутизацией, даже если я жестко кодирую маршрут к чему-то вроде /user/index
.
Я попробовал код ниже.
return array( 'router' => array( 'routes' => array( 'nomodule' => array( 'type' => 'Zend\Mvc\Router\Http\Literal', 'options' => array( 'route' => '/:controller/:action', 'constraints' => array( 'controller' => '[a-zA-Z][a-zA-Z0-9_-]*', 'action' => '[a-zA-Z][a-zA-Z0-9_-]*' ), 'defaults' => array( 'module' => 'Application' // Not sure of the syntax here ) ) ), ) ) );
Как я написал в качестве комментария, я не уверен, что моя проблема связана с синтаксисом по умолчанию, но я бы не подумал, что так же произойдет, если я буду жестко кодировать маршрут и удалить все значения по умолчанию. Я также попытался поэкспериментировать с ним на примерах в скелетном приложении, но без везения. Неужели я ошибаюсь? Есть ли лучший подход? Или я просто ошибся?
Заранее спасибо.
Изменить: Чтобы код работал, см. Ответ. Для объяснения того, как это работает, прочитайте эту статью .
Примечание. Явные маршруты настоятельно рекомендуются по шаблону.
В вашей попытке использовался тип маршрута Zend \ Mvc \ Router \ Http \ Literal, так как вы можете догадаться, что это буквальный, то есть точное совпадение. Чтобы он работал, вам нужен тип сегмента.
Проверьте маршрут приложения в конфигурации application
Zend Skeleton и его дочерний маршрут по default
. Он делает именно то, что вы пытаетесь сделать.
Что касается модулей, то с точки зрения вашего кода нет такого понятия, как «модуль». Модуль регистрирует ресурсы при запуске и после этой точки больше не уместен. В zf2 вы указываете точный контроллер по имени класса или псевдонима, под которым контроллер, зарегистрированный контроллеромManager
// module\Application\config\module.config.php return array( 'router' => array( 'routes' => array( 'home' => array( 'type' => 'Zend\Mvc\Router\Http\Literal', 'options' => array( 'route' => '/', 'defaults' => array( 'controller' => 'Application\Controller\Index', 'action' => 'index', ), ), 'may_terminate' => true, 'child_routes' => array( 'default' => array( 'type' => 'Segment', 'options' => array( 'route' => '[:controller[/:action]]', 'constraints' => array( 'controller' => '[a-zA-Z][a-zA-Z0-9_-]*', 'action' => '[a-zA-Z][a-zA-Z0-9_-]*' ), 'defaults' => array( 'action' => 'index', '__NAMESPACE__' => 'Application\Controller' ) ) ) ) ) ) ), 'controllers' => array( 'invokables' => array( 'Application\Controller\Index' => 'Application\Controller\IndexController', 'Application\Controller\User' => 'Application\Controller\UserController' ), ) );
Как я сказал в комментарии в ответ на @Xerkus, он не работает для всех URL-адресов:
/application/index/index /application/index /application /index/index /index /
Я также добавил testAction()
в IndexController
и TestController
с теми же действиями, что и IndexController
, поэтому я мог проверить свое решение и на следующих маршрутах:
/index/test /test/index /test/test /test
Поэтому после некоторых исследований ( здесь и здесь в основном) я подготовил решение, работающее для всех из них. Я module.config.php
весь массив module.config.php
:
return array( 'router' => array( 'routes' => array( 'home' => array( 'type' => 'Literal', 'options' => array( 'route' => '/', 'defaults' => array( 'controller' => 'Application\Controller\Index', 'action' => 'index', ), ), ), 'noModule' => array( 'type' => 'Segment', 'options' => array( 'route' => '/[:controller[/:action]]', 'constraints' => array( 'controller' => '[a-zA-Z][a-zA-Z0-9_-]*', 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', ), 'defaults' => array( '__NAMESPACE__' => 'Application\Controller', 'controller' => 'Index', 'action' => 'index', ), ), ), // The following is a route to simplify getting started creating // new controllers and actions without needing to create a new // module. Simply drop new controllers in, and you can access them // using the path /application/:controller/:action 'application' => array( 'type' => 'Literal', 'options' => array( 'route' => '/application', 'defaults' => array( '__NAMESPACE__' => 'Application\Controller', 'controller' => 'Index', 'action' => 'index', ), ), 'may_terminate' => true, 'child_routes' => array( 'default' => array( 'type' => 'Segment', 'options' => array( 'route' => '/[:controller[/:action]]', 'constraints' => array( 'controller' => '[a-zA-Z][a-zA-Z0-9_-]*', 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', ), 'defaults' => array( ), ), ), ), ), ), ), 'service_manager' => array( 'factories' => array( 'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory', ), ), 'translator' => array( 'locale' => 'en_US', 'translation_file_patterns' => array( array( 'type' => 'gettext', 'base_dir' => __DIR__ . '/../language', 'pattern' => '%s.mo', ), ), ), 'controllers' => array( 'invokables' => array( 'Application\Controller\Index' => 'Application\Controller\IndexController', 'Application\Controller\Test' => 'Application\Controller\TestController' ), ), 'view_manager' => array( 'display_not_found_reason' => true, 'display_exceptions' => true, 'doctype' => 'HTML5', 'not_found_template' => 'error/404', 'exception_template' => 'error/index', 'template_map' => array( 'layout/layout' => __DIR__ . '/../view/layout/layout.phtml', 'application/index/index' => __DIR__ . '/../view/application/index/index.phtml', 'error/404' => __DIR__ . '/../view/error/404.phtml', 'error/index' => __DIR__ . '/../view/error/index.phtml', ), 'template_path_stack' => array( __DIR__ . '/../view', ), ), );
По сравнению с Zend 2 Skeleteon Application config я добавил маршрут noModule
и новый controller invokable
– test
. Конечно, маршрут noModule
включает пространство имен Application/Controller
, поэтому, основываясь на этом факте, вы можете установить любой необходимый по умолчанию модуль. Теперь он работает так, как должен.
Конечно, помните, что ваш маршрут noModule
должен быть определен в первом модуле из application.config.php
чтобы гарантировать, что он всегда будет иметь приоритет. Также помните, что решение по умолчанию для модулей должно выполняться тщательно, чтобы избежать конфликтов между именами контроллеров и модулей, например, если вы IndexController
свой следующий Index
модуля, то, очевидно, у вас будет конфликт имен с IndexController
в модуле Application
.
Я новичок в ZF в целом, и я только начал изучать его, поэтому попробовал это, и это сработало для меня. Чтобы быть уверенным, хотите ли вы изменить свой модуль по умолчанию, когда вы переходите на ваш домен, и не вводите имя контроллера?
Перейдите в модуль module.config.php
'router' => array( 'routes' => array( 'album WITH CONTROLLER IN URL' => array( 'type' => 'segment', 'options' => array( 'route' => '/album[/:action]', 'constraints' => array( 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', ), 'defaults' => array( 'controller' => 'Album\Controller\Album', 'action' => 'index', ), ), ), 'album WITHOUT CONTROLLER IN URL' => array( 'type' => 'segment', 'options' => array( 'route' => '/[:action]', 'constraints' => array( 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', ), 'defaults' => array( 'controller' => 'Album\Controller\Album', 'action' => 'index', ), ), ), 'SET IT AS YOUR HOMEPAGE' => array( 'type' => 'segment', 'options' => array( 'route' => '/', 'defaults' => array( 'controller' => 'Album\Controller\Album', 'action' => 'index', ), ), ), ), ),