如何寫一個(gè)屬于自己的數(shù)據(jù)庫(kù)封裝(1)
發(fā)表時(shí)間:2023-09-10 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]寫在前頭依然在前進(jìn)的菜鳥一只,錯(cuò)誤什么的請(qǐng)輕噴指出對(duì)于數(shù)據(jù)庫(kù)連接由于較淺的工作經(jīng)驗(yàn)所以無(wú)法完全覆蓋,較復(fù)雜的query可能會(huì)有意想不到的bug所以本系列只提供思路,成熟穩(wěn)定的數(shù)據(jù)庫(kù)封裝有請(qǐng)自行搜索編寫該系列的初衷就是為了拋磚引玉, 在每一節(jié)的后端,我都會(huì)提出一些個(gè)人疑問(wèn)(或無(wú)),希望能引出大神為我...
寫在前頭
依然在前進(jìn)的菜鳥一只,錯(cuò)誤什么的請(qǐng)輕噴指出
對(duì)于數(shù)據(jù)庫(kù)連接由于較淺的工作經(jīng)驗(yàn)所以無(wú)法完全覆蓋,較復(fù)雜的query可能會(huì)有意想不到的bug
所以本系列只提供思路,成熟穩(wěn)定的數(shù)據(jù)庫(kù)封裝有請(qǐng)自行搜索
編寫該系列的初衷就是為了拋磚引玉, 在每一節(jié)的后端,我都會(huì)提出一些個(gè)人疑問(wèn)(或無(wú)),希望能引出大神為我解答迷惑
使用的php版本為7.0+,該系列并不向下兼容,還在5.6版本的童鞋們快過(guò)來(lái)玩呀
數(shù)據(jù)庫(kù)封裝參考了laravel的源代碼, 如有雷同, 不是巧合
最終效果
假設(shè)我們有一個(gè)表,名'Actor', 經(jīng)過(guò)簡(jiǎn)單設(shè)置, 可以直接如下調(diào)用
$a = Actor::select('first_name', 'last_name')
->where('first_name', 'NICK')
->where('last_name', 'WAHLBERG')
->first()
var_dump($a);
返回格式
object(Actor)[11]
public 'first_name' => string 'NICK' (length=4)
public 'last_name' => string 'WAHLBERG' (length=8)
返回的數(shù)據(jù)依然可操作(update/delete)
$a->update(...);
$a->delete();
常見(jiàn)的數(shù)據(jù)庫(kù)連接寫法
對(duì)php有一定了解的人都知道,相比已被淘汰的mysql或取而代之的mysqli, pdo 可以避免SQL注入式攻擊, 更安全, 而且面向?qū)ο?/a>, 所以以下以pdo作為例子
<?php
$driver='mysql'; //數(shù)據(jù)庫(kù)類型
$host='localhost'; //數(shù)據(jù)庫(kù)主機(jī)名
$db = 'sakila'; //數(shù)據(jù)庫(kù)名稱
$username='root'; //數(shù)據(jù)庫(kù)連接用戶名
$password=''; //數(shù)據(jù)庫(kù)密碼
$dsn="$driver:host=$host;dbname=$db";
try {
$pdo= new PDO($dsn, $username, $password); //初始化一個(gè)PDO對(duì)象
$sql = "select * from actor";
$res = $pdo->query($sql); // 從actor中獲取所有數(shù)據(jù)
foreach($res as $row) echo $row['first_name']."<br>";
} catch (PDOException $e) {
die($e->getMessage());
}
以上例子非常簡(jiǎn)潔, 當(dāng)一個(gè)項(xiàng)目逐漸成長(zhǎng),日漸復(fù)繁的時(shí)候,那么我們需要一個(gè)封裝類來(lái)減少代碼的重復(fù)性, 就像平時(shí)自行寫的一些輔助函數(shù), 不過(guò)封裝類略微進(jìn)階而已。
基本思路
那么,應(yīng)該怎么寫呢?
首先, 平時(shí)我們要簡(jiǎn)略一些代碼, 都會(huì)自行編寫一些輔助函數(shù),比如我個(gè)人有個(gè)不好的習(xí)慣,不喜歡用編輯器的調(diào)試功能(畫外音:我用的是sublime text 3),那么debug的時(shí)候一開(kāi)始都是這么寫的
$a = "is bug";
die(var_dump($a)); // 輸出變量并且停止運(yùn)行之后的代碼
/***從xdebug得知bug出現(xiàn)在這一行,所以查看上一行的邏輯與數(shù)據(jù) ***/
die(var_dump())的出場(chǎng)率略高, 因此我將它們寫成了一個(gè)輔助函數(shù)
function dd($var) {
die(var_dump($var));
}
同樣道理,在數(shù)據(jù)庫(kù)讀取的時(shí)候,select的出場(chǎng)率極高, 所以簡(jiǎn)單的包裹一下
function select($pdo, $table, $require, $where = []) {
$w = [];
// 將搜索條件轉(zhuǎn)化為數(shù)據(jù)庫(kù)命令能接受的格式
foreach ($where as $key => &$val)
$w[] = "$key = '$val'";
// 有時(shí)候并不需要條件,僅僅將所有數(shù)據(jù)取出,因此$where默認(rèn)為空
if(!empty($w)) $w = "where ".implode(', ', $w);
else $w = "";
// 生成sql query
$sql = "select $require from $table $w";
// 將已生成的query帶入pdo實(shí)例
$res = $pdo->query($sql);
// 返回結(jié)果
return $res->fetchAll();
}
例子
select($pdo, 'actor', '*', ['first_name'=>'PENELOPE'])
/**
* 生成sql query => select * from actor where first_name = 'PENELOPE'
**/
總結(jié)一下, 數(shù)據(jù)庫(kù)封裝淺顯的形容就是將參數(shù)帶入輔助函數(shù),讓其自動(dòng)生成SQL命令。
數(shù)據(jù)庫(kù)封裝的架構(gòu)
主要分成四個(gè)文件
Connector.php - 負(fù)責(zé)與數(shù)據(jù)庫(kù)的通信, 請(qǐng)求與返回?cái)?shù)據(jù)庫(kù)數(shù)據(jù)
Model.php - 入口文件,負(fù)責(zé)表的設(shè)置, 并接受請(qǐng)求, 返回回應(yīng)
Grammar.php - 將Builder存儲(chǔ)的請(qǐng)求轉(zhuǎn)化為SQL語(yǔ)句
Builder.php - 核心文件, 存儲(chǔ)Model的請(qǐng)求,調(diào)用Grammar以返回SQL語(yǔ)句, 與參數(shù)變量一并送往Connector以獲取數(shù)據(jù)庫(kù)數(shù)據(jù),再返還給Model
架構(gòu)可能解釋得不太好,但沒(méi)關(guān)系, 接下來(lái)會(huì)慢慢一個(gè)個(gè)的深入解釋
大致如此, 如果可以的話點(diǎn)個(gè)贊,或在下方評(píng)論區(qū)討論, 只有反饋才能推動(dòng)一個(gè)懶癌晚期病患繼續(xù)前行。
以上就是如何寫一個(gè)屬于自己的數(shù)據(jù)庫(kù)封裝(1)的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注php中文網(wǎng)其它相關(guān)文章!
學(xué)習(xí)教程快速掌握從入門到精通的SQL知識(shí)。