框架入门 基础篇 (上)入口文件,自动加载,路由

来源:互联网 发布:网络上的占豪是谁啊 编辑:程序博客网 时间:2024/06/10 04:29

这两天看了看慕课网的 《从零打造自己的MVC矿建》 感觉很有收获

做点总结

首先是框架运行原理:

一个框架 进入入口文件后 首先它会定义一些常量 ,然后加载核心类库,启动框架

接下来路由类会根据一定的规则去解析用户输入的路由 找到对应的控制器 把控制器加载进来 去调用模型 把结果响应到视图

那么入口文件是干什么的呢

<?php/** * 1.入口文件 * 2.定义常量 * 3.加载函数库 * 4.启动框架 */header("content-type:text/html;charset=utf-8");define('IMOOC', realpath(''));define('CORE', IMOOC.'/core');define('APP', IMOOC.'/application');define('MODULE', 'application');define('DEBUG', true);if (DEBUG) {    ini_set('display_error', 'On');}else{    ini_set('display_error', 'Off');}include CORE.'/common/function.php';include CORE.'/imooc.php';spl_autoload_register('\core\imooc::load');\core\imooc::run();

通过上面代码我们看到: 入口文件 一般来说
首先会定义一些框架中需要用到的常量 :例如文件夹路径 、系统设计模式等等
接下来 会加载核心类库
最后去运行核心类库中运行框架的方法

说到加载类库 就不得不提到自动加载了 这是一个框架的灵魂
他需要用到一个函数

spl_autoload_register('\core\imooc::load');

在了解这个函数之前先来看另一个函数:__autoload。

一、__autoload

这是一个自动加载函数,在PHP5中,当我们实例化一个未定义的类时,就会触发此函数。看下面例子:

printit.class.php <?php class PRINTIT {  function doPrint() {  echo 'hello world'; }}?> index.php <?function __autoload( $class ) { $file = $class . '.class.php';   if ( is_file($file) ) {    require_once($file);   }} $obj = new PRINTIT();$obj->doPrint();?>

运行index.PHP后正常输出hello world。在index.php中,由于没有包含printit.class.php,在实例化printit时,自动调用__autoload函数,参数$class的值即为类名printit,此时printit.class.php就被引进来了。

在面向对象中这种方法经常使用,可以避免书写过多的引用文件,同时也使整个系统更加灵活。

二、spl_autoload_register()

再看spl_autoload_register(),这个函数与__autoload有与曲同工之妙,看个简单的例子:

<?function loadprint( $class ) { $file = $class . '.class.php';   if (is_file($file)) {    require_once($file);   } } spl_autoload_register( 'loadprint' ); $obj = new PRINTIT();$obj->doPrint();?>

将__autoload换成loadprint函数。但是loadprint不会像__autoload自动触发,这时spl_autoload_register()就起作用了,它告诉PHP碰到没有定义的类就执行loadprint()。

spl_autoload_register() 调用静态方法

<? class test { public static function loadprint( $class ) {  $file = $class . '.class.php';    if (is_file($file)) {     require_once($file);    }  }} spl_autoload_register(  array('test','loadprint')  );//另一种写法:spl_autoload_register(  "test::loadprint"  ); $obj = new PRINTIT();$obj->doPrint();?>

是不是很神奇

那么看看我的 \core\imooc::load 到底干了些什么

public static $classMap = array();public static function load($class)    {        //自动加载类库        //检测类是否已经被加载        if(isset($classMap[$class])) {            return true;        } else {            $class = str_replace('\\', '/', $class);            $file = IMOOC.'/'.$class.'.php';            if(is_file($file)) {                include $file;                self::$classMap[$class] = $class;            } else {                return false;            }        }    }

为了考虑性能 首先检测了类库是不是已经加载过了
如果没有加载过
那么 include 类库
是不是也很简单

接下来我们该分配路由了

我的是LAMP环境
apache路由规则重写模块已经加载过了
直接在项目根目录 新建一个 .htaccess文件

<IfModule mod_rewrite.c>    RewriteEngine on    RewriteCond %{REQUEST_FILENAME} !-f    RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]</IfModule>

这样我们用户的所有请求都会重定向加上index.php
用户输入的url是这样的:
www.imooc.com/index/index
实际访问的页面是这样的
www.imooc.com/index.php/index/index

然后我们的路由要干几件事

1.隐藏index.php
2.获取url 参数部分
3.返回对应的控制器和方法
4.将多余的参数转化为$_GET 参数
第一步我们在上面已经做完了

接下类我们完成下面的几步

<?phpnamespace core\lib;class route{    public $controller;    public $action;    public function __construct()    {        // xxx.com/index/index        /**         * 1.隐藏index.php         * 2.获取url 参数部分         * 3.返回对应的控制器和方法         */        if(isset($_SERVER['REQUEST_URI']) && $_SERVER['REQUEST_URI'] != '/')        {            $path = $_SERVER['REQUEST_URI'];            $patharr = explode('/', trim($path, '/'));            if(isset($patharr[0])){                $this->controller = $patharr[0];                unset($patharr[0]);            }            if(isset($patharr[1])){                $this->action = $patharr[1];                unset($patharr[1]);            }else{                $this->action = 'index';            }            //url多余部分转化为GET参数            //a/1/b/2/c/3            $count = count($patharr) + 2;            $i = 2;            while ($i < $count) {                if(isset($patharr[$i + 1]))                {                    $_GET[$patharr[$i]] = $patharr[$i + 1];                }                $i += 2 ;            }        }        else        {            $this->controller = 'index';            $this->action = 'index';        }    }}

这样我们就在用户输入url的时候将用户第一个斜杠之后的参数存到controlleraction 中

我们的路由就弄好了!

下一章 :框架入门 基础篇(下)MVC

0 0
原创粉丝点击