zblogphp1.5.0代码分析 从index.php开始

admin2023-01-193233

打开 index.php 后,首先加载 c_system_base.php 来初始化相关操作

打开所有的错误报告,打开缓存

定义网站路径和 hookerror 错误常量

定义版本号相关常量11个

将 15 1626 类似的版本写入超全局变量 $GLOBALS['blogversion']

加载同目录下的另外4个基础函数文件 plugin(插件接口相关) debug(错误调试) common(辅助通用函数) event(事件相关函数)

设置自动注册类函数为自己的函数 AutoloadClass函数,当使用的函数未注册时使用该函数注册

定义系统常量,分别是操作系统7个、网站服务器6个、PHP引擎7个、兼容性相关12个、文章类型9个,共41个

定义文章类型超全局数组变量 $GLOBALS['posttype'] array(array(1,2,3))

定义文章状态常量6个

定义命令超全局数组变量 $GLOBALS['actions'] array(1,2,...)

定义数据表超全局数组变量 $GLOBALS['table'] array(1,2,...)

定义数据库结构超全局变量 array(array(array(1,2,...)))

定义4个超全局变量 $_SERVER 相关资料说不建议用

版本兼容性处理,如果 PHP 支持 get_magic_quotes_gpc 且打开了该功能,则使用自己的函数将 $_GET $POST $_COOKIE $_REQUEST 添加的的反斜杠删除

定义系统全局变量 $GLOBALS 8个

将配置文件通过 require 到 $GLOBALS['option'] ,可以在全局中使用 $GLOBALS['option']['xxxx'] 来获取配置数据. 这个配置文件在 zb_system/defend/option.php

配置包括是否关闭网站、网站基本设置、数据库配置、插件、全局配置、静态化等等

接下来判断 如果 ZBP_HOOKERROR 为 false 且有全局环境变量 $_ENV['ZBP_USER_OPTION'] 且这个文件可读,则将其赋值到 $op_users 变量,并将这个数组合并到 $GLOBALS['option'] 全局变量中, 否则如果 zb_users/c_option.php 文件存在,将 zb_users/c_option.php 的数组赋值到 $op_users 变量,并将这个数组合并到 $GLOBALS['option'] 全局变量中

P.S. 我在zblogphp150版本中搜索了很多次,都没有找到哪里有定义 $_ENV['ZBP_USER_OPTION'] 这个变量的!

接下来将 $GLOBALS['option'] 里的一些数据赋值到 $GLOBALS 的网站信息,包括 博客标题,博客名称,博客主题什么的...

然后开始系统实例化,使用 AutoloadClass函数 (这个函数在 zb_system/function/common.php 文件中,前面有个插件中断方式的,只要不是return就能加载对应类,待研究) 来实例化位于 zb-system/function/lib下的类函数.这里依次加载了 zbp全局操作类、SQL语句生成类、配置类

然后通过

$GLOBALS['zbp'] = ZBlogPHP::GetInstance();

$GLOBALS['zbp']->Initialize();

初始化 $zbp

最后加载主题和插件APP:

如果能读取到博客主题的 theme.xml ,则将 博客主题名称 赋值到 $GLOBALS['activedapps'][]

如果能读取到博客主题的 include.php ,则将这个文件加载进来(主题插件的)

获取需要激活的插件名称数组,赋值到 $aps

然后依次将插件名称放入 $GLOBALS['activedapps'][] 以及加载对应的 include.php 文件(主动方式插入注册)

foreach 循环执行插件的函数

最后的最后将使用过的变量销毁 c_system_base.php 结束

--------------------------------------------------------------------------------------------

执行玩初始化相关操作后,实例化对象为 $GLOBALS['zbp'] = $zbp, 使用这个全局对象可以使用 lib/zblogphp类(全局操作类)的所有函数

$zbp->RedirectInstall();

这个是跳转到安装页面的函数,判断 $this->option['ZC_DATABASE_TYPE'] 配置是否有值,因为会加载 zb_users/c_option.php ,同键值后者覆盖前者,如果没有值才安装.然后还会判断 $this->option['ZC_YUN_SITE'] 这个值,这个值是 空的,所以进入该语句内的又一个 if 判断, $this->Config

('system')->CountItem() == 0 判断数据config表配置名为 system 的 值,如果没有值就跳转到注册页面.正常安装之后这个函数就没用了.

$zbp->CheckGzip();

检查是否打开 Gzip压缩,如果打开则 $zbp->isgzip 为 true ,这个变量是私有的,只能在 zblogphp类中使用,不能通过实例化调用.

