我想让模块Api有多个行为,其中URL中的paramateres是不同的 - 我想检查它们的约束。
如果在module.config.php中我做了类似下面的操作,那么这个控制器/模块将控制应用程序中的所有路径。
例如,如果我尝试运行http://example.com/notapi,它将在没有zf2布局的情况下生成错误,因为它会尝试处理此控制器,但是当我从应用程序配置中删除此模块时,它将处理ZF2布局中的错误。
这个控制器出了什么问题?
return array(
'controllers' => array(
'invokables' => array(
'Api\Controller\Api' => 'Api\Controller\ApiController',
),
),
'router' => array(
'routes' => array(
'api' => array(
'type' => 'literal',
'options' => array(
'route' => '/api',
'defaults' => array(
'controller' => 'Api\Controller\Api',
'action' => 'index',
),
),
),
'action1' => array(
'type' => 'segment',
'options' => array(
'route' => '/api/action1/:param',
'constraints' => array(
'param' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Api\Controller\Api',
'action' => 'action1',
),
),
),
'action2' => array(
'type' => 'segment',
'options' => array(
'route' => '/api/action2/:type/:lang',
'constraints' => array(
'type' => '[012]',
'lang' => 'pl|by|ru|ua',
),
'defaults' => array(
'controller' => 'Api\Controller\Api',
'action' => 'action2',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'api' => __DIR__ . '/../view'
),
'strategies' => array(
'ViewJsonStrategy',
),
),
);
这是我在Api模块中的Module.php
namespace Api;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
use Zend\View\Model\JsonModel;
class Module
{
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$eventManager->attach(MvcEvent::EVENT_DISPATCH_ERROR, array($this, 'onDispatchError'), 0);
$eventManager->attach(MvcEvent::EVENT_RENDER_ERROR, array($this, 'onRenderError'), 0);
}
public function onDispatchError($e)
{
return $this->getJsonModelError($e);
}
public function onRenderError($e)
{
return $this->getJsonModelError($e);
}
public function getJsonModelError($e)
{
$error = $e->getError();
if (!$error) {
return;
}
$response = $e->getResponse();
$exception = $e->getParam('exception');
$exceptionJson = array();
if ($exception) {
$exceptionJson = array(
'class' => get_class($exception),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'message' => $exception->getMessage(),
'stacktrace' => $exception->getTraceAsString()
);
}
$errorJson = array(
'message' => 'An error occurred during execution; please try again later.',
'error' => $error,
'exception' => $exceptionJson,
);
if ($error == 'error-router-no-match') {
$errorJson['message'] = 'Resource not found.';
}
$model = new JsonModel(array('errors' => array($errorJson)));
$e->setResult($model);
return $model;
}
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
}
答案 0 :(得分:0)
ZF2路线是“第一匹配”原则。将使用匹配的第一条路线。所以你的第一条路线是/ api这将匹配你所有的/ api *路线。所以你的其他路线永远不会被使用。
return array(
'controllers' => array(
'invokables' => array(
'Api\Controller\Api' => 'Api\Controller\ApiController',
),
),
'router' => array(
'routes' => array(
'action1' => array(
'type' => 'segment',
'options' => array(
'route' => '/api/action1/:param',
'constraints' => array(
'param' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Api\Controller\Api',
'action' => 'action1',
),
),
),
'action2' => array(
'type' => 'segment',
'options' => array(
'route' => '/api/action2/:type/:lang',
'constraints' => array(
'type' => '[012]',
'lang' => 'pl|by|ru|ua',
),
'defaults' => array(
'controller' => 'Api\Controller\Api',
'action' => 'action2',
),
),
),
'api' => array(
'type' => 'literal',
'options' => array(
'route' => '/api',
'defaults' => array(
'controller' => 'Api\Controller\Api',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'api' => __DIR__ . '/../view'
),
'strategies' => array(
'ViewJsonStrategy',
),
),
);
编辑:
我会使用更通用的路线。看到这个例子:
'myroutename' => array(
'type' => 'Literal',
'options' => array(
'route' => '/myprefix',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Gantt',
'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(
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Wildcard',
'options' => array(
)
)
)
),
),
),
这匹配一个控制器和一个动作,带有通配符的childroute允许我需要的所有参数。