首页 > 后端开发 > 正文

php实现框架数据库链接封装 如何写一个属于自己的数据库封装(2)

2023-10-06 07:12:40 | 我爱编程网

大家平时对后端开发都十分关注,今天为大家整理了php实现框架数据库链接封装 如何写一个属于自己的数据库封装(2),下面就随我爱编程网小编一起来看一下吧。

php实现框架数据库链接封装 如何写一个属于自己的数据库封装(2)

如何写一个属于自己的数据库封装(2)


Connector.php负责与数据库通信,增删改读(CRUD)
首先, 建一个Connector类, 并且设置属性
<?php
class Connector {
// 数据库地址前缀,常见的有mysql,slqlsrv,odbc等等等
private $driver = 'mysql';
// 数据库地址
private $host = 'localhost';
// 数据库默认名称, 设置为静态是因为有切换数据库的需求
private static $db = 'sakila';
// 数据库用户名
private $username = 'root';
// 数据库密码
private $password = '';
// 当前数据库连接
protected $connection;
// 数据库连接箱,切换已存在的数据库连接不需要重新通信,从这里取即可
protected static $container = [];
// PDO默认属性配置,具体请自行查看文档
protected $options = [
PDO::ATTR_CASE => PDO::CASE_NATURAL,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
PDO::ATTR_STRINGIFY_FETCHES => false,
];
}以上代码配合注释应该可以理解了所以不多解释了,直接进入函数
buildConnectString - 就是生成DSN连接串, 非常直白
protected function buildConnectString() {
return "$this->driver:host=$this->host;dbname=".self::$db;
}
// "mysql:host=localhost;dbname=sakila;"connect - 连接数据库
public function connect() {
try {
// 连接数据库,生成pdo实例, 将之赋予$connection,并存入$container之中
self::$container[self::$db] = $this->connection = new PDO($this->buildConnectString(), $this->username, $this->password, $this->options);
// 返回数据库连接
return $this->connection;
} catch (Exception $e) {
// 若是失败, 返回原因
// 还记得dd()吗?这个辅助函数还会一直用上
dd($e->getMessage());
}
}setDatabase - 切换数据库
public function setDatabase($db) {
self::$db = $db;
return $this;
}_construct - 生成实例后第一步要干嘛
function construct() {
// 如果从未连接过该数据库, 那就新建连接
if(empty(self::$container[self::$db])) $this->connect();
// 反之, 从$container中提取, 无需再次通信
$this->connection = self::$container[self::$db];
}接下来两个函数式配合着用的,单看可能会懵逼, 配合例子单步调试
$a = new Connector();
$bindValues = [
'PENELOPE',
'GUINESS'
];
dd($a->read('select * from actor where first_name = ? and last_name = ?', $bindValues));返回值
array (size=1)
0 =>
object(stdClass)[4]
public 'actor_id' => string '1' (length=1)
public 'first_name' => string 'PENELOPE' (length=8)
public 'last_name' => string 'GUINESS' (length=7)
public 'last_update' => string '2006-02-15 04:34:33' (length=19)read - 读取数据
public function read($sql, $bindings) {
// 将sql语句放入预处理函数
// $sql = select * from actor where first_name = ? and last_name = ?
$statement = $this->connection->prepare($sql);
// 将附带参数带入pdo实例
// $bindings = ['PENELOPE', 'GUINESS']
$this->bindValues($statement, $bindings);
// 执行
$statement->execute();
// 返回所有合法数据, 以Object对象为数据类型
return $statement->fetchAll(PDO::FETCH_OBJ);
}bindValues - 将附带参数带入pdo实例
// 从例子中可以看出, 我用在预处理的变量为?, 这是因为pdo的局限性, 有兴趣可以在评论区讨论这个问题
public function bindValues($statement, $bindings) {
// $bindings = ['PENELOPE', 'GUINESS']
// 依次循环每一个参数
foreach ($bindings as $key => $value) {
// $key = 0/1
// $value = 'PENELOPE'/'GUINESS'
$statement->bindValue(
// 如果是字符串类型, 那就直接使用, 反之是数字, 将其+1
// 这里是数值, 因此返回1/2
is_string($key) ? $key : $key + 1,
// 直接放入值
// 'PENELOPE'/'GUINESS'
$value,
// 这里直白不多说
// PDO::PARAM_STR/PDO::PARAM_STR
is_int($value) ? PDO::PARAM_INT : PDO::PARAM_STR
);
}
}所以懂了吗_( :3」∠)
update - 改写数据
// 与read不同的地方在于, read返回数据, update返回boolean(true/false)
public function update($sql, $bindings) {
$statement = $this->connection->prepare($sql);
$this->bindValues($statement, $bindings);
return $statement->execute();
}delete - 删除数据
// 与update一样, 分开是因为方便日后维护制定
public function delete($sql, $bindings) {
$statement = $this->connection->prepare($sql);
$this->bindValues($statement, $bindings);
return $statement->execute();
}create - 增加数据
// 返回最新的自增ID, 如果有
public function create($sql, $bindings) {
$statement = $this->connection->prepare($sql);
$this->bindValues($statement, $bindings);
$statement->execute();
return $this->lastInsertId();
}lastInsertId - 返回新增id, 如果有
// pdo自带,只是稍微封装
public function lastInsertId() {
$id = $this->connection->lastInsertId();
return empty($id) ? null : $id;
}过于高级复杂的SQL语句可能无法封装, 因此准备了可直接用RAW query通信数据库的两个函数
exec - 适用于增删改
public function exec($sql) {
return $this->connection->exec($sql);
}query - 适用于读
public function query($sql) {
$q = $this->connection->query($sql);
return $q->fetchAll(PDO::FETCH_OBJ);
}将数据库事务相关的函数封装起来, 直白所以没有注释
public function beginTransaction() {
$this->connection->beginTransaction();
return $this;
}
public function rollBack() {
$this->connection->rollBack();
return $this;
}
public function commit() {
$this->connection->commit();
return $this;
}
public function inTransaction() {
return $this->connection->inTransaction();
}完整代码<?php
class Connector {
// 数据库地址前缀,常见的有mysql,slqlsrv,odbc等等等
private $driver = 'mysql';
// 数据库地址
private $host = 'localhost';
// 数据库默认名称, 设置为静态是因为有切换数据库的需求
private static $db = 'sakila';
// 数据库用户名
private $username = 'root';
// 数据库密码
private $password = '';
// 当前数据库连接
protected $connection;
// 数据库连接箱,切换已存在的数据库连接不需要重新通信,从这里取即可
protected static $container = [];
// PDO默认属性配置,具体请自行查看文档
protected $options = [
PDO::ATTR_CASE => PDO::CASE_NATURAL,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
PDO::ATTR_STRINGIFY_FETCHES => false,
];
function construct() {
// 如果从未连接过该数据库, 那就新建连接
if(empty(self::$container[self::$db])) $this->connect();
// 反之, 从$container中提取, 无需再次通信
$this->connection = self::$container[self::$db];
}
// 生成DSN连接串
protected function buildConnectString() {
return "$this->driver:host=$this->host;dbname=".self::$db;
}
// 连接数据库
public function connect() {
try {
// 连接数据库,生成pdo实例, 将之赋予$connection,并存入$container之中
self::$container[self::$db] = $this->connection = new PDO($this->buildConnectString(), $this->username, $this->password, $this->options);
// 返回数据库连接
return $this->connection;
} catch (Exception $e) {
// 若是失败, 返回原因
dd($e->getMessage());
}
}
// 切换数据库
public function setDatabase($db) {
self::$db = $db;
return $this;
}
// 读取数据
public function read($sql, $bindings) {
// 将sql语句放入预处理函数
$statement = $this->connection->prepare($sql);
// 将附带参数带入pdo实例
$this->bindValues($statement, $bindings);
// 执行
$statement->execute();
// 返回所有合法数据, 以Object对象为数据类型
return $statement->fetchAll(PDO::FETCH_OBJ);
}
// 将附带参数带入pdo实例
public function bindValues($statement, $bindings) {
// 依次循环每一个参数
foreach ($bindings as $key => $value) {
$statement->bindValue(
// 如果是字符串类型, 那就直接使用, 反之是数字, 将其+1
is_string($key) ? $key : $key + 1,
// 直接放入值
$value,
// 这里直白不多说
is_int($value) ? PDO::PARAM_INT : PDO::PARAM_STR
);
}
}
// 改写数据
public function update($sql, $bindings) {
// 与read不同的地方在于, read返回数据, update返回boolean(true/false)
$statement = $this->connection->prepare($sql);
$this->bindValues($statement, $bindings);
return $statement->execute();
}
// 删除数据
public function delete($sql, $bindings) {
$statement = $this->connection->prepare($sql);
$this->bindValues($statement, $bindings);
return $statement->execute();
}
// 增加数据
public function create($sql, $bindings) {
$statement = $this->connection->prepare($sql);
$this->bindValues($statement, $bindings);
$statement->execute();
return $this->lastInsertId();
}
// 返回新增id, 如果有
public function lastInsertId() {
$id = $this->connection->lastInsertId();
return empty($id) ? null : $id;
}
// 适用于增删改
public function exec($sql) {
return $this->connection->exec($sql);
}
// 适用于读
public function query($sql) {
$q = $this->connection->query($sql);
return $q->fetchAll(PDO::FETCH_OBJ);
}
public function beginTransaction() {
$this->connection->beginTransaction();
return $this;
}
public function rollBack() {
$this->connection->rollBack();
return $this;
}
public function commit() {
$this->connection->commit();
return $this;
}
public function inTransaction() {
return $this->connection->inTransaction();
}
}本期疑问1.) 因为php本身的特性, 默认情况下运行完所有代码类会自行析构,pdo自动断联, 所以我没有disconnect(),让pdo断开连接, 不知这样是不是一种 bad practice?
2.) 增加和改写数据的两个函数并不支持多组数据一次性加入,只能单次增该, 原因是我之前写了嫌太繁琐所以删了, 有心的童鞋可以提供方案

