laravel的路由模块就是从这里封装起来的,咱们先了解下symfony的路由机制

使用注释定义一个路由

symfony 的强大之处在于代码中的注释都参与到程序运行当中,这样强制的规范了注释排版,比如

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class LuckyController extends Controller
{
    /**
     * @Route("/lucky/number")
     */
    public function numberAction()
    {
        $numbers = mt_rand(1,999);

        return new Response($numbers);
    }
}

当输入 http://domain/app_dev.php/lucky/number 将会返回方法中的随机数

使用配置文件定义一个路由推荐这种写法,方便他人维护

@app/config/routing.yml文件中,定义一个blog_show路由

1
2
3
blog_show:
    path:      /blog/{slug}
    defaults:  { _controller: AppBundle:Lucky:show ,slug:2333}

这里还有 {slug} 奇怪的写法,这代表着路由中传入 slug的自定义参数,从laravel过来的同学一定不会陌生

defaults 下指定了该路由指向哪个控制器,同时 slug 也有了默认值,在控制器中就是这样写:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// src: @src/AppBundle/LuckyController
public function showAction($slug){
        $str = 'this is blog-'.$slug;

        return new Response($str);
}

#注释的写法就是
/**
 * @Route("/blog/{slug}", defaults={"slug" = 1})
 */

高级路由示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# in Controller
/**
 * @Route(
 *     "/articles/{_locale}/{year}/{title}.{_format}",
 *     defaults={"_format": "html"},
 *     requirements={
 *         "_locale": "en|fr",
 *         "_format": "html|rss",
 *         "year": "\d+"
 *     }
 * )
 */
public function showAction($_locale, $year, $title)
{
}

# in yaml
# app/config/routing.yml
article_show:
  path:     /articles/{_locale}/{year}/{title}.{_format}
  defaults: { _controller: AppBundle:Article:show, _format: html }
  requirements:
      _locale:  en|fr
      _format:  html|rss
      year:     \d+

这里对参数进行了正则筛选,如果不复合条件的也将报 404 错误

新出现的 requirements 部分就是对指定的参数筛分,使用的是正则的格式

在程序中生成路由和解析路由

路由在系统中是双向映射,既能生成带参数的路由,又能反向解析成运行的函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$params = $this->get('router')->match('/blog/my-blog-post');
dump($params);
// array(
//     'slug'        => 'my-blog-post',
//     '_controller' => 'AppBundle:Blog:show',
// )

$uri = $this->get('router')->generate('blog_show', array(
    'slug' => 'my-blog-post'
));
dump($uri);
// /blog/my-blog-post

generate 方法中,如果添加了路由中没设置的参数比如

1
2
3
4
5
6
$uri = $this->get('router')->generate('blog_show', array(
    'slug' => 'my-blog-post',
    'author' => 'jack',
    'type' => 'markdown'
));
// /blog/my-blog-post?author=jack&type=markdown

会以 Query Strings 的形式添加到地址中

现在生成的是相对路径,如果是全路径的话需要加一个参数

1
2
3
4
5
$uri = $this->get('router')->generate('blog_show', array(
    'slug' => 'my-blog-post',
    'author' => 'jack',
    'type' => 'markdown'
),UrlGenerator::ABSOLUTE_URL);

UrlGenerator::ABSOLUTE_URL 这个参数也可以替换成 0