1. 云栖社区>
  2. PHP教程>
  3. 正文

一步一步重写 CodeIgniter 框架 (3) —— 用面向对象重构代码

作者:用户 来源:互联网 时间:2017-12-01 09:51:50

框架对象代码codeigniter重构重写面向

一步一步重写 CodeIgniter 框架 (3) —— 用面向对象重构代码 - 摘要: 本文讲的是一步一步重写 CodeIgniter 框架 (3) —— 用面向对象重构代码, 前面两篇文章为了重点突出 CodeIgniter 框架的原理,程序的结构很乱,有很多全局变量,在这一课中我们采用面向对象的方法对原先代码进行重构。 到目前为止,程序主要完成的就是 URL 分析,并根据配置文件进行路由转换,也就是说我们这里

前面两篇文章为了重点突出 CodeIgniter 框架的原理,程序的结构很乱,有很多全局变量,在这一课中我们采用面向对象的方法对原先代码进行重构。


到目前为止,程序主要完成的就是 URL 分析,并根据配置文件进行路由转换,也就是说我们这里有两个对象,分别处理 URL 分析和路由转换。


1. URL 分析


URL 分析最主要的两个函数是 detect_uri 和 explode_uri ,考虑到 路由的需要,URL 类包含的成员变量有


segments 数组 原始URL的分段信息


rsegments 数组 经过路由后的分段信息


uri_string URL的路径信息,也就是 index.php 之后的路径


由上述分析及参考上一节的代码:


一步一步重写 CodeIgniter 框架 (3) —— 用面向对象重构代码


1 <?php
2
3 /**
4* URI Class
5*
6* 分析 URI, 并决定路由
7*/
8
9 class CI_URI {
10
11 var $segments = array();
12
13 var $uri_string;
14
15 var $rsegments;
16
17 function fetch_uri_string() {
18if ($uri = $this->detect_uri()) {
19$this->set_uri_string($uri);
20return;
21}
22
23 }
24
25 /**
26* Set
27* @param [type] $str [description]
28*/
29 function set_uri_string($str) {
30$this->uri_string = ($str == '/') ? '' : $str;
31 }
32
33
34 /**
35* --------------------------------------------------------------------
36* 获取 uri ,并通过 uri 调用相应的方法
37* --------------------------------------------------------------------
38*/
39
40 function detect_uri() {
41
42if ( ! isset($_SERVER['REQUEST_URI']) OR ! isset($_SERVER['SCRIPT_NAME'])) {
43return '';
44}
45
46$uri = $_SERVER['REQUEST_URI'];
47if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0) {
48$uri = substr($uri, strlen($_SERVER['SCRIPT_NAME']));
49}
50
51if ($uri == '/' || empty($uri)) {
52return '/';
53}
54
55$uri = parse_url($uri, PHP_URL_PATH);
56
57// 将路径中的 '//' 或 '../' 等进行清理
58return str_replace(array('//', '../'), '/', trim($uri, '/'));
59 }
60
61
62
63 function explode_uri() {
64
65foreach (explode('/', preg_replace("|/*(.+?)/*$|", "//1", $this->uri_string)) as $val) {
66$val = trim($val);
67if ($val != '') {
68 $this->segments[] = $val;
69}
70}
71 }
72
73 }

一步一步重写 CodeIgniter 框架 (3) —— 用面向对象重构代码


2. Router 路由类


路由类起的作用就是一个路由转换 set_routing ,并提供给外界获取转换后路由的接口如 fetch_class, fetch_method 等, 根据前面两篇的代码和思路,很容易写出如下的 Router 类。


其中最关键的就是 set_routing 函数,它被入口文件 index.php 执行,通过 URI 类分析获得 分段信息,并根据分析后的结果,获得转换后的路由,设置 class 和 method。


一步一步重写 CodeIgniter 框架 (3) —— 用面向对象重构代码


1 <?php
2
3 class CI_Router {
4
5 var $uri;
6
7 var $routes;
8
9 var $class;
10
11 var $method;
12
13 var $default_controller;
14
15 function __construct() {
16global $URI;
17
18$this->uri = &$URI;
19 }
20
21 function set_routing() {
22
23if (is_file('routes.php')) {
24include('routes.php');
25}
26
27$this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route;
28unset($route);
29
30$this->default_controller = ( ! isset($this->routes['default_controller']) OR $this->routes['default_controller'] == '') ? FALSE : $this->routes['default_controller'];
31
32$this->uri->fetch_uri_string();
33
34if ($this->uri->uri_string == '') {
35return $this->set_default_controller();
36}
37
38$this->uri->explode_uri();
39
40$this->parse_routes();
41 }
42
43
44 function set_default_controller() {
45
46 }
47
48 function parse_routes() {
49$uri = implode('/', $this->uri->segments);
50
51if (isset($this->routes[$uri])) {
52$rsegments = explode('/', $this->routes[$uri]);
53
54return $this->set_request($rsegments);
55}
56 }
57
58 function set_request($segments = array()) {
59
60if (count($segments) == 0) {
61return $this->set_default_controller();
62}
63
64$this->set_class($segments[0]);
65
66if (isset($segments[1])) {
67$this->set_method($segments[1]);
68} else {
69$method = 'index';
70}
71
72$this->uri->rsegments = $segments;
73 }
74
75 function set_class($class) {
76$this->class = str_replace(array('/', '.'), '', $class);
77 }
78
79 /**
80* Set the method
81*
82* @param string $method the method to execute
83*/
84 function set_method($method) {
85$this->method = $method;
86 }
87
88 /**
89* Fetch the class
90*
91* @return string the class
92*/
93 function fetch_class() {
94return $this->class;
95 }
96
97 /**
98* Fetch the method
99*
100* @return string the method
101*/
102 function fetch_method() {
103return $this->method;
104 }
105 }

一步一步重写 CodeIgniter 框架 (3) —— 用面向对象重构代码


3. 主入口文件逻辑


使用面向对象重构后,主入口文件只需要创建它们的实例,通过调用它们的方法,即可以处理最重要的工作,然后通过调用 call_user_fun_array 来执行。


一步一步重写 CodeIgniter 框架 (3) —— 用面向对象重构代码


1 <?php
2 /**
3* 框架主入口文件,所有的页面请求均定为到该页面,并根据 url 地址来确定调用合适的方法并显示输出
4*/
5 require 'Router.php';
6 require 'URI.php';
7
8
9 $URI = new CI_URI();
10
11 $RTR = new CI_Router();
12
13 $RTR->set_routing();
14
15
16 $class = $RTR->fetch_class();
17 $method = $RTR->fetch_method();
18
19 $CI = new $class();
20
21 call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));
22
23 class Welcome {
24
25 function hello() {
26echo 'My first Php Framework!';
27 }
28
29 function saysomething($str) {
30echo $str.", I'am the php framework you created!";
31 }
32 }

一步一步重写 CodeIgniter 框架 (3) —— 用面向对象重构代码


4. 测试


http://localhost/learn-ci/index.php/welcome/hello,可以看到与第二课一样的输出结果


hello, I'am the php framework you created!



以上是云栖社区小编为您精心准备的的内容,在云栖社区的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索框架 , 对象 , 代码 , codeigniter , 重构 , 重写 面向 ,以便于您获取更多的相关知识。