- 封装数据库操作类:
- 因为目前所使用的mysqli扩展实现数据库的操作还比较零散,如果想要高效的使用,就必须要进行二次加工
- 在面向对象编程中,所有操作都应该是由类来实现完成
- 封装的完整程度是根据业务的需求来定
步骤
1、确定要封装的业务:基于mysqli的数据库底层实现,完成数据库操作的基本诉求
- 简化初始化操作
- 实现错误处理
- 实现增删改查
2、明确封装的类的作用,确定内部实现机制
- 方法独立性:一个方法只做一件事情
- 方法独立性:方法只负责执行,不对结果进行任何处理,交由外部调用处判定
- 灵活性:封装的所有操作应该是灵活的,不是写死的内容
3、根据思路明确封装类的数据和数据操作
- 数据使用属性保留:数据需要跨方法或者对外提供数据支持
- 数据库操作的数据:主机地址、端口、用户名、密码、数据库名字、字符集
- 数据库连接资源跨方法:连接资源
- 错误信息对外数据支持:错误信息、错误编号
- 数据操作具体功能
- 初始化资源工作:构造方法,实现属性初始化
- 初始化数据库资源:实现数据库的连接认证、字符集设置和数据库选择:失败返回false并记录错误
- SQL指令语法检查:SQL执行并完成错误处理:失败返回false并记录错误
- 写操作:实现增伤改指令的执行:调用SQL指令语法检查,成功返回受影响行数
- 自增长ID获取:实现自增长id获取
- 读操作:单记录获取和多记录获取:调用SQL指令语法检查
4、确定类的控制
- 不需要外部访问和使用的私有
- 明确外部需要用到的公有
- 如果数据安全性要求高,那么可以属性私有,但是允许对外提供可以操作的公有方法(内部安全处理)
示例
1、一个类通常就是一个文件,所以要先确定文件的名字:通常类文件命名规范有两种
- 文件名字与类名字一样,如Sql.php
- 为了区分普通PHP文件,增加中间类描述,如Sql.class.php
- 现在PHP几乎都是面向对象编程,所以通常采用第一种方式:因此当前命名数据类的文件为:Sql.php
2、确定类文件名字后其实也就确定了类名字,因此可以创建一个Sql类
# 数据库操作类
class Sql{}
3、类的创建分两种:一是特定使用,即类里面的所有内容只为某次使用;二是通用,即工具类,以后很多地方可以用。
- 特定使用,功能可以不用太灵活
- 通用工具,功能应该大众化,数据的变化会比较多
数据库类以后凡是要操作数据库的地方都可以用得到,很多项目都会用到,所以应该是个通用工具类,因此要考虑其到处可用的特性,让其能够灵活
4、数据库的操作最基本的特性不会改变:即需要连接认证,而连接认证的信息是灵活的,所以可以通过设定属性来控制,这些信息也都是不同使用者不同的,应该可以改变,所以可以通过构造方法来实现数据传入
# 数据库操作类
class Sql{
# 设置属性:数据库初始化信息
public $host;
public $port;
public $user;
public $pass;
public $dbname;
public $charset;
# 构造方法初始化数据:数据较多,应该使用数组来传递数据,关联数组,而且绝大部分的开发者本意是用来测试,所以基本都是本地,因此可以给默认数据
/*
$info = array(
'host' => 'localhost',
'port' => '3306',
'user' => 'root',
'pass' => 'root',
'dbname' => 'blog',
'charset' => 'utf8'
)
*/
public function __construct(array $info = array()){
# 初始化:确保用户传入了数据,否则使用默认值
$this->host = $info['host'] ?? 'localhost';
$this->port = $info['port'] ?? '3306';
$this->user = $info['user'] ?? 'root';
$this->pass = $info['pass'] ?? 'root';
$this->dbname = $info['dbname'] ?? 'test';
$this->charset = $info['charset'] ?? 'utf8';
}
}
注意:方法设定的原则是一个方法只实现一个简单的功能,不要多个功能堆积到一个方法中。
5、数据库属性会在实例化Sql对象的时候自动初始化
# 接上述代码(类外测试)
$s1 = new Sql(); # 使用默认数据库信息
$db = array(
'host' => '192.168.0.1',
'user' => 'admin',
'pass' => 'admin',
'dbname' => 'Taobao'
);
$s2 = new Sql($db); # 使用外部数据库信息
6、数据库要操作的第一件事就是连接认证,所以需要一个连接认证的功能。这里可以使用mysqli面向过程的方法。但是需要建立一个方法来实现连接认证:连接是否成功?
# 对外提供属性,记录错误数据(外部如何处理,不需要我们管)
public $errno;
public $error;
# mysqli的连接资源对象是任何mysqli扩展操作的基础,因此需要该连接对象能够在其他方法中使用:属性处理
public $link;
# 在上述类中增加一个方法:实现连接认证功能
public function connect(){
# 利用属性可以跨方法访问:5个参数分别为:主机、用户名、密码、数据库、端口
# 利用错误抑制符抑制可能出现的错误
$this->link = @mysqli_connect($this->host,$this->user,$this->pass,$this->dbname,$this->port);
# 判定连接是否成功
if(!$this->link){
# 将错误信息保存到记录错误的属性中,返回false
$this->errno = mysqli_connect_errno();
$this->error = mysqli_connect_error();
return false;
}
# 返回一个连接结果:不需要返回资源对象,为真即可表示成功
return true;
}
7、连接认证包括数据库选择设定好后,此时还存在一个细节问题:字符集,为了保证数据库连接的正常操作,需要新增一个方法设定字符集
# 在Sql类中增加设定字符集的方法
public function charset(){
# 调用mysqli的设置字符集的函数
$res = mysqli_set_charset($this->link,$this->charset);
# 判定是否成功
if(!$res){
$this->errno = mysqli_errno($this->link);
$this->error = mysqli_error($this->link);
return false;
}
return true;
}
8、初始化完成后,可以实现具体的业务处理:所有的SQL都需要使用mysqli_query执行,也都可能产生错误,因此封装一个专门执行SQL并检查错误的方法
# SQL执行以及错误检查
p