对框架的理解

原创 2018-12-22 17:52:38 258
摘要:1、全局配置文件(使用数组返回)     return [     //应用配置     'app'=>[         //调试开关   &n
1、全局配置文件(使用数组返回)
    return [

    //应用配置
    'app'=>[
        //调试开关
        'debug'=>true,
    ],

    //路由配置
    'route'=>[
        //默认模块
        'module'=>'admin',

        //默认控制器
         'controller'=>'Index',

        //默认操作
          'action' => 'index',
    ],

    //数据库配置
    'db'=>[
        //数据库类型
        'database_type'=>'mysql',

        //默认的数据库名称
        'database_name'=>'frame',

        //默认的主机名
        'server' => '127.0.0.1',

        //默认的用户名
        'username' => 'root',

        //用户密码
        'password' => '123456',

        //默认客户端的字符编码集
        'charset' => 'utf8',

        //默认服务端口号
        'port' => 3306,

    ],
];

2、还需要一个vendor目录,他包含着包依赖工具Composer,数据库框架Medoo。
3、路由解析类:①路由解析②请求分发
    //解析路由
public function parse($queryStr='')
{
    //第一步:将查询字符串前后的'/'去掉,然后再按分隔符'/'拆分到数组中
    //统一处理变为小写,处理简洁
    $queryStr = trim(strtolower($queryStr),'/');
    //把字符串打散为数组
    $queryArr = explode('/',$queryStr);
    //第二步:解析出$queryArr数组中的内容(模块,控制器,操作,参数)
     switch(count($queryArr))
     {
         //没有参数,则使用默认的模块、控制器、操作
         case 0:
             $this->pathInfo = $this->route;
             break;
         //只有一个参数,除模块外,控制器和操作使用默认值
         case 1:
             $this->pathInfo['module'] = $queryArr[0];
             break;
         //二个参数,模块和控制器自定义,操作默认
         case 2:
             $this->pathInfo['module'] = $queryArr[0];
             $this->pathInfo['controller'] = $queryArr[1];
             break;
         //三个参数, 模块/控制器/操作全部自定义
         case 3:
             $this->pathInfo['module'] = $queryArr[0];
             $this->pathInfo['controller'] = $queryArr[1];
             $this->pathInfo['action'] = $queryArr[2];
             break;
         //默认情况,对参数进行处理
         default:
             $this->pathInfo['module'] = $queryArr[0];
             $this->pathInfo['controller'] = $queryArr[1];
             $this->pathInfo['action'] = $queryArr[2];
                 //从pathInfo数组的索引3,即第4个元素起,将剩余元素全部做为操作的参数获取
             $arr = array_slice($queryArr,3);
             //键值对必须成对出现,所以每次必须递增2
             for($i=0;$i<count($arr);$i+=2)
             {
                 //如果没有第二个参数,则放弃,确保键值一一对应
                 if(isset($arr[$i+1]))
                 {
                    $this->params[$arr[$i]] = $arr[$i+1];
                 }
             }
             break;
     }
     //返回当前类的实例,这样就可以实现链式调用,即直接用->调用另一方法,省去重复写对象
     return $this;
}
    ②请求分发
    public function dispatch()
{
    //生成的带有命名空间的控制器类名称:app\模块\controller\控制器类
    //类名称应该与类文件所在的绝对路径一一对应,这样才可以实现自动映射,方便自动加载
    //模块名称
    $module = $this->pathInfo['module'];
    //控制器名称
    $controller = 'app\\' .$module .'\controller\\'. ucfirst($this->pathInfo['controller']);
    //操作名
    $action = $this->pathInfo['action'];
    //判断当前类中是否存在指定的操作,如果没有,就执行默认的操作方法
    if(!method_exists($controller,$action))
    {
        $action = $this->route['action'];
        echo '没有该方法';
        header('Location:/');
    }
    //将用户的请求分发到指定的控制器和对应的操作方法上
    return call_user_func_array([new $controller,$action],$this->params);
}

4、框架基础类:1.调试模式,2.自动加载,3.启动框架
    //设置调试模式
public function setDebug()
{
    //debug == true
    if($this->config['app']['debug'])
    {
        error_reporting(E_ALL);
        ini_set('display_errors','On');
    }
    else
    {
        //error_reporting(E_ALL);
        ini_set('display_errors','Off');
        ini_set('log_errors','On');
    }
}
//注册自动加载器:自动加载的是类
public function loader($class)
{
    $path = ROOT_PATH.str_replace('\\','/',$class).'.php';

    //如果没有找到类文件,就直接返回默认首页
    if(!file_exists($path))
    {
        header('Location: /');
    }

    require $path;
}
//启动框架
public function run()
{
    //调试模式
    $this->setDebug();

    //自动加载
    spl_autoload_register([$this,'loader']);

    //请求分发
    echo (new Route($this->config['route']))->parse($this->queryStr)->dispatch();
}

5、框架的控制器基类(主要是创建视图对象)
namespace pig\core;

class Controller
{
    //视图对象
    protected $view = null;

    //构造方法:实例化视图类
    public function __construct()
    {
        $this->view = new namespace\View();
        //配置模板引擎
        $this->config();
    }

    //视图模板引擎配置
    public function config()
    {
        //设置模板目录名称[可选]
        $this->view->setDirectory(ROOT_PATH.'/app/admin/view');

        //设置模板目录别名:命名空间
        $this->view->addFolder('admin',ROOT_PATH.'/app/admin/view');

        //设置前台目录名称[可选]
        $this->view->setDirectory(ROOT_PATH.'/app/home/view');

        //设置前台模板目录别名:命名空间
        $this->view->addFolder('home',ROOT_PATH.'/app/home/view');
    }

    //任何模板引擎都有两个核心的功能
    //1、模板赋值  2、渲染模板
    //1、模板赋值
    public function assign($name,$value)
    {
        $this->data[$name] = $value;
    }

    //2、渲染模板
    public function fetch($file)
    {
        //1、将容器数组中的元素(键值对)转化为变量
        // $data['price'] = 1000 ,  目标:$price = 1000
        // $data['arr'] = [1,2,3]   目标:$arr=[1,2,3]
        //将数组的键值对转为变量的名值对的过程,返回变量个数
        extract($this->data);

        //2、加载模板文件
        if(file_exists($file) && is_file($file))
        {
            require $file;
        }

    }
}

6、框架的视图基类(使用第三方的一个基于原生php的模板引擎:Plates)
    namespace pig\core;
use League\Plates\Engine;

class View  extends Engine
{
   //变量容器
   protected $data = [];

   //构造方法
    /**
     * View constructor.
     * @param null $directory 模板默认目录
     * @param string $fileExtension 模板默认扩展名:php
     */
    public function  __construct($directory = null, $fileExtension = 'php')
    {
        parent::__construct($directory, $fileExtension);
    }
}

7、框架的模型基类(采用Medoo作为数据库管理的框架)
   namespace pig\core;

//引入Medoo框架类的命名空间
use Medoo\Medoo;

class Model extends Medoo
{
    public function __construct($options=null)
    {
        //导入配置文件
        $config = require __DIR__.'/../config.php';
        $options = $config['db'];

        //实例化数据库框架Medoo
        parent::__construct($options);
    }
}

8、app下面的admin、home、model分别对应Controller,View,Model


批改老师:天蓬老师批改时间:2018-12-22 18:31:17
老师总结:你把课堂源码抄一份发上来了, 不知你是否理解了原理?

发布手记

热门词条