热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

超轻的PHP数据库工具包-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

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

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 是单例类');
	}
}

推荐阅读
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文介绍了adg架构设置在企业数据治理中的应用。随着信息技术的发展,企业IT系统的快速发展使得数据成为企业业务增长的新动力,但同时也带来了数据冗余、数据难发现、效率低下、资源消耗等问题。本文讨论了企业面临的几类尖锐问题,并提出了解决方案,包括确保库表结构与系统测试版本一致、避免数据冗余、快速定位问题等。此外,本文还探讨了adg架构在大版本升级、上云服务和微服务治理方面的应用。通过本文的介绍,读者可以了解到adg架构设置的重要性及其在企业数据治理中的应用。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 本文比较了eBPF和WebAssembly作为云原生VM的特点和应用领域。eBPF作为运行在Linux内核中的轻量级代码执行沙箱,适用于网络或安全相关的任务;而WebAssembly作为图灵完备的语言,在商业应用中具有优势。同时,介绍了WebAssembly在Linux内核中运行的尝试以及基于LLVM的云原生WebAssembly编译器WasmEdge Runtime的案例,展示了WebAssembly作为原生应用程序的潜力。 ... [详细]
  • 本文讨论了B360主板是否可以安装win7系统的问题。由于B360主板不支持win7系统且缺乏官方驱动的支持,安装win7系统可能存在兼容性和稳定性问题。然而,通过借助USB3.0转接卡,B360主板仍然可以安装win7系统,但USB接口无法使用。相比之下,B365主板可以直接支持win7系统,并提供了相应的驱动,具有更好的稳定性和兼容性。选择合适的主板对于安装win7系统至关重要。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • 橱窗设计的表现手法及其应用
    本文介绍了橱窗设计的表现手法,包括直接展示、寓意与联想、夸张与幽默等。通过对商品的折、拉、叠、挂、堆等陈列技巧,橱窗设计能够充分展现商品的形态、质地、色彩、样式等特性。同时,寓意与联想可以通过象形形式或抽象几何道具来唤起消费者的联想与共鸣,创造出强烈的时代气息和视觉空间。合理的夸张和贴切的幽默能够明显夸大商品的美的因素,给人以新颖奇特的心理感受,引起人们的笑声和思考。通过这些表现手法,橱窗设计能够有效地传达商品的个性内涵,吸引消费者的注意力。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
author-avatar
mobiledu2502903717
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有