menu 学神博客
search
account_circle
让随手写的论坛用上SQLite
学神之女
学神之女
Time:
local_offer share




废话连篇

上次暑假我写了个PHP论坛,嗯,随手写的。现在改成了SQLite3,可以看看这个版本发布

实际上不止是核心数据库变化,我还把配置文件单放在了properties.php里,很多变量的命名也有变化,加入了安装和后台(后台是个残废),包括api.php的返回函数页变得更加的合理了。(简直是个体力活)

不过我不想说那么多,所以本文就是关于我让基于JSON数据库的自制论坛用上SQLite作为数据库的过程,其他内容可以自己查阅推送产生的修改,同样,博主是个语文渣,文笔不好,本文会很烂。

小声说下为什么我当初写这个论坛只用了不到一星期而改论坛却用了一个学期

技术细节

首先,SQLite代码的执行需要用SQL指令,但本人不会,就借助这个库(找不到哪个库了,去我的GitHub库找代码复制粘贴吧,下面的bug都修好了)的代码实现了SQL指令生成。

并不是拿来就用的,这个生成器的addQuotes函数的BUG很多。这个函数极为虐人,它是很多SyntaxError的源头,不过只要加上一下代码,就可以避免很多SyntaxError:

if( is_bool($el) ) $el = $el?'1':'0';//不能用true,false,会制造更多bug
if( is_null($el) ) $el = 'NULL';

然后,老样子,自己封装了一个class来连接数据库,不过SQLite3需要new,所以就没有直接扩展,而选择了静态:

class Database{
    //还是静态好,不需要new
    public static $sqlite;
    public static function launch($file){
        self::$sqlite = new SQLite3($file);
    }
    public static function query($sql,$default=null){
        //单个查询,直接返回第一个
        $ret = self::$sqlite->query($sql);
        return $ret?$ret->fetchArray():$default;
    }
    public static function multiple_query($sql,$default=null){
        //多个查询
        $ret = self::$sqlite->query($sql);
        if(!$ret) return $default;
        $rows = [];
        while($row = $ret->fetchArray()) array_push($rows,$row);
        return $rows;
    }
    public static function execute($sql){
        return self::$sqlite->exec($sql);
    }
    public static function shutdown(){
        self::$sqlite->close();
    }
    /*兼容部分旧版函数,因为全用新函数太麻烦了*/
    private static function addQuotes($el) {
        if( is_array($el) ) {
            $el = array_map(array($this, __FUNCTION__), $el);
        }
        if( is_string($el) ) {
            $el = '\'' . SQLite3::escapeString($el) . '\'';
        }
        if( is_bool($el) ){
            $el = $el?'1':'0';
        }
        if( is_null($el) ){
            $el = 'NULL';
        }
        return $el;
    }
    public static function select($from,$key=null,$value=null){
        if(empty($from)) return null;
        if(empty($key)) return self::$sqlite->query("select * from ".$from)->fetchArray();
        $ret = self::$sqlite->query("select * from ".$from." where ".$key."=".self::addQuotes($value));
        if(!$ret) return null;
        $rows = [];
        while($row = $ret->fetchArray()) array_push($rows,$row);
        return $rows;
    }
    public static function insert($into,$column){
        if(empty($into)||empty($column)) return false;
        $status = self::$sqlite->exec((new SQL)->insert([$column])->into($into)->getSql());
        return $status?$column:false;
    }
    public static function update(){
        /**
         * 我也不会实现,算了
         */
    }
    public static function delete(){
        /**
         * 本来就没实现,这里更不想实现了
         */
    }
}

除此外,已经写好的查询语句还要做一下改动:

<?php
//SQL指令: select * from table where column = value;
Database::select('table','column','value');//原写法,可保留
Database::query((new SQL)->select('*')->from('table')->where('column=','value')->getSql());//也可以是multiple_query
//SQL指令: insert into table (first_column, second_column) VALUES ('value a','value b');
Database::insert('table',['first_column'=>'value a','second_column'=>'value_b']);//原写法,可保留,注意数组要转换
Database::execute((new SQL)->insert([['first_column'=>'value a','second_column'=>'value b']])->into('table')->getSql());
//SQL指令: UPDATE table set another_column=new_value where column=value;
$new_column['another_column']='new_value';
Database::update('table','column','value',$new_column);//原写法,很复杂
Database::execute((new SQL)->update('table')->where('column=','value')->set('another_column','new_value')->getSql());
//别的指令旧版就没实现过

目前还不安全,因为有时候一些危险数据可以造成SQL注入,如这样提供用户名:恒河猴恍恍惚惚'; DELETE FROM table; #

百度了一圈也没有好的解决方案,所以在PHP官网上找到了这样的转义方法解决:

<?php echo SQLite3::escapeString('恒河猴恍恍惚惚\'; DELETE FROM table; #');//输出: 恒河猴恍恍惚惚''; DELETE FROM table; #

综上所述这简单的改动还不算难,但都浪费了我很长时间去找,所以说……去年写代码至今。(其实跨年时我在写作业)


评论

   textsms
   account_circle
昵称不能为空
   email
邮箱格式错误
   language





message 只有 1 条评论QwQ
    学神之女
    Time: 2019-01-17 22:51




    看上去文章有点草,以后再改进吧。


    arrow_back 上一篇
    arrow_back 上一篇
    Happy New Year!
    下一篇 arrow_forward
    如何强制修改网页字体
    下一篇 arrow_forward