$zbp->Load();

首先使用 foreach循环获取 $GLOBALS['hooks']['Filter_Plugin_Zbp_Load_Pre'] Zbp类的加载(预处理)接口的插件名称和插件中断方式(在Add_Filter_Plugin 挂上Filter(过滤器)接口,第三个参数,默认是PLUGIN_EXITSIGNAL_NONE,没有中断.另外两种是 return 和 break 方式).不过这里会将 插件中断方式清空在加载插件函数.

之后判断是否初始化成功,失败则返回false

之后判断是否载入,载入则返回false

接下来执行 StartGzip() 函数打开 Gzip ,看来必须要成功,不然还无法载入?

header('Content-type: text/html; charset=utf-8'); 输出编码格式

执行 ConvertTableAndDatainfo() 函数对表明和数据结构进行预转换

执行 LoadCategorys() 函数载入分类列表

执行 LoadTags() 函数载入标签列表,被注释掉了.

执行 LoadModules() 函数载入载入模块列表

执行 Verify()函数验证用户登录(COOKIE中的用户名密码)

之后执行 RegBuildModule() 函数重建了9个模块,第一个参数是模块名,第二个参数是用户函数.

然后 PrepareTemplate() 创建模板类

通过 LoadApp 函数载入指定应用,这里是载入 theme ,然后如果应用类型不是空的话则获取主题信息

通过 $this->ismanage 判断是否载入 管理模式,默认为false

最后通过 Add_Filter_Plugin() 挂载插件文件,这里挂载了3处!

然后 使用 foreach 函数加载钩子函数,设置 已加载标识,返回 true, Load() 结束!

$zbp->RedirectPermanentDomain();

该函数作用是检测当前的URL,如果不符合设置就跳转到固定的域名链接.

有两个判断,一个是是否启动固定域名,一个是是否打开永久域名重定向(这个没看到在哪里有设置,默认是true).所以会继续执行该函数.

接下来先使用 GetCurrentHost() 函数来获取当前的网站地址,这个函数在 zb_system/function/s_system_common.php 文件中,返回的是完整的地址. $this->host 是返回的网站路径?还是返回网址?不过这两次执行的函数的参数都是一样,只是一个带入和cookie一个没有.如果两次结果不一样则执行 GetRequestUri() 函数获取请求来源URL,看代码应该是返回最后一个斜杠之后的参数,拼接网站PATH,最后 执行 Redirect301() 函数进行301跳转.这几个函数都是在 common.php 文件.

$zbp->CheckSiteClosed();

最后一个调用的zblogphp类的函数是这个,检测网站是否关闭,如果关闭则显示错误页(关闭提示)并终止执行.

接下来如果没有关闭网站则 foreach 执行插件函数 (位于启动接口的的插件),显示页面之前

执行 ViewIndex() 函数显示首页,当然搜索页、feed页也是用这个函数显示的.

之后再次 foreach 执行插件函数,此处是启动个完毕之后的插件执行接口.

最后执行 RunTime() 函数显示页面执行时间,程序执行结束,显示页面.

-------------------------------------------------------------------------------------------

在根目录的 index.php 文件中,有一个函数很重要的函数 ViewIndex(); 它的作用是显示前台的页面.该函数位于c_system_event.php 事件相关函数文件中.首页,搜索页和feed页面都是调用的这个显示函数.

这个函数首先设置全局变量 $zbp 和 $action, $zbp 对于 zblogphp 来说是一个很重要的全局对象,基本上系统的大部分数据都可以通过这个对象来获取.

例如:$zbp->option['ZC_BLOG_NAME'] 获得的是网站博客的名称

然后 foreach 循环输出插件函数,(只输出位于 Filter_Plugin_ViewIndex_Begin 接口的,看位置应该是模板之前的位置,index 和 view 的入口位置是不同的,也就是说 index 位置的插件函数比view位置的插件函数先执行).

插件注册的时候是把方法名赋值给插件名的,所以 return $fpname() 会直接执行插件的函数

在插件挂载的时候是把中断方式赋值给执行函数名的,所以 $fpname => &$fpsignal 获得插件的中断方式

不过这里不管是什么中断方式都会设置成无.保证页面能顺利执行下去.

然后 $zbp->template->hasTemplate('404') 执行模板类对象的 hasTemplate 方法,得到当前使用模版的404.php内容? 路径:\zb_users\cache\compiled\default\404.php

