来自博客:神的尾巴,原文链接

已经提交到github,DB组件代码,代码质量一般,大家将就着看 :)

使用PDO

基于PDO,PDO提供了一个数据访问抽象层,能够支持多种数据库。另外使用预处理语句,能有效预防SQL注入

预处理语句是分两次发送到数据库的,第一次发送语义,例如: selecet * from user where username = ? and password = ? limit 1,如果不使用预处理语句,就可能导致sql注入。例如,用户名:godtail,密码:123456 or 1 = 1。但是如果是预处理语句的话,会把语义和数据分两次发送到数据库。这样就防止数据影响SQL语义,导致SQL注入(需要设置PDO::ATTR_EMULATE_PREPAREStrue,否则会在PHP模拟处理,进行数据转义)。

支持多个数据库

定义静态变量用来接收配置文件,用来配置单个或者多个数据库。

#单个数据库
return [
    'dbType' => 'Mysql',
    'host' => '127.0.0.1',
    'database' => 'blog',
    'port' => '3306',
    'user' => 'root',
    'password' => 'root',
    'charset' => 'utf8'
]

#多个数据库
return [
    'main' => [
        'dbType' => 'Mysql',
        'host' => '127.0.0.1',
        'database' => 'blog',
        'port' => '3306',
        'user' => 'root',
        'password' => 'root',
        'charset' => 'utf8'
    ]
    'log' => [
        'dbType' => 'Mysql',
        'host' => '127.0.0.1',
        'database' => 'blog_log',
        'port' => '3306',
        'user' => 'root',
        'password' => 'root',
        'charset' => 'utf8'
    ]
]

使用单例,防止多次初始化同一个DB,保证一个DB只有一个连接。

调用方法如下:

#单个
$db = Db::instance();

#多个
$dbLog = DB::instance('log');

每种数据库支持的操作和连接方式不一样,使用抽象类Driver实现通用功能。然后,每种数据库驱动继承Driver,负责实现例如连接方式等,不同数据库的特有功能。在实例化的时候,会根据配置的dbType,返回每个db对于的驱动。

支持类似TP or Laravel的连贯操作

我把连贯操作分为两类:

  1. 设置数据的dataOpt。例如:where, field, limit...

  2. 执行最后查询或修改操作的endOpt。例如: find, select...

在抽象类Driver,定义protected属性,$dataOpt$endOpt,用来标记,每个db支持的dataOptendOpt,例如Mysql支持limitSQL Server不支持(或者说实现的方式不一致)。

dataOpt实现接口DataOpt,提供方法parse,返回数据包含,sqlPart用来拼装sql,paramssql ?对应的参数。

interface DataOpt
{
    /**
     * @return array
     *  [
     *      'sqlPart' => ' where name = ?',
     *      'params' => ['godtail']
     *  ]
     */
    public static function parse($arguments);
}

在调用的时候,使用Driver的魔法方法__call,如果是dataOpt,设置数据到$data变量,如果是endOpt,根据endOpt设置的执行顺序,执行对于数据的解析。

判断是否有endOptAfter方法或endOptBefore,依次调用(后面打算使用Hook实现)。


神的尾巴
2.2k 声望15 粉丝