迷你框架的建立

Original 2019-03-20 21:45:15 402
abstract:<?php /**  * 路由解析类  * 1.路由解析  * 2.请求分发  */ namespace pig; class Route {    //路由信     protected $route =&nbs
<?php
/**
 * 路由解析类
 * 1.路由解析
 * 2.请求分发
 */
namespace pig;
class Route
{
   //路由信
    protected $route = [];
    //pathinfo
    //public $pathInfo = [];
    protected $pathInfo = [];
    //URL参数
    //public $params = [];
    protected $params = [];
    //构造方法
    public function __construct($route)
    {
        $this->route = $route;
    }
    //解析路由
    public function parse($queryStr='')
    {
        /**
         *   /admin/user/add/name/peter/age/30
         *   $this->pathInfo=['module'=>'admin','controller'=>'user','action'=>'add']
         *   参数数组:$this->params = ['name'=>'peter','age'=>30]
         */
        //第一步:将查询字符串前后的/去掉,再按分隔符/拆分到数组中
        $queryStr = trim(strtolower($queryStr),'/');
        $queryArr = explode('/',$queryStr);//拆分成数组
        //$queryArr = array_filter($queryArr);
        //第二步:解析出$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开始,将剩余的元素全部作为参数进行处理
                $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;
        }
        //返回当前路由类的实例对象,主要是方便链式调用:
        //$route->parse();$route->worm();$route->print()
        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'];
            header('location: /');
        }
        //将用户的请求分发到指定的控制器和操作方法上
        return call_user_func_array([new $controller,$action],$this->params);
    }
    //获取pathinfo
    public function getPathInfo()
    {
        return $this->pathInfo;
    }
    //获取模块
    public function getModule()
    {
        return $this->pathInfo['module'] ? : $this->route['module'];
    }
    //获取控制器名称
    public function getController()
    {
        return 'app\\'.$this->getModule().'\controller\\'.ucfirst($this->pathInfo['controller']);
    }
}
/*//测试路由
$queryStr = $_SERVER['QUERY_STRING'];
echo $queryStr;
echo '<hr>';
echo '<pre>';
print_r(explode('/',$queryStr));
$config = require 'config.php';
$route = new Route($config['route']);
$route->parse($queryStr);
/*print_r($route->pathInfo);
print_r($route->params);
//测试请求分发
require __DIR__.'/../app/admin/controller/Index.php';
echo $route->dispatch();*/
<?php
/**
 * 框架基础类
 * 1.调试模式
 * 2.自动加载
 * 3.启动框架
 */
namespace pig;
class Base
{
    //框架配置
    protected $config = [];
    //路由信息
    protected $queryStr = '';
    //构造方法
    public function __construct($config,$queryStr='')
    {
        $this->config = $config;
        $this->queryStr = $queryStr;
    }
    //设置调试模式
    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)
    {
        //new \app\admin\controller\Stu(),  app/admin/controller/Stu.pho
        $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();
    }
}
<?php
/**
 * 配置文件:适用于整个应用
 * 采用PHP数组方式返回数据
 */
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' =>'root',
        //默认的客户端的字符集编码
        'charset' => 'utf8',
        //默认服务端口号
        'port' => 3306,
    ]
];

框架的核心文件:框架的配置文件(以数组的形式完成整个应用的配置,路由,数据库等),路由类(路由解析和请求分发)和基础类(调试模式,自动加载和启动框架)文件,还有入口文件(定义常量,加载函数库,启动框架,使启动框架有统一的入口),还有创建框架的模型基类(实例化数据库框架),视图基类(实例化视图模型),控制器基类(实现模板引擎的配置,模板赋值(将参数保存在数组)和模板渲染(将数组键值对转换为变量的名值对,然后加载模板文件)。至此,一个小型的框架就完成,然后就可以建立自己的项目啦。学完这章,对框架的整体建立和运行过程有一个基本的认识,懂得其中的原理,为学习其他框架提供了基础。至此,php基础也学完了,学到了很多东西,感谢老师的辛苦讲解和付出,为我以后的php道路打下了扎实的基础。有老师陪伴,学习的时间真的很开心,很充实。


Correcting teacher:灭绝师太Correction time:2019-03-21 09:08:24
Teacher's summary:希望你们通过自己的努力,都成为行业佼佼者,前路还长,继续加油!

Release Notes

Popular Entries