`

Yii分析10:Yii核心组件之数据库类CDbConnection

阅读更多

 

数据库类几乎是每个PHP框架必不可少的组件之一,Yii的数据库核心主要包含两类,一类是管理数据库连接的CDbConnection及相关类,另一类是ORM(Object Relation Model),即管理数据库表记录的CActiveRecord及相关类。

首先我将介绍和分析数据库连接管理类CDbConnection,CDbConnect作为CApplication的核心组件,在应用初始化时会自动进行初始化,对于使用者来说,需要在配置文件中将配置CDbConnection的初始化配置:

 

//protected/config/main.php:
'components'=>array(
	……
'db'=>array(
		//连接字符串,设置数据库类型,数据库主机地址,数据库名
			'connectionString' => 'mysql:host=localhost;dbname=blog',
			//用户名
			'username' => 'root',
			//密码
			'password' => '123456',
			//字符集
			'charset' => 'utf8',
		),
	……

 

 在应用初始化时,会自动初始化CDbConnectiont:

 

//CApplication:

abstract class CApplication extends CModule
	//构造函数
public function __construct($config=null)
{
		……
		//注册核心组件
		$this->registerCoreComponents();
		……
}
……
protected function registerCoreComponents()
{
	//核心组件列表
		$components=array(
			……
			'db'=>array(
				'class'=>'CDbConnection',
			),
			……
		};
		//调用父类函数注册
		$this->setComponents($components);
}

//CModule:
abstract class CModule extends CComponent

	public function setComponents($components,$merge=true)
	{
		foreach($components as $id=>$component)
		{
			//如果是接口IApplicationComponent的一个实例
			//调用setComponent
			//CDbConnect继承自CApplicationComponent
			//CApplicationCompnent继承了IApplicationCompnent接口
			if($component instanceof IApplicationComponent)
				$this->setComponent($id,$component);
			else if(isset($this->_componentConfig[$id]) && $merge)
				$this->_componentConfig[$id]=CMap::mergeArray($this->_componentConfig[$id],$component);
			else
				$this->_componentConfig[$id]=$component;
		}
	}
	public function setComponent($id,$component)
	{
		if($component===null)
			unset($this->_components[$id]);
		else
		{
			$this->_components[$id]=$component;
			//初始化组件
			if(!$component->getIsInitialized())
				$component->init();
		}
	}
}

 

 

接下来我们看看CDbConnect在初始化阶段,都做了那些事情:

 

/**
* CDbConnection与CDbCommand、CDbDataReader和CDbTransaction一起合作提供对DBMS的数据访问功能
* 它使用PDO作为数据库连接驱动
*/
class CDbConnection extends CApplicationComponent
{
	//以下属性在配置文件中设置
	public $connectionString;
	public $username='';
	public $password='';
	public $charset;

	//表结构缓存时间,单位是秒,默认不缓存
	public $schemaCachingDuration=0;
	//表结构缓存排除列表
	public $schemaCachingExclude=array();
	//表结构缓存ID
	public $schemaCacheID='cache';
	//自动连接,默认为true,如果设置为false,在使用时才会连接
	public $autoConnect=true;
	//模仿prepare,默认为false,PDO会使用原生的prepare,对于某些数据库(例如MySql),最好设置为true,这样就不会使用有bug的PDO原生prepare,关于PDO的prepare相关信息可以查阅:http://php.net/manual/en/pdo.prepare.php
	public $emulatePrepare=false;
	//是否记录绑定变量(如果使用prepare方式进行查询,如果记录sql语句,是看不到绑定变量的值的),调试时使用
	public $enableParamLogging=false;
	//是否记录SQL语句,调试时使用
	public $enableProfiling=false;
	//数据表前缀
	public $tablePrefix;
	//在建立数据库连接之后立即执行的SQL语句
	public $initSQLs;

	//目前支持的数据库驱动
	public $driverMap=array(
		'pgsql'=>'CPgsqlSchema',    // PostgreSQL
		'mysqli'=>'CMysqlSchema',   // MySQL
		'mysql'=>'CMysqlSchema',    // MySQL
		'sqlite'=>'CSqliteSchema',  // sqlite 3
		'sqlite2'=>'CSqliteSchema', // sqlite 2
		'mssql'=>'CMssqlSchema',    // Mssql driver on windows hosts
		'dblib'=>'CMssqlSchema',    // dblib drivers on linux (and maybe others os) hosts
		'sqlsrv'=>'CMssqlSchema',   // Mssql
		'oci'=>'COciSchema',        // Oracle driver
	);
	……
	//初始化
	public function init()
	{
		//调用父类初始化
		parent::init();
		//
		if($this->autoConnect)
			$this->setActive(true);
	}
	……
	public function setActive($value)
	{
		//如果需要设置的状态与当前状态不同
		if($value!=$this->_active)
		{
			if($value)
				$this->open();
			else
				$this->close();
		}
	}
	protected function open()
	{
		if($this->_pdo===null)
		{
			if(empty($this->connectionString))
				throw new CDbException(Yii::t('yii','CDbConnection.connectionString cannot be empty.'));
			try
			{
				Yii::trace('Opening DB connection','system.db.CDbConnection');
				//创建PDO实例
				$this->_pdo=$this->createPdoInstance();
				//初始化连接
				$this->initConnection($this->_pdo);
				$this->_active=true;
			}
			catch(PDOException $e)
			{
				//异常处理
				……
			}
		}
	}
	……
	//创建PDO实例
	protected function createPdoInstance()
	{
		$pdoClass='PDO';
		if(($pos=strpos($this->connectionString,':'))!==false)
		{
			$driver=strtolower(substr($this->connectionString,0,$pos));
			if($driver==='mssql' || $driver==='dblib')
				$pdoClass='CMssqlPdoAdapter';
		}
		return new $pdoClass($this->connectionString,$this->username,
									$this->password,$this->_attributes);
	}
	……
	//初始化连接
	protected function initConnection($pdo)
	{
		$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
		if($this->emulatePrepare && constant('PDO::ATTR_EMULATE_PREPARES'))
			$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,true);
		if($this->charset!==null)
		{
			$driver=strtolower($pdo->getAttribute(PDO::ATTR_DRIVER_NAME));
			//pg,mysql,mysqli需要设置字符编码
			if(in_array($driver,array('pgsql','mysql','mysqli')))
				$pdo->exec('SET NAMES '.$pdo->quote($this->charset));
		}
		//如果有初始化SQL,则执行
		if($this->initSQLs!==null)
		{
			foreach($this->initSQLs as $sql)
				$pdo->exec($sql);
		}
	}
}
 

 

 

以上便是CDbConnect初始化的过程,其实CDnConnection主要功能是为用户封装了PDO的实例,并且自定义了一些配置,方便用户使用。

 

如果我们在项目中不想使用应用核心组件数据库连接,想自定义一个数据库连接,那么可以直接创建CDbConnection的对象:


$connection=new CDbConnection($dsn,$username,$password);
//CDbConnection的祖先类Ccomponent包含有__isset方法,自动会调用名称为set[attribute]的方法,即会调用CdbConnection::setActive方法
$connection->active=true;
  如果想直接执行一条SQL:
$command=$connection->createCommand($sqlStatement);
$command->execute();   //
// 执行SQL获取结果
$reader=$command->query();

//$row代表一条记录
foreach($reader as $row) ...
与CDbConnection密切相关的几个类有:

CDbCommand:用户生成SQL语句,执行SQL语句
CDbTransaction:用于管理数据库事务的类
CDbDataReader:用于管理SQL语句执行结果的类,实现了Iterator接口,能够像遍历数组一样遍历自身
这里不再详述每个类的内部细节,我们只需要了解用法即可。 

 

1
0
分享到:
评论

相关推荐

    yii2-schemadump:从现有数据库生成模式

    yii2-schemadump 从现有数据库生成模式。演示版要求PHP 7.3或更高版本Yii 2.x安装composer require --dev jamband/yii2-schemadump用法在config / console.php中添加以下内容: return [ . . . 'components' => [ . ...

    yii2-settings:Yii2 设置组件

    Yii2 设置组件 安装 安装此扩展的首选方法是通过 。 要么跑 php composer.phar require --prefer-dist pendalf89/yii2-settings "*" 或添加 "pendalf89/yii2-settings": "*" 到composer.json文件的 require 部分...

    Yii 2.0进阶版 高级组件 优化京东平台

    Yii 2.0进阶版 高级组件 优化京东平台 包括前后台源代码,使用php 实现数据库mysql

    yii-robokassa:用于与 Robokassa 支付服务的 api 配合使用的 Yii 组件

    用于与支付的 api 配合使用的 Yii 组件 安装 从这个 github 存储库下载 yii-robokassa: cd protected/components git clone https://github.com/ladamalina/yii-robokassa.git 在 protected/config/main.php 中...

    yii-passport:使Laravel Passport与Yii一起工作

    Yii护照 安装 :light_bulb: 这是展示如何安装软件包的好地方,请参见下文: 跑步 $ composer require inquid/yii-passport 用法 :light_bulb: 这是显示一些用法示例的好地方! 变更日志 请看看 。 贡献 请看看 。...

    yii2-swoole:完整的解决方案,使yii2-framework与协程在swoole上运行

    此插件基于 swoole (v2.0) 底层实现的协程,改造 Yii2 的核心代码,使开发者无感知,以及在不改动业务代码的情况下,用上 swoole 的异步IO能力。 特性 协程 MySQL 客户端、连接池,支持主从、事务。 协程 Redis ...

    yii2elfinder:yii2elfinder

    yii2elfinder 感谢: : 感谢:zybodya 提供当前 yii 版本 yii2elfinder 介绍:旧版本无法使用,因为它完全不适用于最新的jquery版本! 所以除了行动,我不得不改变一切;) 这个扩展允许你将 ElFinder 文件管理...

    yii2-beanstalk, Yii2 beanstalk web和控制台组件.zip

    yii2-beanstalk, Yii2 beanstalk web和控制台组件 yii2-beanstalkYii2 beanstalkd web和控制台组件,它是 pda/pheanstalk服务器顶部的一个接口。 感谢 Paul Annesley 完成这项工作。:如何使用?插件安装与 Composer...

    yii-simplepie:Yii1.* 的 RSS 解析扩展

    yii-simplepie yii-simplepie 是用于解析 rss 提要的 yii 扩展: 简单派: simplepie 文档: 用法 在 yii 中安装扩展 下载所有文件并放入 yii 扩展文件夹,然后在 config/main.php 中添加以下代码 'simplepie' ...

    yii-qa:基于Yii2实现的问答系统

    Yii-QA简介(此项目目前已不再维护)感谢选择Yii-QA,基于框架基础实现的问答程序。 #意识到目前的急性时间有限,无法管理太多的额外项目,我准备合并现有手上的项目,集成在一个项目中,感谢支持!!!!!!!请关注:...

    Yii框架应用组件用法实例分析

    本文实例讲述了Yii框架应用组件用法。分享给大家供大家参考,具体如下: 应用组件 ¶ 应用主体是服务定位器, 它部署一组提供各种不同功能的 应用组件 来处理请求。 例如,urlManager组件负责处理网页请求路由到对应...

    yii2-curl:用于 curl 的 Yii2 组件

    php composer.phar require --prefer-dist peterfrench/yii2-curl " * " 一旦 composer 安装了扩展,在您的配置文件中包含该组件。 'curl' => ['class' => 'peterfrench\curl\Curl' ,'options' => [/* curl options...

    yii-fullcalendar:Arshaw 的 FullCalendar jQuery 插件的 Yii 扩展

    Arshaw 的 FullCalendar jQuery 插件的 Yii 扩展 作者:Alexey Samoylov ( )。 要求 PHP 5.4 Yii 1.x 例子 全局组件配置示例: 'components' => [ 'fullcalendar' => [ 'class' => 'ext.yii-fullcalendar....

    yii2sly:jquery 狡猾

    yii2sly 这个扩展是惊人的 jquery 滑块“sly”的包装器,可以在这里找到: 请。 仔细查看所有插件选项,可以通过将它们添加到“clientOptions”参数来传递这些选项,如下所示。 可以在此处找到扩展的演示: 安装 ...

    yii2-fullcalendar:Yii 2组件,可轻松实现全日历集成

    Yii2全日历组件 安装 安装此扩展的首选方法是通过 。 要安装,请运行 $ php composer.phar require edofre/yii2-fullcalendar "V1.0.11" 或添加 "edofre/yii2-fullcalendar": "V1.0.11" 到composer.json文件的...

    yii-ckeditor:简单的 Yii 框架 CKEditor 小部件

    Yii 框架的 CKEditor 小部件 简单的 Yii CKEditor 小部件。 CKEditor - 每个人的 WYSIWYG 编辑器。 小部件生成具有相同属性的 CHtml::activeTextArea。 使用 CKEditor 4+ 版本测试。 安装 将此小部件复制到扩展...

    YII数据库操作大全

    yii对象操作、直接数据库操作、事物等操作。几乎所有的操作都收录了

    yii-seo:Yii PHP 框架的搜索引擎优化

    yii-seo Yii PHP 框架的搜索引擎优化。 用法 布局中 <?php Yii::app()->controller->widget( 'vendor.crisu83.yii-seo.widgets.SeoHead', array( 'httpEquivs' => array( 'Content-Type' => 'text/html; ...

    yii-demo:Yii 3演示应用程序

    Yii框架演示项目 [Yii Framework]是一个现代框架,旨在为您PHP应用程序奠定坚实的基础。 它旨在显示和测试所有Yii功能。 安装 您至少需要PHP 7.4。 克隆此存储库。 在项目根目录中运行composer update 。 运行./...

    yii-streamlog:将 Yii 1 日志发送到 stdoutstderr - 创建用于与 http 上提供的 php-fpmnginx Docker 堆栈一起使用

    Yii 1 流日志 将 Yii 1 日志发送到 stdout/stderr - 创建用于与提供的 php-fpm/nginx Docker 堆栈一起使用 感谢 Haensel 为! 安装 通过作曲家安装: composer require neam/yii-streamlog:* 或者下载扩展,将src...

Global site tag (gtag.js) - Google Analytics