2.3 重写规则

回忆一下,Solar的URI都是这种形式controller/action/param/param/param。例如,在博客演示应用中,读取一篇博文的URI是blog/read/1。正因为此,Solar才知道把URI请求路由于 "blog" 页面控制器,使用 "read"动作,并传递参数 "1"。

但是,如果你想识别不同于上面这种结构的URI怎么呢? 这时候动态重写规则就发挥作用了。你可以使用重定规则把输入的URI转化为Solar系统可以识别的那种。

有两种方式用于描述重写规则:一种是短格式,另一种是长格式。

2.3.1 短格式

在短格式中,重写规则表示为数组元素,数组元素的键是匹配输入URI的正则表达式。元素的值表明将如何重写匹配成功的URI。(这里的键和值是函数preg_replace()的前两个参数)

这里有一个示例配置文件的代码片断,在前端控制器中使用短格式重写规则

<?php
// "blog/88/edit" gets rewritten as "blog/edit/88"
$pattern = 'blog/(\d+)/edit';
$rewrite = 'blog/edit/$1';
$config['Solar_Controller_Front']['rewrite'][$pattern] = $rewrite;

2.3.2 替换标记

你也可以为正则表达式定义替换标记;这样的话,你可以预先定义一些正则表达式,而且以后可以重用它们并且可读性可好。前端控制器定义了一些替换标记,你也可以定义你自己的。

<?php
// Solar_Uri_Rewrite defines the following by default:
// '{:action}'     => '([a-z-]+)',
// '{:alpha}'      => '([a-zA-Z]+)',
// '{:alnum}'      => '([a-zA-Z0-9]+)',
// '{:controller}' => '([a-z-]+)',
// '{:digit}'      => '([0-9]+)',
// '{:param}'      => '([^/]+)',
// '{:params}'     => '(.*)',
// '{:slug}'       => '([a-zA-Z0-9-]+)',
// '{:word}'       => '([a-zA-Z0-9_]+)',

// you can add your own regex replacement strings as well
$config['Solar_Controller_Front']['replace'] = array(
    '{:product_slug}' => '(\d+\-[a-zA-Z]+)',
);

// "product/123-foobar/view" gets rewritten as "catalog/show-item/123-foobar"
$pattern = 'product/{:product_slug}/view';
$rewrite = 'catalog/show-item/$1';
$config['Solar_Controller_Front']['rewrite'][$pattern] = $rewrite;
[Note]Note

在短格式规则中,替换标记没有任何语义,也不是参数关键字。它们只是可读性好的替代字符串,从而可以让我们避免重复写那些难于记忆的正则表达式。

2.3.3 长格式

在长格式中,重写规则仍然表示为数组元素。但是,数组元素的键是规则名,元素的值是处理命令的子数组。我们称这种方式为“命名动作”或“命名规则”。(在其他框架中,这被称为“命名路由”)

<?php
$name = 'blog-edit';

$rule = array(
    'pattern' => 'blog/{:id}/edit', // the URI pattern to match
    'rewrite' => 'blog/edit/$1',    // rewrite the URI like this
    'replace' => array(             // custom replacement tokens
        '{:id}' => '(\d+)',
    ),
    'default' => array(
        'id' => '88',
    ),
);

$config['Solar_Controller_Front']['rewrite'][$name] = $rule;

在视图脚本中,你可以使用命名动作为你产生URI,而且还可带上参数。

<?php
// from inside a view script:
$name = 'blog-edit';
$data = array('id' => '70');
$text = 'Edit Blog Entry';
echo $this->namedAction($name, $data, $text);
// outputs <a href="/blog/70/edit">Edit Blog Entry</a>