Loading [MathJax]/jax/output/CommonHTML/fonts/TeX/AMS-Regular.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >typecho源代码解析1 - 系统初始化

typecho源代码解析1 - 系统初始化

作者头像
老高的技术博客
发布于 2022-12-28 00:49:11
发布于 2022-12-28 00:49:11
65700
代码可运行
举报
运行总次数:0
代码可运行

首先恭喜typecho v1.0的上线!

其次,这篇文章同thinkphp的源代码解析一样都是老高谋划了很久的文章,国庆节由于单位加班没有时间写,今天终于等来了轮休,果断放开了写。希望大家多多支持!

最后老高想说的是,如果大家有兴趣研究源码,那么问题来了,如何高效的学习研究源代码?

老高的建议是:

  1. 一定要熟悉MVC模式(针对WEB开发)
  2. 先看看文档再动手
  3. 分辨什么是好的坏的代码,不要搞盲目崇拜
  4. 做笔记

以下:

文档

如果有什么不明白的,文档里也许会找到答案。

typecho开发文档

版本

再研究源代码前,如果知道自己使用的typecho的版本呢?

答案写在var/Typecho/Common.php里,Typecho_Common类中的常量VERSION

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Typecho_Common
{
    /** 程序版本 */
    const VERSION = '1.0/14.10.9';
    ...
}

开启DEBUG模式

有些同学可能已经发现,typecho默认对外隐藏了PHP的错误信息,如果我们想要看到真正的报错信息,需要开启typecho的DEBUG模式,也可以叫做开发模式。当我们开启了这个模式后,在开发插件或者了解系统原理的时候就能够得到可视化的错误信息了。

开启方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 修改/config.inc.php
# 在代码的第一行加入
/**开启debug模式*/
define('__TYPECHO_DEBUG__',1);

ps.调试的时候如果你的服务器没有安装xdebug,那么你的var_dump()信息会没有格式。

在此老高推荐使用TP框架内的方法dump(),以后我们就可以使用dump()打印变量信息了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 修改/config.inc.php
# 在debug后加入

/**
 * 浏览器友好的变量输出
 * @param mixed $var 变量
 * @param boolean $echo 是否输出 默认为True 如果为false 则返回输出字符串
 * @param string $label 标签 默认为空
 * @param boolean $strict 是否严谨 默认为true
 * @return void|string
 */
function dump($var, $echo=true, $label=null, $strict=true) {
    $label = ($label === null) ? '' : rtrim($label) . ' ';
    if (!$strict) {
        if (ini_get('html_errors')) {
            $output = print_r($var, true);
            $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';
        } else {
            $output = $label . print_r($var, true);
        }
    } else {
        ob_start();
        var_dump($var);
        $output = ob_get_clean();
        if (!extension_loaded('xdebug')) {
            $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output);
            $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';
        }
    }
    if ($echo) {
        echo($output);
        return null;
    }else
        return $output;
}

入口

入口文件为index.php,国际惯例贴代码。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (!@include_once 'config.inc.php') {
    file_exists('./install.php') ? header('Location: install.php') : print('Missing Config File');
    exit;
}

/** 初始化组件 */
Typecho_Widget::widget('Widget_Init');

/** 注册一个初始化插件 */
Typecho_Plugin::factory('index.php')->begin();

/** 开始路由分发 */
Typecho_Router::dispatch();

/** 注册一个结束插件 */
Typecho_Plugin::factory('index.php')->end();

typecho也采用了流行的单一入口,在此会引出一个伪静态的问题,此处先留个坑,以后补上。

index.php文件流程:

config.inc.php文件如果存在,就引入;如果不存在,就跳转到install.php进行程序安装,请原谅老高在此跳过install.php流程,如果读者有问题,请留言交流。

config.inc.php在安装程序的时候会自动生成,其主要工作是:引入程序常量,设定包含路径,引入各个核心文件(注意此时没有使用__autoLoad,所以只能require),执行Typecho_Common::init()初始化工作,保存数据库连接信息并初始化数据库对象。

Typecho_Common::init()位于var/Typecho/Common.php,方法代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static function init()
    {
        ini_set( 'display_errors', 'On' );
        /** 设置自动载入函数 */
        if (function_exists('spl_autoload_register')) {
            spl_autoload_register(array('Typecho_Common', '__autoLoad'));
        } else {
            function __autoLoad($className) {
                Typecho_Common::__autoLoad($className);
            }
        }

        /** 兼容php6 */
        if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) {
            $_GET = self::stripslashesDeep($_GET);
            $_POST = self::stripslashesDeep($_POST);
            $_COOKIE = self::stripslashesDeep($_COOKIE);

            reset($_GET);
            reset($_POST);
            reset($_COOKIE);
        }

        /** 设置异常截获函数 */
        set_exception_handler(array('Typecho_Common', 'exceptionHandle'));
    }

