【基础】【后台】 微信小程序 - 腾讯云 - wafer2 - PHP - DEMO - 003 - 源码分析 - 02 - 路由

版权声明:本文为博主原创文章,未经博主允许不得转载。如需转载,联系作者 https://blog.csdn.net/yellow_hill/article/details/81811493

本文原创,欢迎转载,但是,务必保持原文并且给出原文链接。

前言:

前一篇已经介绍了,整个wafer2的文件组织,这里结合文件组织,分析一下,微信后台采用的MVC的框架。

路由是服务器配置管理的重要方面:腾讯云的CodeIgniter 架构,让路由的方法也因由这个架构而方便起来。


1 原型框架分析

写在前面话:

CodeIgniter  的路由方法:如下,我copy这个链接的内容,做了一定修改。

http://codeigniter.org.cn/user_guide/tutorial/static_pages.html

这是一个纯CodeIgniter  的例子:

你要做的第一件事情是新建一个 控制器 来处理静态页面,控制器就是一个简单的类, 用来完成你的工作,它是你整个 Web 应用程序的 “粘合剂” 。

例如,当访问下面这个 URL 时:

http://example.com/news/latest/10

通过这个 URL 我们就可以推测出来,有一个叫做 "news" 的控制器,被调用的方法为 "latest" , 这个方法的作用应该是查询 10 条新闻条目并显示在页面上。在 MVC 模式里,你会经常看到下面 格式的 URL :

http://example.com/[controller-class]/[controller-method]/[arguments] //这就是标准的路由的格式

在正式环境下 URL 的格式可能会更复杂,但是现在,我们只需要关心这些就够了。

新建一个文件 application/controllers/Pages.php ,然后添加如下代码。

<?php
class Pages extends CI_Controller {

    public function view($page = 'home')
    {
    }
}

你刚刚创建了一个 Pages 类,有一个方法 view 并可接受一个 $page 参数。 Pages 类继承自 CI_Controller 类,这意味着它可以访问 CI_Controller 类( system/core/Controller.php )中定义的方法和变量。

控制器将会成为你的 Web 应用程序中的处理请求的核心,在关于 CodeIgniter 的技术讨论中,这有时候被称作 超级对象。和其他的 PHP 类一样,可以在  你的控制器中使用 $this 来访问它,通过 $this 你就可以加载类库、 视图、以及针对框架的一般性操作。

现在,你已经创建了你的第一个方法,是时候创建一些基本的页面模板了,我们将 新建两个视图(页面模板)分别作为我们的页脚和页头。

新建页头文件 application/views/templates/header.php 并添加以下代码:

<html>
    <head>
        <title>CodeIgniter Tutorial</title>
    </head>
    <body>

        <h1><?php echo $title; ?></h1>

页头包含了一些基本的 HTML 代码,用于显示页面的主视图之前的内容。 另外,它还打印出了 $title 变量,这个我们后面讲控制器的时候再讲。 现在,再新建个页脚文件 application/views/templates/footer.php ,然后添加以下代码:

        <em>&copy; 2015</em>
    </body>
</html>

在控制器中添加逻辑

你刚刚新建了一个控制器,里面有一个 view() 方法,这个方法接受一个参数 用于指定要加载的页面,静态页面模板位于 application/views/pages/ 目录。

在该目录中,再新建两个文件 home.php 和 about.php ,在每个文件里随便 写点东西然后保存它们。如果你没什么好写的,就写 "Hello World!" 吧。

为了加载这些页面,你需要先检查下请求的页面是否存在:

public function view($page = 'home')
{
  if ( ! file_exists(APPPATH.'views/pages/'.$page.'.php'))
    {
        // Whoops, we don't have a page for that!
        show_404();
    }

    $data['title'] = ucfirst($page); // Capitalize the first letter

    $this->load->view('templates/header', $data);
    $this->load->view('pages/'.$page, $data);
    $this->load->view('templates/footer', $data);
}

当请求的页面存在,将包括页面和页脚一起被加载并显示给用户,如果不存在, 会显示一个 "404 Page not found" 错误。

第一行检查页面是否存在,file_exists() 是个原生的 PHP 函数,用于检查某个 文件是否存在,show_404() 是个 CodeIgniter 内置的函数,用来显示一个默认的 错误页面。

