来自博客:神的尾巴,原文链接
已经提交到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_PREPARES
为true
,否则会在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的连贯操作
我把连贯操作分为两类:
设置数据的
dataOpt
。例如:where
,field
,limit
...执行最后查询或修改操作的
endOpt
。例如:find
,select
...
在抽象类Driver
,定义protected属性,$dataOpt
和$endOpt
,用来标记,每个db支持的dataOpt
和endOpt
,例如Mysql
支持limit
,SQL Server
不支持(或者说实现的方式不一致)。
dataOpt实现接口DataOpt
,提供方法parse
,返回数据包含,sqlPart
用来拼装sql,params
是sql ?
对应的参数。
interface DataOpt
{
/**
* @return array
* [
* 'sqlPart' => ' where name = ?',
* 'params' => ['godtail']
* ]
*/
public static function parse($arguments);
}
在调用的时候,使用Driver的魔法方法__call
,如果是dataOpt
,设置数据到$data
变量,如果是endOpt
,根据endOpt
设置的执行顺序,执行对于数据的解析。
判断是否有endOptAfter
方法或endOptBefore
,依次调用(后面打算使用Hook实现)。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。