插件数据存储(2):自建数据表


如果上面的 Storage 数据存储方式无法满足更复杂的数据结构存储要求,插件可以自建数据库表存储数据。

创建插件数据表

利用上面提到的【事件回调】机制在自定义的 callback 函数中实现创建插件自己的表,下面给出一个简单的示例。

<?php
!defined('EMLOG_ROOT') && exit('access denied!');

//  初始化插件数据表
function callback_init() {
    $db = MySql::getInstance();
    $charset = 'utf8mb4';
    $type = 'InnoDB';
    $table = DB_PREFIX . 'stats';
    $add = "ENGINE=$type DEFAULT CHARSET=$charset;";
    $sql = "
    CREATE TABLE IF NOT EXISTS `$table` (
        `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
        `gid` int(11) unsigned NOT NULL,
        `title` varchar(255) NOT NULL default '',
        `views` bigint(11) unsigned NOT NULL default 0,
        `comments` bigint(11) unsigned NOT NULL default 0,
        `date` date NOT NULL,
        PRIMARY KEY (`id`),
        UNIQUE KEY `date_gid` (`date`,`gid`)
    )" . $add;
    $db->query($sql);
}

// 插件删除时删除插件数据表
function callback_rm() {
    $sql = "DROP TABLE IF EXISTS `" . DB_PREFIX . "stats`";
    $db = MySql::getInstance();
    $db->query($sql);
}

下面PHP代码是一个完整的维护插件自建数据库表的 callback 示例,可以直接用于自己插件 xxxx_callback.php ,修改对应建表语句即可。

<?php
/**
 * 插件回调
 */
!defined('EMLOG_ROOT') && exit('error!');

/**
 * 插件激活回调
 */
function callback_init(){
    Init_Database_Callback::instance()->pluginInit();
}

/**
 * 插件更新回调
 */
function callback_up(){
    Init_Database_Callback::instance()->pluginUp();
}

/**
 * 插件删除回调
 */
function callback_rm(){
    Init_Database_Callback::instance()->pluginRm();
}

/**
 * 数据表操作类
 */
class Init_Database_Callback {
    //实例
    private static $instance;
    //数据库实例
    private $db;
    //数据表配置
    private $option = [
        //数据表名称
        "tableName"             => DB_PREFIX."toEverColor_list",
        //卸载插件是否删除数据表 - true/false 对应 删除/不删除 默认为false(不删除)
        "checkDeleteTable"      => false,
        //数据表字段信息,字段=>sql语句,请勿写错,程序根据这个来创建和检测字段
        "fieldData"             => [
            "id"            => "`id` int(50) NOT NULL AUTO_INCREMENT",
            "gid"           => "`gid` int(50) NOT NULL COMMENT '文章ID'",
            "color"         => "`color` varchar(200) DEFAULT NULL COMMENT '颜色'",
            "weight"        => "`weight` enum('n','y') DEFAULT 'n' COMMENT '是否加粗(默认不加粗)'",
            "font_size"     => "`font_size` int(50) DEFAULT NULL COMMENT '字号'",
            "line_through"  => "`line_through` enum('n','y') DEFAULT 'n' COMMENT '删除线'",
        ]
    ];

    /**
     * 私有构造函数,保证单例
     */
    private function __construct(){
        //数据库实例赋值
        $this->db = Database::getInstance();
    }

    /**
     * 单例入口
     */
    public static function instance(){
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * 检测数据表是否存在
     */
    public function checkDataTable() {
        if (isset($this->option['tableName'])) {
            $query = $this->db->query("SHOW TABLES LIKE '{$this->option['tableName']}'");
            if ($this->db->num_rows($query) > 0) {
                return true;
            }
            return false;
        }
        return false;
    }

    /**
     * 检测数据表中字段是否存在 - 指定字段名
     */
    public function checkDataField($fieldName = '') {
        if (!empty($fieldName) && $this->checkDataTable()) {
            $query = $this->db->query("SHOW COLUMNS FROM {$this->option['tableName']} LIKE '{$fieldName}'");
            if ($this->db->num_rows($query) > 0) {
                return true;
            }
            return false;
        }
        return false;
    }

    /**
     * 数据表创建函数
     */
    private function addDataTable() {
        if (!empty($this->option) && is_array($this->option) && isset($this->option['fieldData']) && is_array($this->option['fieldData'])) {
            $sql = "CREATE TABLE IF NOT EXISTS {$this->option['tableName']} (";
            foreach ($this->option['fieldData'] as $field => $fieldSql) {
                $sql .= $fieldSql . ',';
            }
            $sql .= " PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='标题改色表';";
            $this->db->query($sql);
        }
    }

    /**
     * 检测数据表字段是否存在,不存在则创建字段
     */
    private function addDataTableField() {
        if (!empty($this->option) && is_array($this->option) && isset($this->option['fieldData']) && is_array($this->option['fieldData'])) {
            $preForeachData = '';
            foreach ($this->option['fieldData'] as $field => $fieldSql) {
                if (!$this->checkDataField($field)) {
                    $after = !empty($preForeachData) ? " AFTER {$preForeachData}" : '';
                    $this->db->query("ALTER TABLE {$this->option['tableName']} ADD COLUMN {$fieldSql}{$after}");
                }
                $preForeachData = $field;
            }
        }
    }

    /**
     * 插件启用执行函数
     */
    public function pluginInit() {
        if ($this->checkDataTable()) {
            $this->addDataTableField();
        } else {
            $this->addDataTable();
        }
    }

    /**
     * 插件更新执行函数
     */
    public function pluginUp() {
        $this->addDataTableField();
    }

    /**
     * 插件卸载执行函数
     */
    public function pluginRm() {
        if (isset($this->option['checkDeleteTable']) && $this->option['checkDeleteTable'] === true) {
            $this->db->query("DROP TABLE {$this->tableName}");
        }
    }
}

读取插件数据表

<?php
   // 读取插件数据
   function getDetail($id) {
   $db = MySql::getInstance();
   $row = $db->once_fetch_array("SELECT * FROM " . DB_PREFIX . "stats WHERE id = " . $id);

    $row['xxxx']
    ……
}
  • 分享:
发表评论 说点什么
登录