thinkphp3.2框架分析

1.路由route

 

<IfModule mod_rewrite.c>
  
Options +FollowSymlinks
  
RewriteEngine On

  
RewriteCond %{REQUEST_FILENAME} !-d
  
RewriteCond %{REQUEST_FILENAME} !-f
  
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]

</IfModule>





2.index.php入口
2.1require './ThinkPHP/ThinkPHP.php';

(1)记录初始运行时间和内存开销

(2)thinkphp核心组件常量判断及定义

 

defined('RUNTIME_PATH') or define('RUNTIME_PATH', APP_PATH . 'Runtime/'); // 系统运行时目录

defined('LIB_PATH') or define('LIB_PATH', realpath(THINK_PATH . 'Library') . '/'); // 系统核心类库目录

defined('CORE_PATH') or define('CORE_PATH', LIB_PATH . 'Think/'); // Think类库目录

defined('BEHAVIOR_PATH') or define('BEHAVIOR_PATH', LIB_PATH . 'Behavior/'); // 行为类库目录

defined('MODE_PATH') or define('MODE_PATH', THINK_PATH . 'Mode/'); // 系统应用模式目录

defined('VENDOR_PATH') or define('VENDOR_PATH', LIB_PATH . 'Vendor/'); // 第三方类库目录

defined('COMMON_PATH') or define('COMMON_PATH', APP_PATH . 'Common/'); // 应用公共目录

defined('CONF_PATH') or define('CONF_PATH', COMMON_PATH . 'Conf/'); // 应用配置目录

defined('LANG_PATH') or define('LANG_PATH', COMMON_PATH . 'Lang/'); // 应用语言目录

defined('HTML_PATH') or define('HTML_PATH', APP_PATH . 'Html/'); // 应用静态目录

defined('LOG_PATH') or define('LOG_PATH', RUNTIME_PATH . 'Logs/'); // 应用日志目录

defined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH . 'Temp/'); // 应用缓存目录

defined('DATA_PATH') or define('DATA_PATH', RUNTIME_PATH . 'Data/'); // 应用数据目录

defined('CACHE_PATH') or define('CACHE_PATH', RUNTIME_PATH . 'Cache/'); // 应用模板缓存目录

defined('CONF_EXT') or define('CONF_EXT', '.php'); // 配置文件后缀

defined('CONF_PARSE') or define('CONF_PARSE', ''); // 配置文件解析方法

defined('ADDON_PATH') or define('ADDON_PATH', APP_PATH . 'Addon');





2.2require CORE_PATH . 'Think' . EXT;
载入框架引导类(Think\Think)并执行Think::start方法进行应用初始化

a.大心脏,类的自动生成。thinkphp通过注册AUTOLOAD方法
spl_autoload_register('Think\Think::autoload');实现类的自动生成加载。
          检查是否存在映射$_map[$class],此主要作用把短命名空间(eg:QL\QueryList),转化为实际路径(eg:/ThinkPHP/Libray/Addons/QL/QueryList.class.php),其主要通过addMap方法、alias.php配置文件和AUTOLOAD_NAMESPACE变量配置添加$_map映射值,主要是为了方便自动化生成自定义命名空间的类    其次系统默认设置自动加载寻找的目录’Think', 'Org', 'Behavior', 'Com', 'Vendor'
          最后,用户还可以通过配置APP_AUTOLOAD_LAYER和APP_AUTOLOAD_PATH变量去设置自动查找的目录
          当扫描完所有目录后找到对应文件,include文件,然后new $class生成对应的类。

 

          紧跟则是设定错误和异常处理

 

register_shutdown_function('Think\Think::fatalError');

set_error_handler('Think\Think::appError');

set_exception_handler('Think\Think::appException');


b.读取运行时文件$runtimefile = RUNTIME_PATH . APP_MODE . '~runtime.php';

 

如果对文件读取失败,则调用complie函数合并以下核心类,同时inclue以下核心类
$mode = include is_file(CONF_PATH . 'core.php') ? CONF_PATH . 'core.php' : MODE_PATH . APP_MODE . '.php’;//即ThinkPHP/Mode/common.php
// 函数和类文件
'core'   => array(
    
THINK_PATH . 'Common/functions.php',
    
COMMON_PATH . 'Common/function.php',
    
CORE_PATH . 'Hook' . EXT,
    
CORE_PATH . 'App' . EXT,
    
CORE_PATH . 'Dispatcher' . EXT,
    
CORE_PATH . 'Log'.EXT,
    
CORE_PATH . 'Route' . EXT,
    
CORE_PATH . 'Controller' . EXT,
    
CORE_PATH . 'View' . EXT,
    
BEHAVIOR_PATH . 'BuildLiteBehavior' . EXT,
    
BEHAVIOR_PATH . 'ParseTemplateBehavior' . EXT,
    
BEHAVIOR_PATH . 'ContentReplaceBehavior' . EXT,
)


c.读取全局配置文件

 

'config' => 
array(
   
 THINK_PATH . 'Conf/convention.php', // 系统惯例配置
   
CONF_PATH . 'config' . CONF_EXT, // 应用公共配置

);


d.读取全局应用模式对应的配置文件

 


if ('common' != APP_MODE && is_file(CONF_PATH . 'config_' . APP_MODE . CONF_EXT)) {
    
  C(load_config(CONF_PATH . 'config_' . APP_MODE . CONF_EXT));

 }



e.读取全局命名空间别名映射,内容放在/Thinkphp/Model/Common.php文件

// 加载模式别名定义

