edit action similar to tutorial doesn't work - zend-framework
I followed the ZF3 tutorial and I'm quite satisfied, but I'm something missing with the edit action in my controller. the add action works fine while the edit action doesn't. Probably I don't see it by myself, so I post it here, asking for help, even if it is really basic.
My model is nearly the same as in the tutorial, here a part of it:
public function exchangeArray(array $data)
{
$this->ProjectID= !empty($data['ProjectID']) ? $data['ProjectID'] : null;
$this->CI_Number= !empty($data['CI_Number']) ? $data['CI_Number'] : null;
$this->Description= !empty($data['Description']) ? $data['Description'] : null;
$this->Projectname= !empty($data['Projectname']) ? $data['Projectname'] : null;
$this->Shortcut= !empty($data['Shortcut']) ? $data['Shortcut'] : null;
$this->Component_Class= !empty($data['Component_Class']) ? $data['Component_Class'] : null;
}
public function getArrayCopy()
{
// echo var_dump(get_object_vars($this)
// );
//return get_object_vars($this);
return [
'ProjectID' => $this->ProjectID,
'CI_Number' => $this->CI_Number,
'Description' => $this->Description,
'Projectname' => $this->Projectname,
'Shortcut' => $this->Shortcut,
'Component_Class' => $this->Component_Class,
];
}
and here also my controlleraction:
public function editAction()
{
$id = (int) $this->params()->fromRoute('id', 0);
echo $id;
if (0 === $id) {
return $this->redirect()->toRoute('project', ['action' => 'add']);
}
else {
try {
$project = $this->projectTable->getProject($id);
} catch (\Exception $e) {
return $this->redirect()->toRoute('project', ['action' => 'index']);
}
$form = new ProjectForm();
$form->bind($project);
//$form->bind($project->current());
$form->get('submit')->setAttribute('value', 'save changes');
$request = $this->getRequest();
$viewData = ['ProjectID' => $id, 'form' => $form];
if (! $request->isPost()) {
return $viewData;
}
$form->setInputFilter($project->getInputFilter());
$form->setData($request->getPost());
if (! $form->isValid()) {
echo "nicht valide";
return $viewData;
}
else{
echo $project;
$this->projectTable->saveProject($project);
}
}
// Redirect to album list
// return $this->redirect()->toRoute('project', ['action' => 'index']);
}
here for completion reasons my view edit.phtml:
<?php
$title = 'projects';
$this->headTitle($title);
?>
<h1><?= $this->escapeHtml($title) ?></h1>
<?php
// This provides a default CSS class and placeholder text for the artist element:
$ProjectID= $form->get('ProjectID');
$ProjectID->setAttribute('class', 'form-control');
$ProjectID->setAttribute('placeholder', 'ProjectID');
$Projectname= $form->get('Projectname');
$Projectname->setAttribute('class', 'form-control');
$Projectname->setAttribute('placeholder', 'Projectname');
$CI_Number= $form->get('CI_Number');
$CI_Number->setAttribute('class', 'form-control');
$CI_Number->setAttribute('placeholder', 'CI_number');
$Shortcut= $form->get('Shortcut');
$Shortcut->setAttribute('class', 'form-control');
$Shortcut->setAttribute('placeholder', 'Shortcut');
$Description= $form->get('Description');
$Description->setAttribute('class', 'form-control');
$Description->setAttribute('placeholder', 'Description');
$Component_Class= $form->get('Component_Class');
$Component_Class->setAttribute('class', 'form-control');
$Component_Class->setAttribute('placeholder', 'Component_Class');
// This provides CSS classes for the submit button:
$submit = $form->get('submit');
$submit->setAttribute('class', 'btn btn-primary');
//$form->setAttribute('action', $this->url('project', ['action' => 'edit',])); //,'id'=> $id
$form->setAttribute('action', $this->url('project', [
'action' => 'edit',
'ProjectID' => $id,
]));
$form->prepare();
echo $this->form()->openTag($form);
?>
<?php // Wrap the elements in divs marked as form groups, and render the
// label, element, and errors separately within ?>
<div class="form-group">
<?= $this->formElement($ProjectID) ?>
<?= $this->formElementErrors()->render($ProjectID, ['class' => 'help-block']) ?>
</div>
<div class="form-group">
<?= $this->formLabel($CI_Number) ?>
<?= $this->formElement($CI_Number) ?>
<?= $this->formElementErrors()->render($CI_Number, ['class' => 'help-block']) ?>
</div>
<div class="form-group">
<?= $this->formLabel($Description) ?>
<?= $this->formElement($Description) ?>
<?= $this->formElementErrors()->render($Description, ['class' => 'help-block']) ?>
</div>
<div class="form-group">
<?= $this->formLabel($Projectname) ?>
<?= $this->formElement($Projectname) ?>
<?= $this->formElementErrors()->render($Projectname, ['class' => 'help-block']) ?>
</div>
<div class="form-group">
<?= $this->formLabel($Shortcut) ?>
<?= $this->formElement($Shortcut) ?>
<?= $this->formElementErrors()->render($Shortcut, ['class' => 'help-block']) ?>
</div>
<div class="form-group">
<?= $this->formLabel($Component_Class) ?>
<?= $this->formElement($Component_Class) ?>
<?= $this->formElementErrors()->render($Component_Class, ['class' => 'help-block']) ?>
</div>
<?php
echo $this->formSubmit($submit);
//echo $this->form->get('DCLID');
echo $this->formHidden($form->get('ProjectID'));
echo $this->form()->closeTag();
It will show the recordset properly, but won't save the changes to the database and afterwards redirects to my add action. I hope somebody sees what I'm missing, even it might be a stupid error.
EDIT1: Here is my routing link from index.phtml
Edit
EDIT2: Screenshot to show the routing parameter
EDIT3: describing test issues
here again my controller edit action, to follow up:
public function editAction()
{
$id = (int) $this->params()->fromRoute('id', 0);
echo "variable id: ". $id;
if (0 === $id) {
//return $this->redirect()->toRoute('project', ['action' => 'index']);
echo "id = 0";
}
else {
try {
$project = $this->projectTable->getProject($id);
} catch (\Exception $e) {
return $this->redirect()->toRoute('project', ['action' => 'index']);
}
$form = new ProjectForm();
$form->bind($project);
//$form->bind($project->current());
$form->get('submit')->setAttribute('value', 'save changes');
var_dump(get_object_vars($project));
$request = $this->getRequest();
$viewData = ['ProjectID' => $id, 'form' => $form];
if (!$request->isPost()) {
return $viewData;
}
else {
$form->setInputFilter($project->getInputFilter());
$form->setData($request->getPost());
if (!$form->isValid()) {
echo "nicht valide";
return $viewData;
}
else{
echo "valide";
echo $project;
$this->projectTable->saveProject($project);
}
}
}
// Redirect to album list
// return $this->redirect()->toRoute('project', ['action' => 'index']);
}
I get the output of the vardump, so the project to edit will be delivered correctly. If I send the form with the recordchanges the controller won't catch it, the controller action sees id=0 then, so the method saveProject will be never called. In my understanding it might has to do with the formvalid something, because after sending the data I come never further than if (0 === $id).
EDIT 4: After some actual tests I think it must be a routing issue. If I give the route manually via browser, I won't get the target page at all. If I dump the value, it is always NULL. So I think it could be a bracket to much/to less issue in my module.config.php I show it here because I couldn't finde the problem, I countedt the braskets several times and I won't get it. So any help is appreciated, it must be a very simple topic:
<?php
namespace Import;
use Zend\Router\Http\Segment;
use Zend\Router\Http\Literal;
use Zend\ServiceManager\Factory\InvokableFactory;
//use Zend\ServiceManager\Factory\InvokableFactory;
return [
/* 'controllers' => [
'factories' => [
Controller\ImportController::class => InvokableFactory::class,
],
], */
// hier die Einstellungen für die Routen
'router' => [
'routes' => [
'index' => [
'type' => Segment::class,
'options' => [
'route' => '/import[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
],
'import' => [
'type' => Segment::class,
'options' => [
'route' => '/import[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\ImportController::class,
'action' => 'index',
],
],
],
'importdcl' => [
'type' => Segment::class,
'options' => [
'route' => '/importdcl[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\ImportdclController::class,
'action' => 'index',
],
],
],
'project' => [
'type' => Segment::class,
'options' => [
'route' => '/project[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\ProjectController::class,
'action' => 'index',
],
],
],
'unit' => [
'type' => Segment::class,
'options' => [
'route' => '/unit[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\UnitController::class,
'action' => 'index',
],
],
],
'index' => [
'type' => Segment::class,
'options' => [
'route' => '/index[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
],
'user' => [
'type' => Segment::class,
'options' => [
'route' => '/user[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\UserController::class,
'action' => 'index',
],
],
],
'followup' => [
'type' => Segment::class,
'options' => [
'route' => '/followup[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\FollowupController::class,
'action' => 'index',
],
],
],
],
],
'view_manager' => [
'template_path_stack' => [
'import' => __DIR__ . '/../view',
],
],
/* ... */
'navigation' => [
'default' => [
[
'label' => 'Dashboard',
'route' => 'home',
],
[
'label' => 'Project',
'route' => 'project',
'pages' => [
[
'label' => 'Add',
'route' => 'project',
'action' => 'add',
],
[
'label' => 'Edit',
'route' => 'project',
'action' => 'edit',
],
[
'label' => 'Delete',
'route' => 'project',
'action' => 'delete',
],
],
],
[
'label' => 'Unit',
'route' => 'unit',
'pages' => [
[
'label' => 'Add',
'route' => 'unit',
'action' => 'add',
],
[
'label' => 'Edit',
'route' => 'unit',
'action' => 'edit',
],
[
'label' => 'Delete',
'route' => 'unit',
'action' => 'delete',
],
],
],
[
'label' => 'Importlog',
'route' => 'importdcl',
'action' => 'index',
'pages' => [
[
'label' => 'Add',
'route' => 'unit',
'action' => 'add',
],
[
'label' => 'Edit',
'route' => 'unit',
'action' => 'edit',
],
[
'label' => 'Delete',
'route' => 'unit',
'action' => 'delete',
],
],
],
[
'label' => 'Follow up',
'route' => 'followup',
'action' => 'index',
'pages' => [
[
'label' => 'Add',
'route' => 'unit',
'action' => 'add',
],
[
'label' => 'Edit',
'route' => 'unit',
'action' => 'edit',
],
[
'label' => 'Delete',
'route' => 'unit',
'action' => 'delete',
],
],
],
[
'label' => 'User',
'route' => 'user',
'pages' => [
[
'label' => 'Add',
'route' => 'unit',
'action' => 'add',
],
[
'label' => 'Edit',
'route' => 'unit',
'action' => 'edit',
],
[
'label' => 'Delete',
'route' => 'unit',
'action' => 'delete',
],
],
],
[
'label' => 'Logout',
'route' => 'user',
'action' => 'logout',
'pages' => [
[
'label' => 'Add',
'route' => 'unit',
'action' => 'add',
],
[
'label' => 'Edit',
'route' => 'unit',
'action' => 'edit',
],
[
'label' => 'Delete',
'route' => 'unit',
'action' => 'delete',
],
],
],
],
],
/* ... */
];
I'm testing in the usercontroller at the moment, but I have had the same problem in others routes, so I think the error might be in this file.
Based on your code, seem the problem is on $id. It mean the value is 0, that's why it is redirected to project/add.
$id = (int) $this->params()->fromRoute('id', 0);
echo $id;
if (0 === $id) {
return $this->redirect()->toRoute('project', ['action' => 'add']);
}
In your view script, the form action is set to project/edit/ProjectID/$id
$form->setAttribute('action', $this->url('project', [
'action' => 'edit',
'ProjectID' => $id,
]));
That's why your controller cannot retrieve $this->params()->fromRoute('id', 0), because the form send ProjectID param instead of id.
So, the solution please adjust your form (using id) or your controller (using ProjectID).
I at last solved it. My suggestion was right, it was a problem with the module.config.php, I have set an endbracket at the wrong place.
After writing it in parts new, tsting and complete the file, it now works.
Related
Zend routing issue
I'm working on converting a (quite sloppily put together) zend expressive website to a zend framework 3 website for a local restaurant. When I set up the routing on the expressive website I would load a location based on a query parameter looking like this. website.com/location?location=xxx On my new website the routing looks like this website.com/locations/view/xxx I need to set up a route that redirects the old url to the new url. So far I have set up a route that looks for the /location?location=[/:location] hoping that it would recognize this 'Segment' route and load the appropriate LocationsController. Right now it is giving me a route not found error. My code looks like below. module.config.php namespace Application; use Zend\Router\Http\Literal; use Zend\Router\Http\Segment; use Zend\ServiceManager\Factory\InvokableFactory; return [ 'router' => [ 'routes' => [ 'home' => [ 'type' => Literal::class, 'options' => [ 'route' => '/', 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'index', ], ], ], 'locations-old' => [ 'type' => Segment::class, 'options' => [ 'route' => '/location?location=[/:location]', 'defaults' => [ 'controller' => Controller\LocationController::class, 'action' => 'index', ], ], ], 'locations' => [ 'type' => Segment::class, 'options' => [ 'route' => '/locations[/:action[/:location]]', 'constraints' => [ 'action' => '[a-zA-Z]*', 'location' => '[a-zA-Z]*', ], 'defaults' => [ 'controller' => Controller\LocationController::class, 'action' => 'index', ], ], ], 'locations.html' => [ 'type' => Literal::class, 'options' => [ 'route' => '/locations.html', 'constraints' => [ 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', 'location' => '[a-zA-Z][a-zA-Z0-9_-]*', ], 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'index', ], ], ], 'about' => [ 'type' => Literal::class, 'options' => [ 'route' => '/about', 'defaults' => [ 'controller' => Controller\AboutController::class, 'action' => 'index', ], ], ], 'employ' => [ 'type' => Literal::class, 'options' => [ 'route' => '/employ', 'defaults' => [ 'controller' => Controller\EmployController::class, 'action' => 'index', ], ], ], 'news' => [ 'type' => Literal::class, 'options' => [ 'route' => '/news', 'defaults' => [ 'controller' => Controller\NewsController::class, 'action' => 'index', ], ], ], ], ], 'view_manager' => [ 'display_not_found_reason' => true, 'display_exceptions' => true, 'doctype' => 'HTML5', 'not_found_template' => 'error/404', 'exception_template' => 'error/index', 'template_map' => [ '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' => [ __DIR__ . '/../view', ], ], ]; LocationController.php namespace Application\Controller; use Zend\Mvc\Controller\AbstractActionController; use Application\Model\StoreTable; use Zend\View\Model\ViewModel; class LocationController extends AbstractActionController { private $table; public function __construct(StoreTable $table) { $this->table = $table; } public function indexAction() { if($_GET['location'] && $this->table->doesExist($_GET['location'])) { $location = $_GET['location']; $this->redirect()->toRoute('locations', ['action' => 'view', 'location' => $location])->setStatusCode(302); } else { $this->redirect()->toUrl('/#locations')->setStatusCode(301); } } public function viewAction() { $location = (string) $this->params()->fromRoute('location'); $store = $this->table->getStore($location); return new ViewModel([ 'store' => $store, ]); } } Any help would be greatly appreciated and I can provide more info if needed. Thanks!
configure your route as following, this will be handle query based url as you given "website.com/location?location=xxx", In below route ":key" variable implies ?location=xxx 'locations-old' => [ 'type' => Segment::class, 'options' => [ 'route' => '/location/:key', 'defaults' => [ 'controller' => Controller\LocationController::class, 'action' => 'index', ], 'constraints' => [ 'key' => '[a-z0-9]+', ], ], 'child_routes' => [ 'query' => ['type' => 'query'], ], ]
Method not allowed(#405)
following code throws out error like this: "Method Not Allowed (#405) Method Not Allowed. This url can only handle the following request methods: ." Any ideas,how to fix this? ['label' => 'Logout', 'url' => ['/site/logout'], 'linkOptions' => ['data' => ['method' => 'post']]], Here is still method in SiteController: public function actionLogout() { Yii::$app->user->logout(); return $this->goHome(); }
use data-method in linkOptions ['label' => 'logOut', 'url' => ['/site/logout'], 'linkOptions' => ['data-method' => 'post'] ], notice:check behavior in sitecontroller public function behaviors() { return [ 'access' => [ 'class' => AccessControl::className(), 'only' => ['logout', 'dashboard'], 'rules' => [ [ 'actions' => ['logout'], 'allow' => true, 'roles' => ['#'], ], ], ], 'verbs' => [ 'class' => VerbFilter::className(), 'actions' => [ 'logout' => ['post'], ], ], ]; }
routing after authentication doesn't work properly
I probably have an understanding issue how the routing works. I tried a bit with zend-authentication, you can see the controllercode below. If the authentication is valide I want a routing to another controller index action. Should be quite simple, but the routing doesn't work I stay at the loginform. I added an echo just to see where I am after authentication and the authentication is valide. Here is the code: $form = new LoginForm(); //return ['form' => $form]; $form->get('submit')->setValue('Login'); //echo "hier"; //$this->layout()->setTemplate('layout/login-layout'); $request = $this->getRequest(); if (! $request->isPost()) { return ['form' => $form]; } else { $username=$request->getPost('accessname'); $password=$request->getPost('passwort'); //echo $password; $adapter = $this->authService->getAdapter(); $adapter->setIdentity($request->getPost('accessname')); $adapter->setCredential($request->getPost('passwort')); $result = $this->authService->authenticate(); if ($result->isValid()){ echo "valide"; //return $this->redirect()->toRoute('import'); return $this->redirect()->toRoute('import', ['action' => 'index']); } else{ return ['form' => $form, 'messages' => $result->getMessages()]; } } as you can see I tried several possibilities. The other controller is placed in the same module. Here additional the index action of the destinationcontroller. I'm not finished there, because of the false routing I toggled everything else, so it just shows the echotext when I land there. public function indexAction() { echo "importcontroller"; // $result = $this->authService->has // $auth=Zend_Auth::getInstance(); // $adapter = $this->authService->getAdapter(); // if(!$this->authService->hasIdentity()) // { // return $this->redirect()->toRoute('./index/index'); // } // else { // return new ViewModel([ // 'projects' => $this->projectTable->fetchAll(), // ]); // } } EDIT1: Add module.confg.php 'router' => [ 'routes' => [ 'import' => [ 'type' => Segment::class, 'options' => [ 'route' => '/import[/:action[/:id]]', 'constraints' => [ 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', 'id' => '[0-9]+', ], 'defaults' => [ 'controller' => Controller\ImportController::class, 'action' => 'index', ], ], ], 'project' => [ 'type' => Segment::class, 'options' => [ 'route' => '/project[/:action[/:id]]', 'constraints' => [ 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', 'id' => '[0-9]+', ], 'defaults' => [ 'controller' => Controller\ProjectController::class, 'action' => 'index', ], ], ], 'unit' => [ 'type' => Segment::class, 'options' => [ 'route' => '/unit[/:action[/:id]]', 'constraints' => [ 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', 'id' => '[0-9]+', ], 'defaults' => [ 'controller' => Controller\UnitController::class, 'action' => 'index', ], ], ], 'index' => [ 'type' => Segment::class, 'options' => [ 'route' => '/index[/:action[/:id]]', 'constraints' => [ 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', 'id' => '[0-9]+', ], 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'index', ], ], ], 'user' => [ 'type' => Segment::class, 'options' => [ 'route' => '/user[/:action[/:id]]', 'constraints' => [ 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', 'id' => '[0-9]+', ], 'defaults' => [ 'controller' => Controller\UserController::class, 'action' => 'index', ], ], ], 'followup' => [ 'type' => Segment::class, 'options' => [ 'route' => '/followup[/:action[/:id]]', 'constraints' => [ 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', 'id' => '[0-9]+', ], 'defaults' => [ 'controller' => Controller\FollowupController::class, 'action' => 'index', ], ], ],
Can you show contents of module.config.php with routing configuration? Maybe your routing was wrong and redirect to the same page where you are before correct authentication? P.s. I think, You should always filternig data from form and get it by $form->getDate() function. Of course before you should apply appropriate filters. this concept is described in zend framework tutorial: https://docs.zendframework.com/tutorials/getting-started/forms-and-actions/
ZF2 - how to check if a route with child exists
Given this route: 'country' => array( 'type' => 'Zend\Mvc\Router\Http\Segment', 'options' => array( 'route' => '/1country', 'defaults' => array( 'controller' => 'Index', 'action' => 'country', 'country_id' => '5', ), ), 'may_terminate' => true, 'child_routes' => array( 'city' => array( 'type' => 'Zend\Mvc\Router\Http\Segment', 'options' => array( 'route' => '/1city', 'defaults' => array( 'controller' => 'Index', 'action' => 'city', 'city_id' => '4', ), ), ), ), ), if I do: $this->getServiceLocator()->get('Router')->hasRoute('country'); //true $this->getServiceLocator()->get('Router')->hasRoute('country/city'); //false While both should be true.. Any ideas?
Try this: // explode if child.. $route = 'home/default'; $names = explode('/', $route, 2); // use /* #var Router $router */ $router = $container->get('Router'); if (!$router->hasRoute($names[0])) { // ... }
ZF2 Route multiple strings to the same controller?
I want to configure my Zf2 application in such a way that multiple strings route to the same controller. For example www.mysite.com/this and www.mysite.com/that both route to the same controller and have this and that available to capture with $this->params. How would I accomplish something like this? Would I need 2 separate route declarations? 'directory' => [ 'type' => 'Zend\Mvc\Router\Http\Literal', 'options' => [ 'route' => '/string1 || /string2 || /string3', 'defaults' => [ 'controller' => 'Application\Controller\MyController', 'action' => 'index' ], ], ]
Easiest solution IMO, is: 'varcatcher' => [ 'type' => 'Segment', 'options' => [ 'route' => '[/[:tail]]', 'defaults' => [ 'controller' => '\Application\Controller\Index', 'action' => 'catch', 'module' => 'Application', ], 'constraints' => [ 'tail' => '[a-zA-z0-9_-]*' ], ], 'may_terminate' => true, ], Then deal with it in your action: public function catchAction(){ die( $this->params()->fromRoute('tail') ); } Because ZF2 routes are LIFO. It's probably optimal to deal with it by inserting it first, and handling whatever cases you need to 'catch'. The mention of LIFO, is because if you define routes 'after' in the router array, those will precede the catch-all, which seems to be of benefit if I've read your question right. Cheers! Alex
You could use a Zend\Mvc\Router\Http\Regex route type, instead of a Literal one and do something like 'directory' => [ 'type' => 'Zend\Mvc\Router\Http\Regex', 'options' => [ 'route' => '/string(?<id>[0-9]+)', 'defaults' => [ 'controller' => 'Application\Controller\MyController', 'action' => 'index' ], ], ]
As of definition of Literal route create 3 routes: 'directory1' => [ 'type' => 'Zend\Mvc\Router\Http\Literal', 'options' => [ 'route' => '/string1', 'defaults' => [ 'controller' => 'Application\Controller\MyController', 'action' => 'index', ], ], ], 'directory2' => [ 'type' => 'Zend\Mvc\Router\Http\Literal', 'options' => [ 'route' => '/string2', 'defaults' => [ 'controller' => 'Application\Controller\MyController', 'action' => 'index', ], ], ], 'directory3' => [ 'type' => 'Zend\Mvc\Router\Http\Literal', 'options' => [ 'route' => '/string3', 'defaults' => [ 'controller' => 'Application\Controller\MyController', 'action' => 'index', ], ], ],