php数据库包,超轻的 PHP 数据库工具包

一个很轻的 PHP 数据库工具包,诞生时间两天(足以证明很轻了 )。

两个类,一个 Connection 管理 PDO 连接(支持多数据库),一个 QuickQuery 用来快速执行数据库操作(不用在 PDO 和 PDOStatement 之间来回折腾)

不用下载,在线就能看完。

1.[代码]使用范例use Persistence\DbAccess;

// 在框架初始化的地方添加连接信息

DbAccess\Connection::add(

'default',

'sqlite',

'/db/mydb.sqlite',

null, null, false

);

// 下面是使用

$conn = DbAccess\Connection::instance('default');

// 查询

$query = new DbAccess\QuickQuery($conn);

$query->prepare('select :name as name')->execute(array(':name'=>'tonyseek'));

// 对象直接作为迭代器产生数据数组

foreach($query as $i) {

var_dump($i);

}

// 如果有偏执的话,输出响应之前手动断开连接

DbAccess\Connection::disconnectAll();

2.[代码]Persistence/DbAccess/QuickQuery.php<?php

namespace Persistence\DbAccess;

use PDO, ArrayObject, DateTime;

use LogicException, InvalidArgumentException;

/**

* 快捷查询通道

*

* @version 0.3

* @author tonyseek

* @link http://www.php.cn/

* @license http://www.php.cn/

* @copyright StuCampus Development Team, Shenzhen University

*

*/

class QuickQuery implements \IteratorAggregate

{

/**

* 数据库连接

*

* @var \Persistence\DbAccess\Connection

*/

private $connection = null;

/**

* PDO Statement

*

* @var PDOStatement

*/

private $stmt = null;

/**

* 被检查参数集

*

* @var array

*/

private $checkedParams = array();

/**

* 构造查询通道

*

* @param \Persistence\DbAccess\Connection $connection 数据库连接

*/

public function __construct(Connection $connection)

{

$this->connection = $connection;

}

/**

* 预编译 SQL 语句

*

* @param string $sqlCommand SQL语句

* @return \Persistence\DbAccess\QuickQuery

*/

public function prepare($sqlCommand)

{

// 从连接获取 PDO, 并对 SQL 语句执行 prepare, 产生 PDO Statement

$this->stmt = $this->connection->getPDO()->prepare($sqlCommand);

// 修改 PDO Statement 模式为关联数组数据

$this->stmt->setFetchMode(PDO::FETCH_ASSOC);

// 返回方法链

return $this;

}

/**

* 执行数据查询

*

* @throws PDOException

* @return \Persistence\DbAccess\QuickQuery

*/

public function execute($params = array())

{

$stmt = $this->getStatement();

// 参数检查

$diff = array_diff($this->checkedParams, array_keys($params));

if (count($this->checkedParams) && count($diff)) {

throw new InvalidArgumentException('缺少必备参数:'.implode(' | ', $diff));

}

// 将 PHP 数据类型对应到数据库数据类型

foreach($params as $key => $value) {

$type = null;

switch(true) {

case is_int($value):

$type = PDO::PARAM_INT;

break;

case is_bool($value):

$type = PDO::PARAM_BOOL;

break;

case ($value instanceof DateTime):

$type = PDO::PARAM_STR;

$value = $value->format(\DateTime::W3C);

break;

case is_null($value):

$type = PDO::PARAM_NULL;

break;

default:

$type = PDO::PARAM_STR;

}

$stmt->bindValue($key, $value, $type);

}

$stmt->execute();

$this->checkedParams = array(); // 清空参数检查

return $this;

}

/**

* 获取 Statement 对象

*

* 返回对象可以被绑定参数重新执行, 也可以被当作迭代器遍历获取数据。

*

* @return \PDOStatement

*/

public function getStatement()

{

if (!$this->stmt) {

throw new LogicException('SQL语句应该先被 QuickQuery.prepare 预处理');

}

return $this->stmt;

}

/**

* getStatement 方法的替代名

*

* 实现 PHP 标准库 中的 IteratorAggregate 接口, 外部可以直接将本对象作为迭代器遍

* 历。和 getStatment 唯一不同之处, 是本方法不会抛出 LogicException 异常。如果

* 没有事先使用 prepare 和 execute, 会返回一个空迭代器。

*

* @return Traversable

*/

public function getIterator()

{

try {

return $this->getStatement();

} catch (LogicException $ex) {

return new \ArrayObject();

}

}

/**

* 设置查询参数检查

*

* 通过此处导入的被检查查询参数, 如果没有得到赋值, 则查询时会抛出 LogicException 异常。

*

* @param array $params

* @return \Persistence\DbAccess\QuickQuery

*/

public function setParamsCheck(array $params)

{

$this->checkedParams = $params;

return $this;

}

/**

* 将结果集转换为数组

*

* @return array

*/

public function toArray()

{

return iterator_to_array($this->getStatement());

}

/**

* 获取最后一个插入结果(或序列)的 ID

*

* @param string $name

* @return int

*/

public function getLastInsertId($name=null)

{

return $this->connection->getPDO()->lastInsertId($name);

}

}

3.[代码]Persistence/DbAccess/Connection.php<?php

