使用zend framework 2路由在url上传递数组

时间:2015-06-12 20:28:20

标签: php zend-framework routes zend-framework2

我有一个网络应用,可让用户进行多次搜索,并在同一页面上显示所有搜索结果。

这是一个基本结构:

Search 1
 - Attribute 1 = X
 - Attribute 3 = Y

Search 2
 -Attribute 2 = Z

使用Ajax请求将所有这些结果加载到我的页面。这里的问题是,如果用户想要向某人显示搜索结果,他将无法这样做,因为网址保持不变。

要解决此问题,我可能会使用javascript push state或replace state:https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history

我的问题是Zend 2读取这些URL并解析它。我希望有一些用户友好的东西:

www.example.com/Search/Attribute1-X-Attribute3-Y/Search/Attribute2-Z

我的想法是在我的控制器上收到类似的东西:

$this->getParam('Search');//Array('Attribute1-x-Attribute3-Y','Attribute2-Z');

我知道我们可以用这种方式完成类似的事情:

?a[]=1&a[]=2&a[]=3

但这不是我正在寻找的机器人。

有关如何使用zf2路由完成此任务的任何帮助吗?

1 个答案:

答案 0 :(得分:0)

由于我没有反馈,我不得不做出解决方法。以下是我设法完成我的要求:

首先,而不是使用:

www.example.com/Search/Attribute1-X-Attribute3-Y/Search/Attribute2-Z

我使用过这样的东西:

www.example.com/Search/Attribute1/X/Attribute3/Y/Search/Attribute2/Z

我首先在我的module.config上使用正则表达式:

'search' => array(
            'type' => 'Application\Router\SearchesImprovedRegex',
            'options' => array(
                'regex' => '(/Search((/Attribute1/(?<attr1>[a-zA-Z-]+)){0,1}(/Attribute2/(?<attr2>[a-zA-Z-]+)){0,1}(/Attribute3/(?<attr3>[a-zA-Z-]+)){0,1}))+',
                'defaults' => array(
                    'controller' => 'Application\Controller\Index',
                    'action' => 'index',
                ),
                'spec'=> '/'
            ),
        ),

然后我创建了自己的类,扩展了Zend \ Mvc \ Router \ Http \ Regex并实现了RouterInterface。我只需要覆盖匹配函数,使它以不同的方式解析属性。

<?php 
namespace Application\Router;
use Zend\Mvc\Router\Http\Regex as Regex;
use Zend\Mvc\Router\Http\RouteMatch;
use Zend\Stdlib\RequestInterface as Request;
/**
* Regex route.
*/
class SearchesImprovedRegex extends Regex {

/**
 * match(): defined by RouteInterface interface.
 *
 * @param  Request $request
 * @param  int $pathOffset
 * @return RouteMatch|null
 */
public function match(Request $request, $pathOffset = null) {
    if (!method_exists($request, 'getUri')) {
        return null;
    }

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

    $auxPath = explode('/Search', $path);
    $searches = Array();


    for ($i = 1; $i < count($auxPath); $i++) {
        $search = array();
        $path = '/Search' . $auxPath[$i];

        if ($pathOffset !== null) {
            $result = preg_match('(\G' . $this->regex . ')', $path, $matches, null, $pathOffset);
        } else {
            $result = preg_match('(^' . $this->regex . '$)', $path, $matches);
        }

        if (!$result) {
            return null;
        }

        $matchedLength = strlen($matches[0]);

        foreach ($matches as $key => $value) {
            if (is_numeric($key) || is_int($key) || $value === '') {
                unset($matches[$key]);
            } else {
                $search[$key] = rawurldecode($value);
            }
        }
        array_push($searches, $search);
    }
    $matches = Array('Searches' => $searches);

    return new RouteMatch(array_merge($this->defaults, $matches), $matchedLength);
}
}

然后在控制器上:

var_dump($this->params('Searches'));