安装Stat插件无法激活

楚天乐 5474 1 条

错误提示:“数据表检测失败,统计插件启用失败”

解决过程:
打开插件源代码看了下,

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

打赏

微信打赏

支付宝打赏



网友最新评论(1)

好好学习下

May 31st, 2022
发表我的评论
昵称 (必填)
邮箱 (必填)
网址
执行时间: 53.896903991699 毫秒