php实现框架数据库链接封装 如何写一个属于自己的数据库封装(2)

几种常用PHP连接数据库的代码示例

PHP连接数据库之PHP连接MYSQL数据库代码

  • < ?php
  • $mysql_server_name= localhost ;
  • //改成自己的mysql数据库服务器
  • $mysql_username= root ;
  • //改成自己的mysql数据库用户名
  • $mysql_password= ;
  • //改成自己的mysql数据库密码
  • $mysql_database= mycounter ;
  • //改成自己的mysql数据库名
  • $conn=mysql_connect($mysql_server_name $mysql_username $mysql_password $mysql_database);
  • $sql= CREATE DATABASE mycounter  DEFAULT CHARACTER SET gbk COLLATE gbk_chinese_ci;
  • ;
  • mysql_query($sql);
  • $sql= CREATE TABLE `counter`  (`id` INT( ) UNSIGNED NOT NULL  AUTO_INCREMENT  `count` INT( )  UNSIGNED NOT NULL DEFAULT  PRIMARY KEY  ( `id` ) ) TYPE = innodb; ;
  • mysql_select_db($mysql_database $conn);
  • $result=mysql_query($sql);
  • //echo $sql;
  • mysql_close($conn);
  • echo "Hello!数据库mycounter已经成功建立!";
  • ?>
  • PHP连接数据库之PHP连接ACCESS数据库代码方法

  • < ?
  • $conn = new ("ADODB Connection");
  • $connstr = "DRIVER={Microsoft Access Driver (* mdb)}; DBQ="  realpath("data/db mdb");
  • $conn >Open($connstr);
  • $rs = new ("ADODB RecordSet");
  • $rs >Open("select * from szd_t" $conn );
  • while(! $rs >eof) {
  • $f = $rs >Fields( );
  • echo $f >value;
  • $rs >MoveNext();
  • }
  • ?>
  • PHP连接数据库之PHP连接MS SQL数据库代码方法

    安装SQL服务器并添加PHP的MSSQL扩展

    使用以下代码连接并测试

  • < ?php
  • $myServer = localhost; //主机
  • $myUser = sa; //用户名
  • $myPass = password; //密码
  • $myDB = Northwind; //MSSQL库名
  • $s = @mssql_connect($myServer  $myUser  $myPass)
  • or die(Couldnt connect to SQL Server on $myServer);
  • $d = @mssql_select_db($myDB  $s)
  • or die(Couldnt open database $myDB);
  • $query = SELECT TitleOfCourtesy+ +FirstName+ +LastName AS Employee ;
  • $query  = FROM Employees ;
  • $query  = WHERECountry=USA AND Left(HomePhone   ) = ( );
  • $result = mssql_query($query);
  • $numRows = mssql_num_rows($result);
  • echo < h >   $numRows   Row   ($numRows ==   ? : s)   Returned </ h >;
  • while($row = mssql_fetch_array($result))
  • {
  • echo < li>   $row[Employee]   < /li>;
  • }
  • ?>
  • PHP连接数据库之PHP连接Oracle数据库

    PHP提供了两套函数与Oracle连接 分别是ORA_和OCI函数 其中ORA_函数略显陈旧 OCI函数更新据说更好一些 两者的使用语法几乎相差无几 你的PHP安装选项应该可以支持两者的使用 我爱编程网

  • < ?
  • if ($conn=Ora_Logon("user@TNSNAME" "password"))
  • { echo "SUCCESS ! Connected to databasen";
  • }else
  • {echo "Failed : ( Could not connect to databasen";}
  • Ora_Logoff($conn);
  • phpinfo();
  • ?>
  • lishixinzhi/Article/program/PHP/201405/30761

    php实现框架数据库链接封装 如何写一个属于自己的数据库封装(2)

    thinkphp怎么连接数据库

    thinkphp连接数据库的方法:
    ThinkPHP内置了抽象数据库访问层,把不同的数据库操作封装起来,只需要使用公共的Db类进行操作,而无需针对不同的数据库写不同的代码和底层实现,Db类会自动调用相应的数据库驱动来处理。目前的数据库包括Mysql、SqlServer、PgSQL、Sqlite、Oracle、Ibase、Mongo,也包括对PDO的支持,如果应用需要使用数据库,必须配置数据库连接信息,数据库的配置文件有多种定义方式。
    常用的配置方式是在项目配置文件中添加下面的参数:
    <?php
    //项目配置文件
    return array(
    //数据库配置信息
    'DB_TYPE' => 'mysql', // 数据库类型
    'DB_HOST' => 'localhost', // 服务器地址
    'DB_NAME' => 'thinkphp', // 数据库名
    'DB_USER' => 'root', // 用户名
    'DB_PWD' => '', // 密码
    'DB_PORT' => 3306, // 端口
    'DB_PREFIX' => 'think_', // 数据库表前缀
    //其他项目配置参数
    // ...
    );
    需要注意的是,ThinkPHP的数据库连接的惰性的,所以并不是在实例化的时候就连接数据库,而是在有实际的数据操作的时候才会去连接数据库(额外的情况是,在系统第一次实例化模型的时候,会自动连接数据库获取相关模型类对应的数据表的字段信息)。

    以上就是今天分享给大家的内容了,想要了解更多后端开发资讯,敬请关注我爱编程网!
    与“php实现框架数据库链接封装 如何写一个属于自己的数据库封装(2)”相关推荐
    python自动生成插画-python怎么根据数据生成图像
    python自动生成插画-python怎么根据数据生成图像

    python自动生成插画-python怎么根据数据生成图像如何用python画五一海报要用Python画五一海报,需要用到Python的绘图库,比如matplotlib、Pillow等。以下是一个简单的例子,演示如何使用Python和Pillow库来制作五一海报:fromPILimportImage,ImageDraw,ImageFont#创建一个空白的画布,大小为800x

    2023-12-13 15:46:29
    如何用Python编写一个素数环?
    如何用Python编写一个素数环?

    如何用Python编写一个素数环?代码:n=int(input("请输入最大数n:"))lists=[[1]]#多个素数环surplusnum=list(range(1,n+1))#剩余的数defsumisprime(x,y):#x与y之和是否是素数isprime=True#是否是素数s=x+y#和foriinrange(2,int(s**0.5)+1):

    2023-12-11 17:02:40
    如何使用Python计算两个数字的乘积或平方?
    如何使用Python计算两个数字的乘积或平方?

    怎样用python编出乘法算式?print('\n'.join([''.join(['%sx%s=%-2s'%(y,x,x*y)foryinrange(1,x+1)])forxinrange(1,10)]))Python写出输入二个数,求这二个数的加、减、乘、除、取余、取整、幂的值并输?当你想要让用户输入两个数字,并计算它们的加法、减法、乘法、除法、取余、取整、幂运算的结果,可以

    2023-12-12 13:00:59
    python xlwt excel 单元格边框,如何才能有如下的加黑边框
    python xlwt excel 单元格边框,如何才能有如下的加黑边框

    pythonxlwtexcel单元格边框,如何才能有如下的加黑边框borders = xlwt.Borders()borders.left = 1borders.right = 1borders.top = 1borders.bottom = 1borders.bottom_colour=0x3A    style = xlwt.XFStyle()style.borders = border

    2023-12-12 18:09:59
    我的世界如何写代码
    我的世界如何写代码

    我的世界如何写代码以下是按要求改动的代码:编写代码以制作我的世界(Minecraft)模组是一项既有趣又有挑战性的任务。首先,你需要选择一个编程语言来编写Minecraft模组。目前,最常用的语言是Lua,因为Minecraft的开发者也使用它来编写游戏逻辑。如果你熟悉Python,也可以尝试使用Python编写模组,但Lua更为常见。一、获取Minecraft

    2023-12-13 17:05:15
    python种如何输出指定位小数
    python种如何输出指定位小数

    python种如何输出指定位小数方法一:round(X,N)该方法并不严格有效,当X小数位数n&lt;N时,仅能够输出n位小数。方法二:print('%.Nf'%X)或者print("%.Nf"%X)注意该方法有两个“%”,没有“,”。方法三:print(format(X,'.Nf')或者print(format(X,".Nf")注意该方法没有"%",但有“,”。更多

    2023-12-12 23:54:15
    python时间序列(2)(用python编个十进制转换为六进制的程序!!在线等)
    python时间序列(2)(用python编个十进制转换为六进制的程序!!在线等)

    python时间序列(2)时期(period)表示的是时间区间,比如数日、数月、数季、数年等。Period类所表示的就是这种数据类型,其构造函数需要用到一个字符串或整数,以及表11-4中的频率:这里,这个Period对象表示的是从2007年1月1日到2007年12月31日之间的整段时间。只需对Period对象加上或减去一个整数即可达到根据其频率进行位移的效果:如果两个Per

    2023-12-13 18:17:36
    如何在python IDLE Shell窗口中编写程序计算圆的周长?
    如何在python IDLE Shell窗口中编写程序计算圆的周长?

    如何在pythonIDLEShell窗口中编写程序计算圆的周长?可以按照以下步骤在PythonIDLEShell窗口中编写计算圆周长的程序:打开PythonIDLEShell窗口。在窗口中输入以下代码:pythonCopycoderadius=float(input("请输入圆的半径:"))circumference=2*3.14159*radiuspr

    2023-12-13 02:25:56