namespace Persistence\DbAccess;

use InvalidArgumentException, BadMethodCallException;

use PDO, PDOException;

/**

* 连接工厂,提供全局的PDO对象,并管理事务。

*

* @version 0.3

* @author tonyseek

* @link http://www.php.cn/

* @license http://www.php.cn/

* @copyright StuCampus Development Team, Shenzhen University

*

*/

final class Connection

{

/**

* Connector 实例集合

*

* @var array

*/

static private $instances = array();

/**

* 数据库驱动名

*

* @var string

*/

private $driver = '';

/**

* 数据库连接字符串(Database Source Name)

*

* @var string

*/

private $dsn = '';

/**

* PDO 实例

*

* @var \PDO

*/

private $pdo = null;

/**

* 用户名

*

* @var string

*/

private $username = '';

/**

* 密码

*

* @var string

*/

private $password = '';

/**

* 是否开启持久连接

*

* @var bool

*/

private $isPersisten = false;

/**

* 是否开启仿真预编译

*

* @var bool

*/

private $isEmulate = false;

/**

* 是否在事务中

*

* @var bool

*/

private $isInTransation = false;

/**

* 私有构造函数,阻止外部使用 new 操作符实例化

*/

private function __construct(){}

/**

* 生产 Connector 实例(多例)

*

* @param string $name

* @return \StuCampus\DataModel\Connector

*/

static public function getInstance($name = 'default')

{

if (!isset(self::$instances[$name])) {

// 如果访问的实例不存在则抛出错误异常

throw new InvalidArgumentException("[{$name}] 不存在");

}

return self::$instances[$name];

}

/**

* 断开所有数据库实例的连接

*/

static public function disconnectAll()

{

foreach (self::$instances as $instance) {

$instance->disconnect();

}

}

/**

* 添加数据库

*

* 向实例群添加 Connector

*

* @param string $name 标识名

* @param string $driver 驱动名

* @param string $dsn 连接字符串

* @param string $usr 数据库用户名

* @param string $pwd 数据库密码

* @param bool $emulate 仿真预编译查询

* @param bool $persisten 是否持久连接

*/

static public function registry($name, $driver, $dsn, $usr, $pwd, $emulate = false, $persisten = false)

{

if (isset(self::$instances[$name])) {

// 如果添加的实例名已经存在则抛出异常

throw new BadMethodCallException("[{$name}] 已被注册");

}

// 实例化自身,并推入数组中

self::$instances[$name] = new self();

self::$instances[$name]->dsn = $driver . ':' . $dsn;

self::$instances[$name]->username = $usr;

self::$instances[$name]->password = $pwd;

self::$instances[$name]->driver = $driver;

self::$instances[$name]->isPersisten = (bool)$persisten;

self::$instances[$name]->isEmulate = (bool)$emulate;

}

/**

* 获取 PHP Database Object

*

* @return \PDO

*/

public function getPDO()

{

if (!$this->pdo) {

// 检查 PDO 是否已经实例化,否则先实例化 PDO

$this->pdo = new PDO($this->dsn, $this->username, $this->password);

// 错误模式为抛出 PDOException 异常

$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// 开启查询缓存

$this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, $this->isEmulate);

// 开启持久连接

$this->pdo->setAttribute(PDO::ATTR_PERSISTENT, $this->isPersisten);

}

return $this->pdo;

}

/**

* 获取数据库驱动名

*

* @return string

*/

public function getDriverName()

{

return $this->driver;

}

/**

* 开始事务

*/

public function transationBegin()

{

$this->isInTransation = $this->getPDO()->beginTransaction();

}

/**

* 提交事务

*/

public function transationCommit()

{

if ($this->isInTransation) {

$this->getPDO()->commit();

} else {

trigger_error('transationBegin 应该先于 transationCommit 调用');

}

}

/**

* 回滚事务

* @return bool

*/

public function transationRollback()

{

if ($this->isInTransation) {

$this->getPDO()->rollBack();

} else {

trigger_error('transationBegin 应该先于 transationRollback 调用');

}

}

/**

* 连接是否在事务中

*

* @return bool

*/

public function isInTransation()

{

return $this->isInTransation;

}

/**

* 在事务中执行回调函数

*

* @param function $callback 匿名函数或闭包函数

* @param bool $autoRollback 异常发生时是否自动回滚

* @throws \PDOException

* @return bool

*/

public function transationExecute($callback, $autoRollback = true)

{

try {

// 开始事务

$this->transationBegin();

// 调用回调函数

if (is_callable($callback)) {

$callback();

} else {

throw new InvalidArgumentException('$callback应该为回调函数');

}

// 提交事务

return $this->transationCommit();

} catch(PDOException $pex) {

// 如果开启了自动回滚, 则捕捉到 PDO 异常时先回滚再抛出

if ($autoRollback) {

$this->transationRollback();

}

throw $pex;

}

}

/**

* 安全地断开数据库连接

*/

public function disconnect()

{

if ($this->pdo) {

// 检查 PDO 是否已经实例化,是则设置为null

$this->pdo = null;

}

}

/**

* 阻止克隆

*/

public function __clone()

{

trigger_error('被阻止的 __clone 方法, Connector 是单例类');

}

}

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值