代码中ini_set( 'display_errors', 'On' );是老高自己加的,便于debug,请无视。此方法的主要工作是注册autoload,如果系统打开了magic_quotes_gpc,就使用stripslashesDeep处理输入数据,去除系统自动加入的/,最后接管了系统的异常截获。

config.inc.php完成使命后,控制权又回到了index.php文件。

紧接着执行了Typecho_Widget::widget('Widget_Init'),Typecho_Widget哪里来的?请研究一下init阶段的autoload方法,把类名中的_\替换为/,最后加上.php,这样类名就被映射到了一个确定的文件了。以Typecho_Widget为例,系统将得到Typecho/Widget.php,由于系统核心文件都在var下,那么最终的路径即var/Typecho/Widget.php。所以我们就得到了这样的规律,类名被_分开,类一般会以Typecho或Widget开头,分别对应着文件夹Typecho或Widget,之后就根据剩下的片段去找最终的文件名即可!

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@include_once str_replace(array('\\', '_'), '/', $className) . '.php';

Widget类是整个系统的核心类(抽象类),他抽象出了几个很不错的功能,这一点Widget内部方法与接口有介绍,需要注意的是魔术方法__get会在保护属性row row也让Widget类增色不少,__call和push方法也需要留意。

下面介绍的是Typecho_Widget::widget方法,widget方法其实是一个工厂方法,他接受一个类名,初始化输入输出对象,一并传入目标类名,执行了目标类的构造方法和execute方法,并将实例化的类保存在self::$_widgetPool数组中。execute十分重要,在thinkphp中有一个异曲同工的方法,叫_initalize,位于controller父类中。

以index.php文件中Typecho_Widget::widget('Widget_Init')为例,Typecho_Widget的widget接收到'Widget_Init',初始化var/Widget/Init.php中的Widget_Init类后,执行了其execute方法。该方法又调用了$this->widget('Widget_Options'),即自己又初始化了Widget_Options类,Widget_Options类读出了user = 0的所有系统配置,并将Widget_Options保存在局部变量$options里,进行了一系列的初始化工作。值得留意的地方:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# $options包含了路由信息
# 系统在这一步才执行了解析PathInfo动作
$this->request->getPathInfo();
# 路由器在此初始化
Typecho_Router::setRoutes
# 所有插件在此初始化
Typecho_Plugin::init($options->plugins);
# 下面还有初始化回执,设定了返回的编码和类型
$this->response->setCharset($options->charset);
$this->response->setContentType($options->contentType);
# 时区设置还有session初始化
# 最后打开缓冲