如果主题有这个404文件,则在该文件挂载过滤接口 函数 Include_ShowError404,这个是怎么挂载的?是在zblogphp.php文件初始化是调用的 ShowError 函数,里面会有 foreach 输出插件函数.,这里的作用是判断如果有错误页则将插件挂载到这里,主要做特色化错误页面的.默认错误也是腾讯的公益404.

然后 switch 判断 $action 的值是否为 feed 和 search ,这两个操作有对应的入口文件,默认入口 index 是没有这个参数的,所以会执行 default 部分的代码块.

该代码首先判断 请求的路径 和 保存在cookie的路径是否相同,如果相同则调用 ViewList 函数 且所有参数为 null 以默认方式显示首页列表页面

如果不一样的话则判断

伪静态模式是否为 ACTIVE 或是否 GET rewrite 且 GET 了 id 或者 alias

如果是的话说明请求的是文章内容页,调用 ViewPost 显示页面

如果也不是请求的文章内容页的话,则调用 ViewList 以 对应参数请求结果列表,这包括page,cate,auth,date,tags,详细实现过程这里略过不写.

如果还不是的话,最后会调用 ViewAuto 函数来根据 伪静态规则显示页面

附加内容: ViewList函数分析

ViewList函数是显示列表页面的函数,默认 ViewList(null, null, null, null, null) 输出首页列表内容,伪静态参数默认为false

函数首页 global 全局对象 $zbp

然后 foreach 输出 挂在列表开始的插件函数,设定类型为 index

然后判断第2-5个参数,根据对应参数来设置类型(非null),后者覆盖前者.

定义4个变量值为 null ,(分离,作者,日期,标签),定义w数组,看起来是原来匹配文章是否置顶的.

$w = array();

$w[] = array('=', 'log_IsTop', 0);

$w[] = array('=', 'log_Status', 0);

获取参数1的内容,得到分页值,设置文章列表结果数组和文章置顶列表结果数组

执行 switch ,根据 类型不同执行不同的代码,默认 index 执行第一个 case

首先以伪静态正则 'ZC_INDEX_REGEX' => '{%host%}?page={%page%}', 为参数实例化 Pagebar分页类

将$zbp 的缓存对象的文章总数设置为分页类 count 的值,文章总数是通过 CountNormalArticleNums 函数获取的

然后获得首页(列表)默认模板(index),内容(页面)的默认是(single)

如果页面是第一个,则 设置 $zbp->title 为 网站副标题,否则 $zbp->title 为 第xx页

也就是说,如果不是第一页的列表是不会显示网站副标题的!

之后 break 来到

$pagebar->PageCount = $zbp->displaycount;

$pagebar->PageNow = $page;

$pagebar->PageBarCount = $zbp->pagebarcount;

$pagebar->UrlRule->Rules['{%page%}'] = $page;

依次设置每页显示数量,当前页,一共有多少页,URL规则类 Rules {%page%} 的值设置为 当前页数

输出 Filter_Plugin_ViewList_Core 的插件函数,看参数应该是在输出内容前执行的,官方WIKI也没有写出这个接口的说明

接下来判断如果顶部列表关闭(ZC_LISTONTOP_TURNOFF)是否等于false,也就是如果打开了置顶功能的话则获取全部置顶文章,还说了优先从缓存的数组里获取.(不过我还没看到对应的实现代码,反正 $zbp->GetTopArticle() 之后就获取到了置顶的数据了),然后依次 foreach 得到全局置顶的,首页置顶的和分类置顶的文章类型的数组待用

循环输出 Filter_Plugin_LargeData_Aritcle 的插件函数,看情况是在查询数据库之前(获取数据之前)的插件接口,官方WIKI依然没有这个接口的说明.

然后就是执行 $zbp->GetArticleList 函数查询获得文章列表了.

获取主题标签中的网站标题,中的文章

如果总页数等于0,则将分页类对象删除?(不知道,反正他是把对象 pagebar 设置为了 null)

一长串的 SetTags 设置主题标签和对应的值,有什么用?不知道,反正在这个函数内没看到他用这个!

之后使用 hasTemplate 判断对应的主题文件是否存在,如果存在则 SetTemplate设置主题类中的 entryPage 的值为对应的主题文件的名称,如果不存在则设置为 index (如果 index 也不存在呢?哈哈)

这里有循环输出 Filter_Plugin_ViewList_Template 位置接口的插件函数,官方WIKI终于有说明了,是 处理列表页模板接口 ,然后呢?我还是没有理解能在这里做什么啊,不过可以知道的是这个位置肯定在显示模板文件之前的,因为后面 $zbp->template->Display(); 就是显示模板页面的函数.



网友评论