在页头文件中,$title 变量用来自定义页面的标题,它是在这个方法中赋值的, 但是注意的是并不是直接赋值给 title 变量,而是赋值给一个 $data 数组的 title 元素。

最后要做的是按顺序加载所需的视图,view() 方法的第二个参数用于向视图传递参数, $data 数组中的每一项将被赋值给一个变量,这个变量的名字就是数组的键值。 所以控制器中 $data['title'] 的值,就等于视图中的 $title 的值。

路由

控制器现在开始工作了!在你的浏览器中输入 [your-site-url]index.php/pages/view 来查看你的页面。当你访问 index.php/pages/view/about 时你将看到 about 页面, 包括页头和页脚。

使用自定义的路由规则,你可以将任意的 URI 映射到任意的控制器和方法上,从而打破 默认的规则:

http://example.com/[controller-class]/[controller-method]/[arguments]

让我们来试试。打开文件 application/config/routes.php 然后添加如下两行代码, 并删除掉其他对 $route 数组赋值的代码。

$route['default_controller'] = 'pages/view';
$route['(:any)'] = 'pages/view/$1';

CodeIgniter 从上到下读取路由规则并将请求映射到第一个匹配的规则,每一个规则都是 一个正则表达式(左侧)映射到 一个控制器和方法(右侧)。当有请求到来时,CodeIgniter 首先查找能匹配的第一条规则,然后调用相应的控制器和方法,可能还带有参数。

你可以在关于 URI 路由的文档 中找到更多信息。

这里,第二条规则中 $routes 数组使用了通配符 (:any) 可以匹配所有的请求, 然后将参数传递给 Pages 类的 view() 方法。


URI 路由

一般情况下,一个 URL 字符串和它对应的控制器中类和方法是一一对应的关系。 URL 中的每一段通常遵循下面的规则:

example.com/class/function/id/

但是有时候,你可能想改变这种映射关系,调用一个不同的类和方法,而不是 URL 中对应的那样。

例如,假设你希望你的 URL 变成下面这样:

example.com/product/1/
example.com/product/2/
example.com/product/3/
example.com/product/4/

URL 的第二段通常表示方法的名称,但在上面的例子中,第二段是一个商品 ID , 为了实现这一点,CodeIgniter 允许你重新定义 URL 的处理流程。

设置你自己的路由规则

路由规则定义在 application/config/routes.php 文件中,在这个文件中你会 发现一个名为 $route 的数组,利用它你可以设置你自己的路由规则。 在路由规则中你可以使用通配符或正则表达式。

通配符

一个典型的使用通配符的路由规则如下:

$route['product/:num'] = 'catalog/product_lookup';

在一个路由规则中,数组的键表示要匹配的 URI ,而数组的值表示要重定向的位置。 上面的例子中,如果 URL 的第一段是字符串 "product" ,第二段是个数字,那么, 将调用 "catalog" 类的 "product_lookup" 方法。

你可以使用纯字符串匹配,或者使用下面两种通配符:

(:num) 匹配只含有数字的一段。 (:any) 匹配含有任意字符的一段。(除了 '/' 字符,因为它是段与段之间的分隔符)

注解

通配符实际上是正则表达式的别名,:any 会被转换为 [^/]+ , :num 会被转换为 [0-9]+ 。

注解

路由规则将按照它们定义的顺序执行,前面的规则优先级高于后面的规则。

注解

路由规则并不是过滤器!设置一个这样的路由:'foo/bar/(:num)' , Foo 控制器的 bar 方法还是有可能会通过一个非数字的参数被调用 (如果这个路由也是合法的话)。

例子

这里是一些路由的例子:

$route['journals'] = 'blogs';

URL 的第一段是单词 "journals" 时,将重定向到 "blogs" 类。

$route['blog/joe'] = 'blogs/users/34';

URL 包含 blog/joe 的话,将重定向到 "blogs" 类和 "users" 方法。ID 参数设为 "34" 。

$route['product/(:any)'] = 'catalog/product_lookup';

URL 的第一段是 "product" ,第二段是任意字符时,将重定向到 "catalog" 类的 "product_lookup" 方法。

$route['product/(:num)'] = 'catalog/product_lookup_by_id/$1';

URL 的第一段是 "product" ,第二段是数字时,将重定向到 "catalog" 类的 "product_lookup_by_id" 方法,并将第二段的数字作为参数传递给它。

重要

不要在前面或后面加反斜线('/')。

