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

这两天看了看慕课网的 《从零打造自己的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 参数
第一步我们在上面已经做完了

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

<?php

namespace 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的时候将用户第一个斜杠之后的参数存到 controller action 中

我们的路由就弄好了!

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值