thinkphp3.2是使用率非常普遍的国产php框架,以简单易于上手闻名,那么它框架结构是怎样的?
tp3.2设计简单来说就是CBD,core(框架核心文件),bebavior(行为,tp3.2一大特点就是钩子众多),driver(各种驱动,根据项目需要),针对这三大方面从源码来看框架的运行的原理。
因为tp3.2的古老,所以入口文件没有像5.0和其它主流框架那样做动静分离,index.php直接放在根目录下,打开index.php,里面有引入框架核心文件从而进入框架:
然后打开框架核心文件:
首先看到的是定义的一堆系统常量,包括规定了类名后缀必须是.class.php结尾,最后引入并且运行了框架应用,从这里框架逻辑正式开始。
接着,打开核心Think核心类,首先异常捕捉处理,
// 注册AUTOLOAD方法
spl_autoload_register('Think\Think::autoload');
// 设定错误和异常处理
register_shutdown_function('Think\Think::fatalError');
set_error_handler('Think\Think::appError');
set_exception_handler('Think\Think::appException');
register_shutdown_function,set_error_handler,set_exception_handler三段式,基本每个框架都会有。
接着是加载缓存文件
$runtimefile = RUNTIME_PATH.APP_MODE.'~runtime.php';,
tp里文件运行先以缓存临时文件为主。
接着是最关键的一步,引入框架核心文件
$mode = include is_file(CONF_PATH.'core.php')?CONF_PATH.'core.php':MODE_PATH.APP_MODE.'.php';
这里引入叫commom.php的文件,这里面是预先定义的一些需要框架加载时就引入的文件,驱动,行为,甚至核心文件都有。
不过在tp5和tp5.1这些核心文件都实现了依赖注册函数的惰性加载,性能有所提升。
然后是注册函数加载不需要初始化的文件,比如model,controller,部分驱动,这些文件可以在实例化的加载。
然后运行应用:
// 运行应用
App::run();
接着,打开应用程序类, 查看执行应用过程管理,
首先是对http请求方式进行处理,过滤
define('NOW_TIME', $_SERVER['REQUEST_TIME']);
define('REQUEST_METHOD',$_SERVER['REQUEST_METHOD']);
define('IS_GET', REQUEST_METHOD =='GET' ? true : false);
define('IS_POST', REQUEST_METHOD =='POST' ? true : false);
define('IS_PUT', REQUEST_METHOD =='PUT' ? true : false);
define('IS_DELETE', REQUEST_METHOD =='DELETE' ? true : false);
// URL调度
Dispatcher::dispatch();
if(C('REQUEST_VARS_FILTER')){
// 全局安全过滤
array_walk_recursive($_GET, 'think_filter');
array_walk_recursive($_POST, 'think_filter');
array_walk_recursive($_REQUEST, 'think_filter');
}
然后根据请求的路由规则,调用相应的控制器,控制器作为请求的入口,几乎所有框架都这样,tp也不例外。
$module = controller(CONTROLLER_NAME,CONTROLLER_PATH);
这里根据提交请求的参数名称实例化相应的控制器,然后调用相应的方法
$action = ACTION_NAME.C('ACTION_SUFFIX');
不过这里做了一个参数传递校验和过滤,个人觉得不是一个好的设计,导致不能在控制器里直接使用形参,会让开发变得麻烦,例如为了避免动态方法调用的繁琐,通常可以直接注入(Request $request)
通过反射的放射,处理控制器的参数,限制了只有传参,并且可以自动将http参数赋值给控制器形参,不过这种设计在tp5中被废除。
进入控制器后就可以进行逻辑代码编写了,值得一提的是,tp3.2模板引入还是依赖直接输出,中断下面代码执行的display,到了tp5则和yii2,lavarel一样改为return,将控制器方法作为一个中间处理过程,最终输出到浏览器还要进行统一灵活的数据处理。
网友评论