正则表达式

如果你喜欢,你可以在路由规则中使用正则表达式。任何有效的正则表达式都是 允许的,包括逆向引用。

注解

如果你使用逆向引用,你需要使用美元符号代替双斜线语法。


一个典型的使用正则表达式的路由规则看起来像下面这样:

$route['products/([a-z]+)/(\d+)'] = '$1/id_$2';

说明:

([a-z]+) 表示 a ~ z的字符,作为参数$1的输入参数。

\d 表示截取该段所有的数字,作为参数$2的输入参数。

上例中,一个类似于 products/shirts/123 这样的 URL 将会重定向到 "shirts" 控制器的 "id_123" 方法。


With regular expressions, you can also catch multiple segments at once.

例如,当一个用户访问你的 Web 应用中的某个受密码保护的页面时,如果他没有 登陆,会先跳转到登陆页面,你希望在他们在成功登陆后重定向回刚才那个页面, 那么这个例子会很有用:

$route['login/(.+)'] = 'auth/login/$1';

注解

In the above example, if the $1 placeholder contains a slash, it will still be split into multiple parameters when passed to Auth::login().

如果你还不知道正则表达式,可以访问 regular-expressions.info 开始学习一下。

注解

你也可以在你的路由规则中混用通配符和正则表达式。

回调函数

你可以在路由规则中使用回调函数来处理逆向引用。例如:

$route['products/([a-zA-Z]+)/edit/(\d+)'] = function ($product_type, $id)
{
    return 'catalog/product_edit/' . strtolower($product_type) . '/' . $id;
};

在路由中使用 HTTP 动词

还可以在你的路由规则中使用 HTTP 动词(请求方法),当你在创建 RESTful 应用时特别有用。 你可以使用标准的 HTTP 动词(GET、PUT、POST、DELETE、PATCH),也可以使用自定义的动词 (例如:PURGE),不区分大小写。你需要做的就是在路由数组后面再加一个键,键名为 HTTP 动词。例如:

$route['products']['put'] = 'product/insert';

上例中,当发送 PUT 请求到 "products" 这个 URI 时,将会调用 Product::insert() 方法。

$route['products/(:num)']['DELETE'] = 'product/delete/$1';

当发送 DELETE 请求到第一段为 "products" ,第二段为数字这个 URL时,将会调用 Product::delete() 方法,并将数字作为第一个参数。

当然,使用 HTTP 动词是可选的。

保留路由

有下面三个保留路由:

$route['default_controller'] = 'welcome';

This route points to the action that should be executed if the URI contains no data, which will be the case when people load your root URL. The setting accepts a controller/method value and index() would be the default method if you don't specify one. In the above example, it is Welcome::index() that would be called.

注解

You can NOT use a directory as a part of this setting!

You are encouraged to always have a default route as otherwise a 404 page will appear by default.

$route['404_override'] = '';

这个路由表示当用户请求了一个不存在的页面时该加载哪个控制器,它将会覆盖默认的 404 错误页面。Same per-directory rules as with 'default_controller' apply here as well. show_404() 函数不会受影响,它还是会继续加载 application/views/errors/ 目录下的默认的 error_404.php 文件。

$route['translate_uri_dashes'] = FALSE;

从它的布尔值就能看出来这其实并不是一个路由,这个选项可以自动的将 URL 中的控制器和方法中的连字符('-')转换为下划线('_'),当你需要这样时, 它可以让你少写很多路由规则。由于连字符不是一个有效的类名或方法名, 如果你不使用它的话,将会引起一个严重错误。


1 Demo 给出的4个路由

// 首页指引
/ => application/controllers/Welcome.php

// 登录
/login => application/controllers/Login.php

// 获取微信用户信息
/user => application/controllers/User.php

// 处理信道请求
/tunnel => application/controllers/Tunnel.php
```

## 如果在demo基础上开发
将自己开发的接口放到如下目录下即可生效
/data/release/php-weapp-demo/application/controllers/

http://codeigniter.org.cn/user_guide/tutorial/static_pages.html


参考:

1 RESTful API 设计指南

http://www.ruanyifeng.com/blog/2014/05/restful_api.html

2 URI 路由

http://codeigniter.org.cn/user_guide/general/routing.html

猜你喜欢

转载自blog.csdn.net/yellow_hill/article/details/81811493
今日推荐