Zend框架2路由所需的查询参数不起作用

时间:2016-03-24 15:09:35

标签: php zend-framework routing zend-framework2

我正在研究zf2,只有在传递查询字符串参数时才能访问我的一条路由。否则,它不会。我在路由部分添加了一个过滤器,但是当访问没有查询参数的页面时,它仍然会通过。

'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 =这不应该起作用

2 个答案:

答案 0 :(得分:0)

您目前有这种设置的方式,您必须像这样构建您的网址

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

我认为你想要的是像这样构建你的路线

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

在显示之前,不确定要使用[/]尝试完成什么,但是你在那里选择了破折号?

我会像这样写

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

这样你可以像这样构建你的网址

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

答案 1 :(得分: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;
    }
}

此解决方案也非常容易进行单元测试,它不会验证任何OOP原则并且可以重复使用。

您的新路线定义现在看起来像这样:

// 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'
                )
            ),
        ),
    ),
),