來自博客:神的尾巴,原文連接php
已經提交到github,DB組件代碼,代碼質量通常,你們將就着看 :)git
基於PDO,PDO提供了一個數據訪問抽象層,可以支持多種數據庫。另外使用預處理語句
,能有效預防SQL注入
。github
預處理語句是分兩次發送到數據庫的,第一次發送語義,例如:
selecet * from user where username = ? and password = ? limit 1
,若是不使用預處理語句,就可能致使sql注入
。例如,用戶名:godtail
,密碼:123456 or 1 = 1
。可是若是是預處理語句的話,會把語義和數據分兩次發送到數據庫。這樣就防止數據影響SQL語義,致使SQL注入(須要設置PDO::ATTR_EMULATE_PREPARES
爲true
,不然會在PHP
模擬處理,進行數據轉義)。sql
定義靜態變量用來接收配置文件,用來配置單個或者多個數據庫。數據庫
#單個數據庫 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只有一個鏈接。.net
調用方法以下:code
#單個 $db = Db::instance(); #多個 $dbLog = DB::instance('log');
每種數據庫支持的操做和鏈接方式不同,使用抽象類Driver
實現通用功能。而後,每種數據庫驅動繼承Driver,負責實現例如鏈接方式等,不一樣數據庫的特有功能。在實例化的時候,會根據配置的dbType
,返回每一個db對於的驅動。blog
我把連貫操做分爲兩類:繼承
設置數據的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實現)。