2016-03-24 2 views
1

Я работаю над zf2, чтобы сделать один из моих маршрутов доступным только при передаче параметра строки запроса. В противном случае это не произойдет. Я добавил фильтр в раздел маршрута, но при доступе к странице без параметра запроса он все еще проходит через.Zend framework 2 routing требуемые параметры запроса не работают

'router' => array(
    'routes' => array(
     'show_post' => array(
      'type' => 'segment', 
      'options' => array(
       'route' => '[/]show/post/:filter', 
       'constraints' => array(
        'filter' => '[a-zA-Z0-9-.]*', 
       ), 
       'defaults' => array(
        'controller' => 'blog_controller', 
        'action' => 'show' 
       ) 
      ), 
     ), 
    ), 
), 

http://example.com/show/post/?postId=1235 = Это должно работать

http://example.com/show/post?postId=1235 = Это должно работать

http://example.com/show/post/ = Это не должно работать

http://example.com/show/post = Это не должно работать

+1

Вы не можете (или не должен) маршрут по параметрам запроса в ZF2. Вам нужно будет проверить их в своем контроллере или использовать другую структуру URL (например, '/ show/post/postid = 1235 /') –

ответ

0

так, как вы в настоящее время имеем эту настройку вам нужно будет структурировать ваш URL-адрес следующим образом:

http://example.com/show/post/anything?postId=1235

Я думаю, что вы хотели, чтобы структурировать свой маршрут как этого

'route' => '[/]show/post', 

Не уверен, что вы пытаетесь достичь с [/] перед шоу, хотя, вы делаете что тир необязательно есть ?

Я бы написать это

'route' => '/show/post[/:filter]', 

Таким образом, вы можете структурировать ваши URLs как этот

http://example.com/show/post/anything?postId=1235

или

http://example.com/show/post?postId=1235

Затем в действии вы могут получить доступ к тем па араметры нравится эта

$filter = $this->params('filter'); 
$post_id = $this->params()->fromQuery('post_id'); 

или просто

$post_id = $this->params()->fromQuery('post_id'); 

*************** *************** UPDATE

Похоже, что zf2 используется, чтобы включить то, что вы пытаетесь сделать, и удалить его из соображений безопасности.

http://framework.zend.com/security/advisory/ZF2013-01

+0

Причина, по которой я добавил фильтр в маршрутизации, - это перенаправление на страницу с ошибкой если параметры строки запроса не передаются. Можно ли это сделать непосредственно на 'module.config.php' вместо того, чтобы иметь метод на контроллере, который проверяет, прошла ли строка запроса или нет? – basagabi

+0

Лучшая практика заключается в том, что вы все равно должны загружать данные по умолчанию с параметрами или создавать набор параметров по умолчанию, которые вы добавляете, если их не существует. В противном случае, если вы ожидаете что-то вроде 'post_id' на этом URL-адресе, тогда сделайте этот параметр маршрута таким, как этот '' route '=>'/show/post /: post_id ',', тогда вы гарантируете, что вы получите этот параметр и если их там нет, они отправятся на вашу страницу «404» – gmaniac

+0

Точно. Как я уже сказал, для этой страницы требуется параметр запроса. Если он не существует, он перенаправляется на страницу с ошибкой. Но проблема в том, что, основываясь на приведенном выше коде, если параметр запроса существует или нет, он всегда перенаправляется на метод контроллера, который не должен. – basagabi

0

Не пытайтесь согнуть стандартные ZF2 классы пути. Вместо того, чтобы написать свой собственный класс маршрута, декоратор на маршрут сегмента, который будет делать именно так, как вам угодно:

<?php 
namespace YourApp\Mvc\Router\Http; 

use Zend\Mvc\Router\Http\Segment; 
use use Zend\Mvc\Router\Exception; 
use Zend\Stdlib\RequestInterface as Request; 

class QueryStringRequired extends Segment 
{ 
    public static function factory($options = []) 
    { 
     if (!empty($options['string'])) { 
      throw new Exception\InvalidArgumentException('string parameter missing'); 
     } 

     $object = parent::factory($options); 
     $this->options['string'] = $options['string']; 

     return $object; 
    } 

    public function match(Request $request, $pathOffset = null, array $options = []) 
    { 
     $match = parent::match($request, $pathOffset, $options); 
     if (null === $match) { 
      // no match, bail early 
      return null; 
     } 

     $uri = $request->getUri(); 
     $path = $uri->getPath(); 

     if (strpos($path, $this->options['string']) === null) { 
      // query string parametr not found in the url 
      // no match 
      return null; 
     } 

     // no query strings parameters found 
     // return the match 
     return $match; 
    } 
} 

Этим решением очень легко для модульного тестирования, а также, не проверяют никаких принципов объектно-ориентированного программирования и может использоваться повторно.

Ваше новое определение маршрута будет выглядеть, как это сейчас:

// route definition 

'router' => array(
    'routes' => array(
     'show_post' => array(
      'type' => YourApp\Mvc\Router\Http\QueryStringRequired::class, 
      'options' => array(
       'string' => '?postId=', 
       'route' => '[/]show/post/:filter', 
       'constraints' => array(
        'filter' => '[a-zA-Z0-9-.]*', 
       ), 
       'defaults' => array(
        'controller' => 'blog_controller', 
        'action' => 'show' 
       ) 
      ), 
     ), 
    ), 
), 
Смежные вопросы