摘要:<?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
//如果没有第二个参数,则放弃
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 '
';
echo '
';
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道路打下了扎实的基础。有老师陪伴,学习的时间真的很开心,很充实。
批改老师:灭绝师太批改时间:2019-03-21 09:08:24
老师总结:希望你们通过自己的努力,都成为行业佼佼者,前路还长,继续加油!