假设您创建了以下路线:
Router::connect('/projects/:id/quotations/:quotation_id/*',
array(
'controller' => 'quotations',
'action' => 'get_all_by_project', "[method]" => "GET"),
array(
'pass' => array('id', 'quotation_id'),
'id' => '[0-9]+',
'quotation_id' => '[0-9]+'
),
array(
'named' => array(
'name1',
'name2',
'name3'
)
)
);
在这条路线中:
- 传递的参数将是强制参数
id
,并quotation_id
服从作为第一个和第二个传递参数的顺序
- 命名参数将是可选参数
name1
、name2
和name3
。
- 当然,查询参数也是可选的,并且取决于您在 url 中实际拥有的内容。
- 您需要在末尾加上星号,以便命名参数可以通过
让我们假设以下相同动作的漂亮 url 和丑陋 url:
/projects/1/quotations/23/name2:value2/name3:value3/name1:value1?note=abc&test=123 (pretty)
/quotations/get_all_by_project/1/23/name2:value2/name3:value3/name1:value1?note=abc&test=123 (ugly)
答案的第一部分:
让我们只考虑删除查询参数note
的场景。
我们应该回去
/projects/1/quotations/23/name2:value2/name3:value3/name1:value1?test=123 (pretty)
/quotations/get_all_by_project/1/23/name2:value2/name3:value3/name1:value1?test=123 (ugly)
以下Component方法将起作用。我已经在丑陋和漂亮的网址上对其进行了测试。
public function removeQueryParameters($parameters, $here = '') {
if (empty($here)) {
$here = $this->controller->request->here;
}
$query = $this->controller->request->query;
$validQueryParameters = array();
foreach($query as $param=>$value) {
if (!in_array($param, $parameters)) {
$validQueryParameters[$param] = $value;
}
}
$queryString = $this->_reconstructQueryString($validQueryParameters);
return $here . $queryString;
}
protected function _reconstructQueryString($queryParameters = array()) {
$queryString = '';
foreach($queryParameters as $param => $value) {
$queryString .= $param . '=' . $value . '&';
}
if (strlen($queryString) > 0) {
$queryString = substr($queryString, 0, strlen($queryString) - 1);
$queryString = '?' . $queryString;
}
return $queryString;
}
这就是调用 Component 方法的方式。
$newUrl = $this->RequestExtrasHandler->removeQueryParameters(array('note'));
RequestExtrasHandler
是我编写的具有上述方法的组件的名称。
答案的第二部分:
让我们只考虑删除命名参数name2
的场景。
我们应该回去
/projects/1/quotations/23/name3:value3/name1:value1?test=123 (pretty)
/quotations/get_all_by_project/1/23/name3:value3/name1:value1?test=123 (ugly)
以下Component方法将起作用。我已经在丑陋和漂亮的网址上对其进行了测试。
public function removeNamedParameters($parameters, $here = '') {
if (empty($here)) {
$here = $this->controller->request->here;
}
$query = $this->controller->request->query;
$named = $this->controller->request->params['named'];
$newHere = $here;
foreach($named as $param=>$value) {
if (in_array($param, $parameters)) {
$namedString = $param . ':' . $value;
$newHere = str_replace($namedString, "", $newHere);
}
}
$queryString = $this->_reconstructQueryString($query);
return $newHere . $queryString;
}
这就是调用 Component 方法的方式。
$newUrl = $this->RequestExtrasHandler->removeNamedParameters(array('name2'));
RequestExtrasHandler
是我编写的具有上述方法的组件的名称。
答案第三部分:
当我意识到传递参数是强制性的之后,我发现没有真正的业务需要删除传递的参数。
另一个问题是,与命名参数和查询参数不同,传递的参数往往没有键存在于$this->controller->request->params['pass']
$this->controller->request->params['pass']
通常采用数字索引数组的形式。
因此,取出正确传递的参数是一个巨大的挑战。
因此,我不会创建任何方法来删除传递的参数。
详细查看这里的代码:
https://github.com/simkimsia/UtilityComponents/blob/d044da690c7b83c72a50ab97bfa1843c14355507/Controller/Component/RequestExtrasHandlerComponent.php#L89