使用 zend framework 2 路由在 url 上传递数组
Pass array on url using zend framework 2 routes
我有一个网络应用程序,允许用户进行多次搜索并在同一页面上显示所有搜索结果。
这是一个基本结构:
Search 1
- Attribute 1 = X
- Attribute 3 = Y
Search 2
-Attribute 2 = Z
所有这些结果都使用 Ajax 请求加载到我的页面。这里的问题是,如果用户想向某人显示搜索结果,他将无法执行此操作,因为 url 保持不变。
要解决此问题,我可能会使用 javascript 推送状态或替换状态: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 路由完成此操作的任何帮助?
由于我没有任何反馈,因此我不得不制定解决方法。以下是我如何设法完成我所要求的:
首先,而不是使用:
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'=> '/'
),
),
然后我创建了自己的 class,它扩展了 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'));
我有一个网络应用程序,允许用户进行多次搜索并在同一页面上显示所有搜索结果。
这是一个基本结构:
Search 1
- Attribute 1 = X
- Attribute 3 = Y
Search 2
-Attribute 2 = Z
所有这些结果都使用 Ajax 请求加载到我的页面。这里的问题是,如果用户想向某人显示搜索结果,他将无法执行此操作,因为 url 保持不变。
要解决此问题,我可能会使用 javascript 推送状态或替换状态: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 路由完成此操作的任何帮助?
由于我没有任何反馈,因此我不得不制定解决方法。以下是我如何设法完成我所要求的:
首先,而不是使用:
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'=> '/'
),
),
然后我创建了自己的 class,它扩展了 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'));