搜索
系统检测到您的用户名不符合规范:

Thinkphp5源码解析

浏览:6676 发布日期:2018年06月21日 分类:技术分享
Thinkphp5源码解析试分析一部分

Thinkphp5框架默认入口为public目录下的index.php。

首先从index.php进行代码分析。

index.php(public目录下的index.php)代码如下:

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------

//D:\phpStudy\WWW\tpfive\public __DIR__
// [ 应用入口文件 ]

/* 定义应用目录,定义了常量APP_PATH, __DIR__ 为魔术方法,获取当前执行的PHP脚本所在的目录
../application/ 返回上一级application目录里, */
define('APP_PATH', __DIR__ . '/../application/');

// 加载框架引导文件 载入thinkphp目录下的start.php文件
require __DIR__ . '/../thinkphp/start.php';


从index.php中加载了start.php。

start.php(thinkphp目录下的start.php)代码如下:

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------

//首先定义了命名空间为think
namespace think;

// ThinkPHP 引导文件
// 1. 加载基础文件

//__DIR__指向当前执行的PHP脚本所在的目录,载入当前目录下的base.php(\thinkphp\base.php)
require __DIR__ . '/base.php';

// 2. 执行应用 执行\thinkphp\library\think\App.php文件中的run方法
App::run()->send();


先分析start.php中的这句:


//__DIR__指向当前执行的PHP脚本所在的目录,载入当前目录下的base.php(\thinkphp\base.php)
require __DIR__ . '/base.php';


从start.php中加载了base.php。

base.php(thinkphp目录下的base.php)代码如下:

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------


//这里定义了tp5的一些基本常量

//定义了当前tp框架的版本为'5.0.20',可在任意控制器或视图echo THINK_VERSION;获取框架版本号
define('THINK_VERSION', '5.0.20');

//microtime()返回当前 Unix 时间戳的微秒数,用于对php脚本的运行计时
define('THINK_START_TIME', microtime(true));

//memory_get_usage返回当前分配给你的 PHP 脚本的内存量,单位是字节(byte)
define('THINK_START_MEM', memory_get_usage());

//定义了.php后缀
define('EXT', '.php');

// DIRECTORY_SEPARATOR,路径分隔符,linux上是 "/" windows上是 "\"
define('DS', DIRECTORY_SEPARATOR);

//判断是否定义了常量THINK_PATH,没有则定义常量THINK_PATH为根目录下\thinkphp\
defined('THINK_PATH') or define('THINK_PATH', __DIR__ . DS);

//定义了library文件夹路径,根目录下\thinkphp\library\
define('LIB_PATH', THINK_PATH . 'library' . DS);

//定义常量CORE_PATH为根目录下\thinkphp\library\think\
define('CORE_PATH', LIB_PATH . 'think' . DS);

//定义了traits文件夹路径,根目录下\thinkphp\library\traits\
define('TRAIT_PATH', LIB_PATH . 'traits' . DS);

/* $_SERVER['script_FILENAME']获取的是当前执行脚本的绝对路径,不是当前PHP脚本所在的目录路径,
执行脚本指的是/public下的index.php,不是当前base.php文件,注意区分,dirname返回路径中的目录部分
这里APP_PATH常量在/public/index.php已经定义,
因此后面这句 define('APP_PATH', dirname($_SERVER['script_FILENAME']) . DS)不会执行
*/
defined('APP_PATH') or define('APP_PATH', dirname($_SERVER['script_FILENAME']) . DS);

//判断是否定义了常量ROOT_PATH,没有则定义常量ROOT_PATH为框架application目录所在的路径
defined('ROOT_PATH') or define('ROOT_PATH', dirname(realpath(APP_PATH)) . DS);

//判断是否定义了常量EXTEND_PATH,没有则定义常量EXTEND_PATH为框架extend目录所在的路径
defined('EXTEND_PATH') or define('EXTEND_PATH', ROOT_PATH . 'extend' . DS);

//判断是否定义了常量VENDOR_PATH,没有则定义常量VENDOR_PATH为框架vendor目录所在的路径
defined('VENDOR_PATH') or define('VENDOR_PATH', ROOT_PATH . 'vendor' . DS);

//判断是否定义了常量RUNTIME_PATH,没有则定义常量RUNTIME_PATH为框架runtime目录所在的路径
defined('RUNTIME_PATH') or define('RUNTIME_PATH', ROOT_PATH . 'runtime' . DS);

//判断是否定义了常量LOG_PATH,没有则定义常量LOG_PATH为框架\runtime\log所在的路径
defined('LOG_PATH') or define('LOG_PATH', RUNTIME_PATH . 'log' . DS);

