以dz根目录门户请求入口文件 portal.php为例,浅析其执行流程。
我们以portal.php为例,用户请求 http://xxx.xxx.xx/portal.php
接收到用户请求,脚本执行以下内容:
//定义当前应用ID define('APPTYPEID', 4); //定义当前应用脚本名称 define('CURSCRIPT', 'portal'); //引入dz核心库文件-每个入口文件都会载入此类 require './source/class/class_core.php';
在引入dz 核心库文件的时候,做了以下操作(以下代码位于:source/class/class_core.php)
error_reporting(E_ALL); define('IN_DISCUZ', true); //定义dz根目录 define('DISCUZ_ROOT', substr(dirname(__FILE__), 0, -12)); //define('DISCUZ_CORE_DEBUG', false); //调式模式是否开启 define('DISCUZ_CORE_DEBUG', true); //异常处理 set_exception_handler(array('core', 'handleException')); if(DISCUZ_CORE_DEBUG) { set_error_handler(array('core', 'handleError')); register_shutdown_function(array('core', 'handleShutdown')); } //类自动加载设置 if(function_exists('spl_autoload_register')) { spl_autoload_register(array('core', 'autoload')); } else { function __autoload($class) { return core::autoload($class); } }
接下来的一句:
C::creatapp();
创建dz的类discuz_application的一个实例,此处代码位于文件:source/class/discuz/discuz_application.php中
public static function creatapp() { if(!is_object(self::$_app)) { self::$_app = discuz_application::instance(); } return self::$_app; }
discuz_application::instance() 到底做了什么?
static function &instance() { static $object; if(empty($object)) { $object = new self(); } return $object; } public function __construct() { //运行环境初始化,在x2.5版本中很重要的$_G就在此处声明定义 $this->_init_env(); //应用配置初始化 载入source/config/config_global.php中的配置项,定义cookie前缀,静态文件目录等 $this->_init_config(); //输入初始化, 在这里将$_GET和$_POST合并,统一使用$_GET $this->_init_input(); //输出初始化 header头 跨域攻击xss检查等 $this->_init_output(); }
具体以上四个初始化方法都做了哪些工作,不再赘述,详情可参看 : source/class/discuz/discuz_application.php 文件
以上代码执行完毕,回到portal.php,
$cachelist = array('userapp', 'portalcategory', 'diytemplatenameportal');
$discuz->cachelist = $cachelist;
//应用初始化
$discuz->init();
此句代码我们再次进入类 discuz_application中
public function init() { if(!$this->initated) { $this->_init_db(); $this->_init_setting(); $this->_init_user(); $this->_init_session(); $this->_init_mobile(); $this->_init_cron(); $this->_init_misc(); } $this->initated = true; }
上述代码对数据库连接,css样式缓存,用户信息,session等做了初始化,具体内容可查看源代码
针对门户包含的两个函数文件,其他入口根据情况包含文件有所变化
require DISCUZ_ROOT.'./source/function/function_home.php'; require DISCUZ_ROOT.'./source/function/function_portal.php';
当前操作,定义了门户中可进行的请求内容
if(empty($_GET['mod']) || !in_array($_GET['mod'], array('list', 'view', 'comment', 'portalcp', 'topic', 'attachment', 'rss', 'block'))) $_GET['mod'] = 'index'; define('CURMODULE', $_GET['mod']);
//运行插件
runhooks();
//此句载入source/module/portal目录下相关文件,假设$_GET['mod']是 index,则载入该目录的portal_index.php
require_once libfile('portal/'.$_GET['mod'], 'module');
接下来执行的代码就位于source/module/portal/protal_xxx.php中了,xxx==$_GET['mod'];
在这个文件中,include_once template('diy:portal/index'); 载入模板,此句执行后,返回给用户浏览器可观看的页面
template 模板中所需要的数据,就应该在protal_xxx.php文件中提前准备好
template 具体怎么解析模板, 后面如果有时间,我会继续分析。