至此Typecho_Widget::widget('Widget_Init')执行完毕!这时系统初始化正式完毕,开始真正的'工作'!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2014-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
typecho源代码解析4 - 业务逻辑
由路由表中的正则表达式我们能看出首页的URL为https://blog.phpgao.com/或http://www.phpgao.com,并且不接受任何参数。
老高的技术博客
2022/12/28
2680
typecho源代码解析4 - 业务逻辑
为你的 typecho 博客开启 gzip 压缩功能
typecho 这款程序已经足够轻量级了,比起我之前用的 wordpress 和 Emlog 速度快的没话说,但是折腾无止境,速度的诱惑力太大,虽然本来也不慢我还是要优化,今天分享一下给 typecho 开启 gzip 功能以提快你博客的速度! 看下面 在博客的 index.php 中添加一段代码,代码如下: /** 开启gzip压缩, add by yovisun */ ob_start('ob_gzhandler'); 下面放出我改过后完整的 index.php 文件内容:
杨逸轩
2018/06/14
1.4K0
Typecho语法大全/Typech常用函数/Typecho调用方法
32、导航页面列表调用隐藏特定的页面 这个演示隐藏了 al­bum 和 search 两个页面
目的地-Destination
2023/03/06
2K0
typecho插件编写教程5 - 核心代码
分析一下,发布文章的时候,我们需要的信息就是当前文章的URL,我们需要想办法从contents、 class中拿到他。
老高的技术博客
2022/12/28
3900
访问网站首页 index.php,跟着执行流程走一遍
访问网站首页 index.php,跟着执行流程走一遍,细节不深究,碰到不太明白的变量,直接var_dump()输出看看: 1. index.php——首页入口页面,版本判定、是否开启调试、引入 ThinkPHP框架 路径:‘./index.php‘ 判断PHP版本需是5.3.0以上:version_compare(PHP_VERSION,‘5.3.0‘,‘<‘); 系统调试设置:define(‘APP_DEBUG‘, true ); 应用目录设置:define ( ‘APP_PATH‘, ‘./Application/‘ ); 缓存目录设置:define ( ‘RUNTIME_PATH‘, ‘./Runtime/‘ ); 引入ThinkPHP:require ‘./ThinkPHP/ThinkPHP.php‘; 2. ThinkPHP.php——ThinkPHP框架的入口文件,定义各种常量、判断系统环境,初始化应用 路径:‘./ThinkPHP/ThinkPHP.php‘ 定义常量:版本号 THINK_VERSION、URL 模式定义(4 种模式)、类文件后缀 EXT、是否为SAE 环境、常用的系统路径常量(如Think类库目录、应用公共目录、缓存目录、配置目录等); 引入核心类Think.class.php:require CORE_PATH.‘Think‘.EXT; 应用初始化:Think\Think::start(); //命名空间\类名::方法(); //这里用到了命名空间 3. Think.class.php——框架的核心类,初始化应用程序,加载配置、类库,错误和异常处理,实例化对象 路径:‘./ThinkPHP/Library/Think/Think.class.php‘ 声明:Think\Think start()方法:加载需用的类、配置、语言包,是否需要缓存,运行应用 ①设定方法: spl_autoload_register(‘Think\Think::autoload‘); 自动加载类的方法,以及一些错误异常处理方法; ②分布式存储类初始化,用于读取、写入、删除文件;Storage::connect(STORAGE_TYPE); ③开发模式不缓存加载的核心类文件$runtimefile,用户模式将所有需引用的类并到同一个文件中缓存,加快后续访问速度。 ④加载应用的配置文件、需要的函数和类文件、行文扩展等文件路径的数组$mode;include ‘./ThinkPHP/Mode/common.php‘ ⑤循环加载处理$mode 数组中的各路径的文件; ⑥检查应用目录结构是否存在,不存在则会默认生成目录结构;(这个针对ThinkPHP新建一个应用,首次访问时使用) ⑦开始运行应用 App::run(); 即:‘./ThinkPHP/Library/Think/App.class.php‘ 4. App.class.php——加载公共文件配置、URL解析、调用对应的控制器方法 路径:‘./ThinkPHP/Library/Think/App.class.php‘ 声明:Think\App run()方法: ①App::init(); load_ext_file 加载应用的公共文件(./Application/Common/Common/)配置 (./Application/Common/Conf) Think\Dispatcher::dispatch(); URL解析,获取控制器 index、方法 index ②App::exec(); 执行应用程序,及新建控制器HomeConstroller 的实例,即对象; 创建控制器实例:$module = controller(CONTROLLER_NAME,CONTROLLER_PATH); 即=new IndexController(); 利用 php 反 射 机 制 获 取 action 方 法 对 象 , $method = new \ReflectionMethod($module, $action); 执行这个方法:$method->invoke($module); //无参数时执行,访问首页默认执行这个 $method->invokeArgs($module,$args); //有参数时执行; 以上即执行了控制器 ./Application/Hom
PM吃瓜
2019/08/13
4.1K0
Typecho制作单独Tag标签聚合页面 调用所有标签方式
一般我们在自己制作或者选择的其他人Typecho主题的时候,都会默认单篇文章会有调用单篇文章的标签Tag,且可能在侧栏或者底部会调用部分热门的Tag。不过我们有些朋友希望需要将所有的Tags聚合到一个页面,这里就需要独立制作一个标签模板页面。
老蒋
2021/12/24
1.2K0
关于typecho的一些样式代码
循环页面、分类、标签 <!--循环显示页面--> <?php $this->widget('Widget_Contents_Page_List')->to($pages); ?>
用户7146828
2021/08/09
1.3K0
Typecho主题模板制作快速入门简易教程
Typecho主题的制作并不难,(以下称模板)只要写好了HTML和CSS,嵌套模板就非常简单了,无需了解标签的内部结构,只要会使用,就能迅速完成模板。
梦溪
2021/08/09
5.9K0
thinkphp6.0 底层源码分析 - 类的自动加载、配置文件初始化
因为工作的需要,深入研究了一下thinkphp的源码,也算是对php知识的一个回归,工作这么多年,我一直坚信php是最好的Web编程语言,它可以做到成本和效率的一个平衡,知其然,更要知其所以然才是高手修炼之道
stark张宇
2023/10/21
6180
typecho插件编写教程3 - 保存配置
如上代码所示,我们在激活和卸载插件方法中有返回值,所以在相应操作时会有相应的提示。
老高的技术博客
2022/12/28
4150
typecho插件编写教程3 - 保存配置
Typecho 文章内链接在新窗口打开实现方式
  默认情况文章中如果有添加链接,那么是从当前窗口跳转的,并且外链没有添加标签,不利于SEO,文章内链接新窗口并添加标签如下。