//判断是否定义了常量CACHE_PATH,没有则定义常量CACHE_PATH为框架\runtime\cache目录所在的路径
defined('CACHE_PATH') or define('CACHE_PATH', RUNTIME_PATH . 'cache' . DS);

//判断是否定义了常量TEMP_PATH,没有则定义常量TEMP_PATH为框架\runtime\temp目录所在的路径
defined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH . 'temp' . DS);

//判断是否定义了常量CONF_PATH,没有则定义常量CONF_PATH为框架application目录所在的路径
defined('CONF_PATH') or define('CONF_PATH', APP_PATH); // 配置文件目录

//判断是否定义了常量CONF_EXT,没有则定义常量CONF_EXT为.php后缀
defined('CONF_EXT') or define('CONF_EXT', EXT); // 配置文件后缀

//判断是否定义了常量ENV_PREFIX,没有则定义常量ENV_PREFIX为PHP_
defined('ENV_PREFIX') or define('ENV_PREFIX', 'PHP_'); // 环境变量的配置前缀

//PHP_SAPI 用来判断是使用命令行还是浏览器执行的,nginx下PHP_SAPI输出cgi-fcgi,命令行输出cli
define('IS_CLI', PHP_SAPI == 'cli' ? true : false);

/*PHP_OS检查php运行环境,linux下输出linux,windows下输出WINNT
strpos是查找字符串WINNT下WIN的位置,找不到为false,说明当前运行环境不是windows系统 */
define('IS_WIN', strpos(PHP_OS, 'WIN') !== false);

// 载入\thinkphp\library\think\Loader.php文件
require CORE_PATH . 'Loader.php';

// 加载环境变量配置文件 根目录下的.env文件,默认.env文件没有,需要自行创建,.env是仿laravel框架的全局变量配置
if (is_file(ROOT_PATH . '.env')) {

$env = parse_ini_file(ROOT_PATH . '.env', true);

foreach ($env as $key => $val) {
$name = ENV_PREFIX . strtoupper($key);

if (is_array($val)) {
foreach ($val as $k => $v) {
$item = $name . '_' . strtoupper($k);
putenv("$item=$v");
}
} else {
putenv("$name=$val");
}
}
}

// 注册自动加载,执行上述载入\thinkphp\library\think\Loader.php文件中Loader类的register方法
\think\Loader::register();

/*注册错误和异常处理机制,由于当前php脚本没有Error这个类,因此触发了
\thinkphp\library\think\Loader.php文件Loader类中的register方法中
spl_autoload_register这个函数,而这个函数就会触发Loader类中的autoload方法,autoload方法会根据所该类,
找到该类对应的文件所在的目录,include进来,\think\Error会找到\thinkphp\library\think\Error.php文件
需要注意的是tp3.2中错误函数set_error_handler, 异常处理函数set_exception_handler,
php脚本执行完成函数register_shutdown_function都写在同一个类中,而tp5并没有写在当前类中,从当前类中分离出去
这三个函数写在了\thinkphp\library\think\Error.php文件里面,所以tp5比tp3加载的文件数量更多
*/
\think\Error::register();

/* \think\Config这个类在当前文件同样找不到,因此触发了
\thinkphp\library\think\Loader.php文件Loader类中的register方法,道理同上述一样
include了 \thinkphp\library\think\Config.php文件,执行Config.php文件中Config类中set方法,
加载惯例配置文件 载入 \thinkphp\convention.php文件里的配置*/
\think\Config::set(include THINK_PATH . 'convention' . EXT);


可以看出从base.php中加载了Loader.php。先分析base.php中这句重要的代码:


// 注册自动加载
\think\Loader::register();

全文:https://blog.csdn.net/bazhu3507/article/details/80745380
最佳答案
评论() 相关
后面还有条评论,
评论支持使用[code][/code]标签添加代码
您需要登录后才可以评论 登录 | 立即注册
收藏
zyxljh123
积分:280 等级:LV1
热点推荐
(追記) (追記ここまで)
最新更新

我们

合作

网站

信息

ThinkPHP 是一个免费开源的,快速、简单的面向对象的 轻量级PHP开发框架 ,创立于2006年初,遵循Apache2开源协议发布,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,也注重易用性。并且拥有众多的原创功能和特性,在社区团队的积极参与下,在易用性、扩展性和性能方面不断优化和改进,已经成长为国内最领先和最具影响力的WEB应用开发框架,众多的典型案例确保可以稳定用于商业以及门户级的开发。

AltStyle によって変換されたページ (->オリジナル) /