if (isset($mode['alias'])) {
    
   self::addMap(is_array($mode['alias']) ? $mode['alias'] : include $mode['alias']);

}

// 加载应用别名定义文件,方法放在/Application/Common/alias.php文件
if (is_file(CONF_PATH . 'alias.php')) {
    
   self::addMap(include CONF_PATH . 'alias.php');

}
方法放在/Application/Common/alias.php文件
if (is_file(CONF_PATH . 'alias.php')) {
    
   self::addMap(include CONF_PATH . 'alias.php');

}


f.读取全局行为映射,读取全局的Hook方法,方法放在/Thinkphp/Model/Common.php文件



// 加载模式行为定义

if (isset($mode['tags'])) {
    
   Hook::import(is_array($mode['tags']) ? $mode['tags'] : include $mode['tags']);

}

// 加载应用行为定义
,方法放在/Application/Common/tags.php文件
if (is_file(CONF_PATH . 'tags.php'))
// 允许应用增加开发模式配置定义

{
    
   Hook::import(include CONF_PATH . 'tags.php');

}方法放在/Application/Common/tags.php文件
if (is_file(CONF_PATH . 'tags.php'))
// 允许应用增加开发模式配置定义

{
    
   Hook::import(include CONF_PATH . 'tags.php');

}


g.// 加载框架底层语言包
L(include THINK_PATH . 'Lang/' . strtolower(C('DEFAULT_LANG')) . '.php');

h.其他初始化操作
生成runtime缓存文件,如果是调试模式则调用模式调试配置文件conf/debug.php及应用调试文件debug.php
// 读取当前应用状态对应的配置文件
// 设置系统时区
// 检查应用目录结构 如果不存在则自动创建
// 记录加载文件时间

i.app::run()运行程序

2.3运行程序App::run()
a.// 加载动态应用公共文件和配置
load_ext_file(COMMON_PATH);

b.// 应用初始化标签,路径例子/model/controller/action/vari.php

Hook::listen('app_init');

App::init();(App.class.php)
->Dispatcher.class.php// URL调度Dispatcher::dispatch();预处理
     ->加载模块配置文件(应用目录/Conf/config.php文件)
     ->加载应用模式对应的配置文件(应用目录/Conf/confg_common.php或
     ->当前应用状态对应的配置文件(应用目录/Conf/status.php文件)
     ->加载模块别名定义(应用目录/Conf/alias.php命名空间映射文件)
     ->加载模块tags文件定义(应用目录/Conf/tags.php文件)
     ->加载模块函数文件(应用目录/Common/function.php文件)
     ->加载模块的扩展配置文件(LOAD_EXT_FILE和LOAD_EXT_CONFIG设置的扩展模块)
     ->模块配置文件加载完成检测位
     ->获取控制器和操作名
    ->解析剩余的URL参数
     ->获取控制器的命名空间(路径)


c.// 应用开始标签
Hook::listen('app_begin');

d.// Session初始化
if (!IS_CLI) {
    session(C('SESSION_OPTIONS'));
}

e.// 记录应用初始化时间
G('initTime');

f.App::exec();生成Controller对象,执行里面的action方法,然后调用模板函数找到对应的模板,解析模板,输出页面内容。

 


g.// 应用结束标签
Hook::listen('app_end');

 

 

3数据对象的生成及数据库连接
D方法和M方法的分析:D和M的区别是,D实例化自定义的Model类,其等同于new XXXModel(),而M则是Think\Model()类的生成,直接是对表的操作不需要定义Model类,例如M(‘XXX’)。

3.1.M方法的分析
首先生成Model类

if (strpos($name, ':')) {
    
    list($class, $name) = explode(':', $name);//指定基础模型类生成 例如 MongoModel:User,AdvModel:User,在Think/Model文件夹下

} else {
    
    $class = 'Think\\Model’;//直接生成Model类

}

其次数据库初始化操作,获取数据库操作对象,当前模型有独立的数据库连接信息
$this->db(0, empty($this->connection) ? $connection : $this->connection, true);
->$this->_db[$linkNum] = Db::getInstance($config);
->解析数据库连接$options = self::parseConfig($config);
->生成对应的数据库类$class = !empty($options['lite']) ? 'Think\Db\Lite' : 'Think\\Db\\Driver\\' . ucwords(strtolower($options['type']));

3.2.D方法的分析
有了M方法的分析,D方法更加简单,D方法首先去公共模块下的Common/Model里和对应的应用目录/CommonModel里找,如果存在此类则生成,如果不存在就直接生成M方法里的Model类

$class = parse_res_name($name, $layer);

if (class_exists($class)) {
    
     $model = new $class(basename($name));

} 
elseif (false === strpos($name, '/')) {
    
    // 自动加载公共模块下面的模型
    
   if (!C('APP_USE_NAMESPACE')) {
        
      import('Common/' . $layer . '/' . $class);
    
   } else {
        
      $class = '\\Common\\' . $layer . '\\' . $name . $layer;
    
   }
    
   $model = class_exists($class) ? new $class($name) : new Think\Model($name);

} else {
    
   Think\Log::record('D方法实例化没找到模型类' . $class, Think\Log::NOTICE);
    
   $model = new Think\Model(basename($name));

}

 

4.1模板的生成及展示

在Think/Controller->display()时-----> Think/Controller->fetch() -----> Think/View->fetch() -----> Hook::listen('view_parse', $params); -----> 最终触动 ParseTemplateBehavior

最终调用了Template.class.php的方法


 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

turbocc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值