宜轩
2022/12/29
1.6K0
Typecho 文章内链接在新窗口打开实现方式
实战技巧 | 知其代码方可审计
终于来到了代码审计篇章。希望看了朋友有所收获,我们通常把代码审计分为黑盒和白盒,我们一般结合起来用。
辞令
2020/09/17
1.7K0
实战技巧 | 知其代码方可审计
PHP反序列化进阶学习与总结
序列化(串行化):将变量转换为可保存或传输的字符串的过程;反序列化(反串行化):将字符串转化成原来的变量使用。
Ms08067安全实验室
2022/09/26
6500
twitter主题实现前台发文章
博客原来主题是仿推特的一款主题,文章样式特别多,所以咱也是特别喜欢,也总喜欢搞来搞去的,今晚也是从 @XiaoFans 那里发现了新东西,实现主题前台的发文,前台发文挺新颖的,也是特别想动手实现一下,前台发文是博客的一大特点,可以更加方便,目前只能实现发送文章,后期 @XiaoFans 会加更多功能,上传图片和表情之类的,其他主题原理一样,过程适用于typecho博客,一起来学习下吧
qiangzai
2021/12/21
6760
twitter主题实现前台发文章
typecho在sae安装
<?php /** * Typecho Blog Platform * * @copyright Copyright (c) 2008 Typecho team (http://www.type
2021/11/08
3390
typecho博客配置腾讯云对象存储COS加速
采用Joe主题的typecho的博客运行也有一段时间了。最近发现访问不太稳定,等很长时间都打不开,用chrome调试工具发现cdn.jsdelivr.net长时间加载不出来,还有随着文章越来越多,文章图片的加载也有点慢。正好,腾讯腾讯云赠送了半年的COS对象存储,用来做博客加速刚刚好。
IT不难
2022/05/20
1.3K0
typecho博客配置腾讯云对象存储COS加速
typecho漏洞分析与HCTF实战
typecho漏洞分析与HCTF实战 0x00前记 通过最近的比赛,决定沉淀下来,从复现cms开始慢慢锻炼自己的审计能力,毕竟这个年头的CTF,不会审计只能活在边缘了,今天为大家带了typecho漏洞
安恒网络空间安全讲武堂
2018/02/06
1.4K0
typecho漏洞分析与HCTF实战
看代码学安全(11) - unserialize反序列化漏洞
大家好,我们是红日安全-代码审计小组。最近我们小组正在做一个PHP代码审计的项目,供大家学习交流,我们给这个项目起了一个名字叫 PHP-Audit-Labs 。现在大家所看到的系列文章,属于项目 第一阶段 的内容,本阶段的内容题目均来自 PHP SECURITY CALENDAR 2017 。对于每一道题目,我们均给出对应的分析,并结合实际CMS进行解说。在文章的最后,我们还会留一道CTF题目,供大家练习,希望大家喜欢。下面是 第11篇 代码审计文章:
用户1631416
2018/12/19
1K0
看代码学安全(11) - unserialize反序列化漏洞
typecho插件编写教程6 - 调用接口
此篇我们开始调用接口,我们在插件类中新定义一个方法,起名为send_post,在方法中我们通过系统配置获取接口调用地址。
老高的技术博客
2022/12/28
4380
从CTF中学习PHP反序列化的各种利用方式
为了方便数据存储,php通常会将数组等数据转换为序列化形式存储,那么什么是序列化呢?序列化其实就是将数据转化成一种可逆的数据结构,自然,逆向的过程就叫做反序列化。
Ms08067安全实验室
2022/09/26
3.5K0
推荐阅读
相关推荐
typecho源代码解析4 - 业务逻辑
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档