thinkphp3.2框架分析

来源:互联网 发布:钟无艳国语网络歌手 编辑:程序博客网 时间:2024/06/17 19:24
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.读取全局命名空间别名映射
// 加载模式别名定义
if (isset($mode['alias'])) {
       self::addMap(is_array($mode['alias']) ? $mode['alias'] : include $mode['alias']);
}
// 加载应用别名定义文件
if (is_file(CONF_PATH . 'alias.php')) {
       self::addMap(include CONF_PATH . 'alias.php');
}

f.读取全局行为映射


// 加载模式行为定义
if (isset($mode['tags'])) {
       Hook::import(is_array($mode['tags']) ? $mode['tags'] : include $mode['tags']);
}
// 加载应用行为定义
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));
}



 

原创粉丝点击