前言
昨天迁移完博客站就睡了,今早发现博客站换上Joe主题后,首页文章列表竟然无法正常加载,一直显示loading如图:
后台和控制台也没有任何报错
文章列表无法加载,通常是数据库查询或Widget调用问题。怀疑是Typecho 1.3.0改了一些关键实现,于是开始Debug,发现如下:
Typecho 1.3.0 的变化
- 负责处理数据查询、模板渲染等功能的Widget系统经过重构
数据库访问层从简单的静态调用升级为更现代的面向对象设计
命名空间变化
Typecho在1.3.0版本中引入了现代PHP的命名空间机制:
- 旧版本: Typecho_Db::get()
新版本: Typecho\Db::get()
Widget类体系重构
- 旧版本: Widget_Abstract_Contents
新版本: Widget\Base\Contents 或 Widget\Contents\Post\Admin
路由系统升级
- 旧版本使用 Typecho_Router::post()
- 新版本的路由注册机制发生了变化
解决思路
概览
了解了问题在哪,就可以着手解决了。处理这个变动,只需要把类似$db = Typecho_Db::get();的语句改为$db = Typecho\Db::get();即可。
为了保证前向兼容,可以这样写:
/* 兼容Typecho 1.3.0+的数据库类 */
if (class_exists('Typecho\Db')) {
$db = Typecho\Db::get();
} else {
$db = Typecho_Db::get();修改步骤
第一步:修复Widget类继承问题
文件:widget.php
问题: Joe主题的自定义Widget类继承了旧版本的类名
// 原代码
class Widget_Contents_Hot extends Widget_Abstract_Contents修复: 添加版本检测和兼容性处理
/* 兼容Typecho 1.3.0+版本检测 */
if (class_exists('Widget\Base\Contents')) {
// 新版本基类
class Widget_Contents_Hot extends Widget\Base\Contents {
// ... 实现代码
}
} else {
// 旧版本基类
class Widget_Contents_Hot extends Widget_Abstract_Contents {
// ... 实现代码
}
}同时修复了数据库排序常量:
// 旧版本
->order('table.contents.created', Typecho_Db::SORT_DESC)
// 新版本兼容
->order('table.contents.created', 'DESC')第二步:修复路由系统
文件: core.php
问题: 旧版本的路由注册方式在新版本中失效
修复: 添加路由系统兼容代码
/* 兼容Typecho 1.3.0+的路由系统 */
if (class_exists('Typecho\Router')) {
// 新版本路由注册
if (method_exists('Typecho\Router', 'post')) {
Typecho\Router::post('/joe/api', 'Joe_Action');
}
} else {
// 旧版本路由注册
Typecho_Router::post('/joe/api', 'Joe_Action');
}第三步:修复数据库调用
修复的文件:
functions.phpfunction.phproute.php
问题: 所有直接调用 Typecho_Db::get() 的地方都会在新版本中报错
修复策略: 在每个数据库调用前添加版本检测/* 兼容Typecho 1.3.0+的数据库类 */ if (class_exists('Typecho\Db')) { $db = Typecho\Db::get(); } else { $db = Typecho_Db::get(); }第四步:添加类别名映射
文件:factory.php
解决思路: 为了让旧代码能够无缝使用新类名,添加类别名映射:/* 兼容Typecho 1.3.0+的Widget Helper Form类 */ if (class_exists('Typecho\Widget\Helper\Form')) { class_alias('Typecho\Widget\Helper\Form', 'Typecho_Widget_Helper_Form'); } /* 兼容Typecho 1.3.0+的数据库类 */ if (class_exists('Typecho\Db')) { class_alias('Typecho\Db', 'Typecho_Db'); } /* 兼容Typecho 1.3.0+的Widget类 */ if (class_exists('Typecho\Widget')) { class_alias('Typecho\Widget', 'Typecho_Widget'); } /* 兼容Typecho 1.3.0+的Abstract Contents类 */ if (class_exists('Widget\Contents\Post\Admin')) { class_alias('Widget\Contents\Post\Admin', 'Widget_Abstract_Contents'); } elseif (class_exists('Widget\Base\Contents')) { class_alias('Widget\Base\Contents', 'Widget_Abstract_Contents'); }
最终能用的版本
如果你感觉手动修改有些麻烦,也可以直接使用我改好的版本:
Joe7.7.1-typecho1.3.0-fix.zip
博主,joe主题在typecho1.3.0版本上,页面链接无法正确生成链接,你可以看看怎么解决。
点击页面分类下面的友联,跳转当前阅览的页面,并不是相应的友联页面,只要是页面下的链接都是这样。