错误提示:“数据表检测失败,统计插件启用失败”
解决过程:
打开插件源代码看了下,
class Stat_Plugin implements Typecho_Plugin_Interface{
}
// 来看看这个接口的定义
/**
* 插件接口
*
* @package Plugin
* @abstract
*/
interface Typecho_Plugin_Interface
{
/**
* 启用插件方法,如果启用失败,直接抛出异常
*/
public static function activate();
/**
* 禁用插件方法,如果禁用失败,直接抛出异常
*/
public static function deactivate();
/**
* 获取插件配置面板
*/
public static function config(Typecho_Widget_Helper_Form $form);
/**
* 个人用户的配置面板
*/
public static function personalConfig(Typecho_Widget_Helper_Form $form);
}
这样看很明显了,启用插件会调用插件代码的activate方法,现在我们来看下activate方法代码
class Stat_Plugin implements Typecho_Plugin_Interface
{
/**
* 激活插件方法,如果激活失败,直接抛出异常
*
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function activate()
{
$info = Stat_Plugin::sqlInstall();
Typecho_Plugin::factory('Widget_Archive')->singleHandle = array('Stat_Plugin', 'singleHandle');
Typecho_Plugin::factory('Widget_Archive')->select = array('Stat_Plugin', 'selectHandle');
return _t($info);
}
//SQL创建
public static function sqlInstall()
{
$db = Typecho_Db::get();
$type = explode('_', $db->getAdapterName());
$type = array_pop($type);
$prefix = $db->getPrefix();
try {
$select = $db->select('table.contents.views')->from('table.contents');
$db->query($select, Typecho_Db::READ);
return '检测到统计字段,插件启用成功';
} catch (Typecho_Db_Exception $e) {
$code = $e->getCode();
if(('Mysql' == $type && 1054 == $code ) ||
('SQLite' == $type && ('HY000' == $code || 1 == $code))) {
try {
if ('Mysql' == $type) {
$db->query("ALTER TABLE `".$prefix."contents` ADD `views` INT( 10 ) NOT NULL DEFAULT '0' COMMENT '页面浏览次数';");
} else if ('SQLite' == $type) {
$db->query("ALTER TABLE `".$prefix."contents` ADD `views` INT( 10 ) NOT NULL DEFAULT '0'");
} else {
throw new Typecho_Plugin_Exception('不支持的数据库类型:'.$type);
}
return '建立统计字段,插件启用成功';
} catch (Typecho_Db_Exception $e) {
$code = $e->getCode();
if(('Mysql' == $type && 1060 == $code) ) {
return '统计字段已经存在,插件启用成功';
}
throw new Typecho_Plugin_Exception('统计插件启用失败。错误号:'.$code);
}
}
throw new Typecho_Plugin_Exception('数据表检测失败,统计插件启用失败。错误号:'.$code);
}
}
好了,我们看到最后抛出异常代码:
throw new Typecho_Plugin_Exception('数据表检测失败,统计插件启用失败。错误号:'.$code);
这就是错误点了。
添加一行代码,看看try,catch捕获到了什么错误
$code = $e->getCode();
//添加这行代码
echo $code . "************";exit();
if(('Mysql' == $type && 1054 == $code ) || ('SQLite' == $type && ('HY000' == $code || 1 == $code))) {
输出错误码为42S22。很明显这个错误并没有得到处理。
解决方案:增加一条错误处理条件就好了。我用的MySQL数据库,这么写就好:
if(('Mysql' == $type && (1054 == $code || $code == '42S22') ) || ('SQLite' == $type && ('HY000' == $code || 1 == $code))) {
这个42S22错误到底是什么呢?
是数据表中列没有定义。非常make sense,当数据表所需字段不存在的时候,创建所需字段即可。
为什么作者没处理这个错误码?
我猜作者大约是用MySQLi习惯了没有测试PDO吧,42S22是PDO Exception。
PDOException: SQLSTATE[42S22]: Column not found
好好学习下