Correcting teacher:天蓬老师
Correction status:qualified
Teacher's comments:命名注意规范, select_SQL, 算什么呢? 要么select_sql, 要么selectSql
在本次学习内容的实践过程中,发现Mysqli相对于PDO的要简洁一些,而且mysql_result
的结果集的操作个人感觉也比较简单。
其次,就是无论是PDO还是MySQLi,在访问数据库的步骤上基本是一致的,细节上略有差别而已。
最后,对于接口的多态实现,其本质上,还是利用了接口之间允许继承,并且可以多继承的特性。与此同时,也因为接口仅仅是定义,也就是说接口具备一个接口,允许有多个类进行不同的实现的特性。正是因为这些特性,接口才能很好地实现PHP面向对象开发中的多态。
以上仅代表个人观点哦! - _ -
<?php
/**
* Created by PhpStorm.
* User: Air15_2019
* Date: 2020/2/12
* Time: 10:57
*/
namespace Mysql_data;
use mysqli;
//mysqli 面向对象操作数据库
class MySQLi_Basics{
//新增
public function inter_SQL(){
//1.创建mysqli对象,连接数据库
$mysqli=new mysqli('localhost','root','root888','test');
//2.传入需要---执行的SQL语句
$sql = 'INSERT `tf_users` SET `f_name`=?, `f_password`=?,`f_email`=?,`f_phone`=?,`f_regtime`=?;';
//3.通过stmt_init(),实例化一个预处理对象,防止SQL注入攻击
$stmt=$mysqli->stmt_init();
//3.1 使用预处理对象下的prepare()方法,将SQl注入到预处理对象中
$stmt->prepare($sql);
//参数
$user = ['李木子', sha1('5649725'), 'li_muzi@mayituyu.cn', '1786411111',date('yy-m-d h:i:s',time())];
list($name, $password, $email,$phone,$regtime) = $user;
// 使用预处理对象的 bind_param('参数的类型', 参数列表.....)方法,绑定参数到其中
$stmt->bind_param('sssss', $name, $password, $email, $phone,$regtime);
// 准备完成---执行
$stmt->execute();
// 4. 处理执行的结果
if ($stmt->affected_rows === 1) :
echo '添加成功, 新记录的主键id: ' . $stmt->insert_id;
else :
echo '添加失败' . $stmt->error;
endif;
// 5. 结束操作
// 关闭数据库连接
$stmt->close();
}
//更新
public function update_SQL(){
$mysqli=new mysqli('localhost','root','root888','test');
$sql = "UPDATE `tf_users` SET `f_phone`=?,`f_regtime`=? WHERE `f_id`=?;";
//3.通过stmt_init(),实例化一个预处理对象,防止SQL注入攻击
$stmt=$mysqli->stmt_init();
//3.1 使用预处理对象下的prepare()方法,将SQl注入到预处理对象中
$stmt->prepare($sql);
//参数
$user = ['15867425596',date('yy-m-d h:i:s',time()),2];
list($phone,$regtime,$id) = $user;
// 使用预处理对象的 bind_param('参数的类型', 参数列表.....)方法,绑定参数到其中
$stmt->bind_param('ssi', $phone,$regtime,$id);
// 准备完成---执行
$stmt->execute();
// 4. 处理执行的结果
if ($stmt->affected_rows === 1) :
echo 'ID:'.$id.'的数据更新成功!更新时间:'.$regtime;
else :
echo '更新失败' . $stmt->error;
endif;
// 5. 结束操作
// 关闭数据库连接
$stmt->close();
}
//删除
public function delete_SQL($id){
//1.创建mysqli对象,连接数据库
$mysqli=new mysqli('localhost','root','root888','test');
//2.传入需要---执行的SQL语句
$sql = 'DELETE FROM `tf_users` WHERE `f_id`=?;';
//3.通过stmt_init(),实例化一个预处理对象,防止SQL注入攻击
$stmt=$mysqli->stmt_init();
//3.1 使用预处理对象下的prepare()方法,将SQl注入到预处理对象中
$stmt->prepare($sql);
//参数
$user_id = $id;
// 使用预处理对象的 bind_param('参数的类型', 参数列表.....)方法,绑定参数到其中
$stmt->bind_param('i', $user_id);
// 准备完成---执行
$stmt->execute();
// 4. 处理执行的结果
if ($stmt->affected_rows === 1) :
echo 'ID:'.$user_id.'的数据删除成功!删除时间:'.date('yy-m-d h:i:s',time());
else :
echo '删除失败' . $stmt->error;
endif;
// 5. 结束操作
// 关闭数据库连接
$stmt->close();
}
//查询-1 使用STMT对象查询(预处理对象)
public function select_SQL($id){
//1.创建mysqli对象,连接数据库
$mysqli=new mysqli('localhost','root','root888','test');
//2.传入需要---执行的SQL语句
$sql = 'SELECT `f_name`,`f_email`,`f_regtime` FROM `tf_users` WHERE `f_id`>?;';
//3.通过stmt_init(),实例化一个预处理对象,防止SQL注入攻击
$stmt=$mysqli->stmt_init();
//3.1 使用预处理对象下的prepare()方法,将SQl注入到预处理对象中
$stmt->prepare($sql);
//参数
$user_id = $id;
// 使用预处理对象的 bind_param('参数的类型', 参数列表.....)方法,绑定参数到其中
$stmt->bind_param('i', $user_id);
// 准备完成---执行
$stmt->execute();
// 4. 处理执行的结果
//4.1使用 bind_result()方法,将结果集中的字段绑定在变量上
$stmt->bind_result($name,$email,$regtime);
//4.2 使用fetch()方法,获取结果集中的当前一条记录,并且数据指针会自动下移一个;
while ($stmt->fetch()){
echo '用户名:'.$name.',的邮箱是:'.$email.',用户注册时间:'.$regtime.'<br>';
}
// 5. 结束操作
//5.1 使用 free_result() 释放结果集所占用的内存
$stmt->free_result();
// 关闭数据库连接
$stmt->close();
}
//查询-2 使用
public function select_results($id){
$mysqli=new mysqli('localhost','root','root888','test');
$sql = 'SELECT `f_name`,`f_email`,`f_regtime` FROM `tf_users` WHERE `f_id`>?;';
$stmt=$mysqli->stmt_init();
$stmt->prepare($sql);
$user_id = $id;
$stmt->bind_param('i', $user_id);
$stmt->execute();
//1.使用 get_result(),获取结果集对象
$result=$stmt->get_result();
/*
* 2. 处理执行的结果
* fetch_array(),获取一条记录,包含索引和关联
* fetch_row(),获取一条记录,仅索引部分;
* fetch_assoc()获取一条记录,仅关联部分;
* fetch_all(),一次性获取所有数据(参数为MYSQLI_ASSOC)时,只返回关联部分;
* data_seek(0),索引归 0 复位;
* free_result(),释放结果集所占用的内存;
* */
//循环遍历输出
while ($users=$result->fetch_assoc()){
echo '用户名:'.$users['f_name'].',的邮箱是:'.$users['f_email'].',用户注册时间:'.$users['f_regtime'].'<br>';
}
//索引复位 因为上面以及遍历完了 ,我们下面使用fetch_all一次性返回所有数据,所以需要先将指针复位;
echo '<br>========一次性输出所有========<br>';
$result->data_seek(0);
//fetch_all
$users=$result->fetch_all(MYSQLI_ASSOC);
foreach ($users as $user){
echo '用户名:'.$user['f_name'].',的邮箱是:'.$user['f_email'].',用户注册时间:'.$user['f_regtime'].'<br>';
}
// 5. 结束操作
//5.1 使用 free_result() 释放结果集所占用的内存;
$result->free_result();
// 关闭数据库连接
$stmt->close();
}
}
$mysql_sql=new MySQLi_Basics();
//新增
$mysql_sql->inter_SQL();
echo '<hr>';
//更新
$mysql_sql->update_SQL();
echo '<hr>';
//删除
$mysql_sql->delete_SQL(9);
echo '<hr>';
//查询-1
$mysql_sql->select_SQL(2);
echo '<hr>';
//查询-2
$mysql_sql->select_results(2);
?>
PDO
MySQLi
<?php
/**
* Created by PhpStorm.
* User: Air15_2019
* Date: 2020/2/12
* Time: 15:27
* Description: 数据访问接口定义
*/
/*
* 接口之间允许继承,并且可以多继承。与此同时,一个接口,允许有多个类进行不同的实现。
* 正是因为接口的这些特性,才能使其实现面向对象的 `多态`实现;
* */
namespace Database;
//设置数据库连接参数:默认值
interface inter_DbParam{
const HOST='localhost';
const TYPE='mysql';
const DB_NAME='test';
const USER_NAME='root';
const PASSWORD='root888';
const PORT='3306';
const CHARSET='utf8'; //默认字符集
}
//接口构造方法
interface inter_DbConnection{
//构造方法,
public function __construct(array $connectionParams);
}
//下面是数据库连接接口中,主要被实现的类
interface inter_Execute extends inter_DbParam,inter_DbConnection{
//新增操作,其参数是多个,所以参数是一个数组类型
public function ex_Insert(array $data);
//删除操作,参数是删除数据的条件
public function ex_Delete(string $where);
//更新操作,参数是更新的数据和更新条件
public function ex_Update(array $data,string $where);
//查询操作
public function ex_Select(string $where);
}
<?php
/**
* Created by PhpStorm.
* User: Air15_2019
* Date: 2020/2/12
* Time: 15:51
* Description: PDO方式,实现数据库访问
*/
namespace Database;
//导入PDO
use PDO;
//载入接口文件
require 'DB_interface.php';
class db_PDO implements inter_Execute{
//连接对象
private $pdo=null;
//实现接口中的构造方法
public function __construct(array $connectionParams)
{
//将传入参数 $connectionParams 中的值,分别绑定给指定变量
list($dsn,$username,$password)=$connectionParams;
//实例化PDO对象
$this->pdo=new PDO($dsn,$username,$password);
}
//新增操作
public function ex_Insert(array $data){
$sql="INSERT `tf_users` SET `f_name`=?, `f_password`=?,`f_email`=?,`f_phone`=?,`f_regtime`=?;";
//使用PDO对象的 prepare方法创建预处理对象
$stmt=$this->pdo->prepare($sql);
//执行语句的时候,需要将新增的数据传参给execute()
$stmt->execute($data);
//rowCount()返回受影响的行数
if ($stmt->rowCount()===1){
$message='新增数据成功!';
}else{
$message='新增数据失败!';
}
return$message;
}
//删除操作
public function ex_Delete(string $where){
$sql = 'DELETE FROM `tf_users` WHERE '.$where;
$stmt=$this->pdo->prepare($sql);
$stmt->execute();
//rowCount()返回受影响的行数
if ($stmt->rowCount()===1){
$message='删除数据成功!';
}else{
$message='删除数据失败!';
}
return$message;
}
//更新操作
public function ex_Update(array $data,string $where){
//设置更新的参数
$params='';
foreach ($data as $key=>$value){
$params.="`$key`='$value',";
}
//使用 rtrim() 去掉最后的多于的 逗号
$params=rtrim($params,',');
//执行更新
$sql = "UPDATE `tf_users` SET {$params} WHERE {$where}";
$stmt = $this->pdo->prepare($sql);
$stmt->execute();
//rowCount()返回受影响的行数
if ($stmt->rowCount()===1){
$message='更新数据成功!';
}else{
$message='更新数据失败!';
}
return$message;
}
//查询操作
public function ex_Select(string $where){
//判断传入条件
$where = empty($where) ? '' : ' WHERE ' . $where;
$sql='SELECT * FROM `tf_users` '.$where;
$stmt=$this->pdo->prepare($sql);
$stmt->execute();
//PDO::FETCH_ASSOC 输出关联部分
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
}
<?php
/**
* Created by PhpStorm.
* User: Air15_2019
* Date: 2020/2/12
* Time: 17:56
* Description: MySQLi方式,实现数据库访问
*/
namespace Database;
//导入MySQLi
use mysqli;
//载入接口文件
require 'DB_interface.php';
class db_MySQLi implements inter_Execute{
//连接对象
private $mysqli=null;
//实现接口中的构造方法
public function __construct(array $connectionParams)
{
//将传入参数 $connectionParams 中的值,分别绑定给指定变量
list($host,$username,$password,$dbname)=$connectionParams;
//实例化mysqli
$this->mysqli=new mysqli($host,$username,$password,$dbname);
//设置默认字符集
$this->mysqli->set_charset('utf8');
}
//新增操作
public function ex_Insert(array $data){
$sql="INSERT `tf_users` SET `f_name`=?, `f_password`=?,`f_email`=?,`f_phone`=?,`f_regtime`=?;";
//使用PDO对象的 prepare方法创建预处理对象
$stmt=$this->mysqli->prepare($sql);
//数据绑定
$stmt->bind_param('sssss',$name,$password,$email,$phone,$regtime);
list($name,$password,$email,$phone,$regtime)=$data;
//执行语句的时候,需要将新增的数据传参给execute()
$stmt->execute();
//rowCount()返回受影响的行数
if ($stmt->affected_rows===1){
$message='新增数据成功!';
}else{
$message='新增数据失败!';
}
return$message;
}
//删除操作
public function ex_Delete(string $where){
$sql = 'DELETE FROM `tf_users` WHERE '.$where;
$stmt=$this->mysqli->prepare($sql);
$stmt->execute();
//rowCount()返回受影响的行数
if ($stmt->affected_rows===1){
$message='删除数据成功!';
}else{
$message='删除数据失败!';
}
return$message;
}
//更新操作
public function ex_Update(array $data,string $where){
//设置更新的参数
$params='';
foreach ($data as $key=>$value){
$params.="`$key`='$value',";
}
//使用 rtrim() 去掉最后的多于的 逗号
$params=rtrim($params,',');
//执行更新
$sql = "UPDATE `tf_users` SET {$params} WHERE {$where}";
$stmt = $this->mysqli->prepare($sql);
$stmt->execute();
//rowCount()返回受影响的行数
if ($stmt->affected_rows===1){
$message='更新数据成功!';
}else{
$message='更新数据失败!';
}
return$message;
}
//查询操作
public function ex_Select(string $where){
//判断传入条件
$where = empty($where) ? '' : ' WHERE ' . $where;
$sql='SELECT * FROM `tf_users` '.$where;
$stmt=$this->mysqli->prepare($sql);
$stmt->execute();
//通过 get_result()获取预处理对象的结果集
$results=$stmt->get_result();
return $results;
}
}
<?php
/**
* Created by PhpStorm.
* User: Air15_2019
* Date: 2020/2/12
* Time: 16:34
* Description: DB通用类,面向接口实现PDO、MySQLi的动态支持(多态)
*/
namespace Database;
use Database\inter_Execute as iDb;
/*
* DB 通用类中,使用了接口作为 类方法参数,
* 并且在类方法中返回了接口的方法结果;
* */
class DB{
//新增
public static function db_Insert(iDb $db,array $data){
return $db->ex_Insert($data);
}
//删除
public static function db_Delete(iDb $db,string $where){
return $db->ex_Delete($where);
}
//更新
public static function db_Update(iDb $db,array $data,string $where){
return $db->ex_Update($data,$where);
}
//查询
public static function db_Select(iDb $db, $where){
return $db->ex_Select($where);
}
}
<?php
/**
* Created by PhpStorm.
* User: Air15_2019
* Date: 2020/2/12
* Time: 16:51
* Description: 通过BD类,使用PDO方式访问数据库
*/
namespace Database;
//加载文件
require 'DB_pdo.php';
require 'DB.php';
// 拼接 $dsn
$dsn= inter_DbParam::TYPE . ':host='.inter_DbParam::HOST . ';dbname=' . inter_DbParam::DB_NAME . ';charset='.inter_DbParam::CHARSET;
// 拼接数组参数
$paranms=[
$dsn,
inter_DbParam::USER_NAME,
inter_DbParam::PASSWORD
];
//创建PDO
$link=new db_PDO($paranms);
echo '===========PDO测试============<br>';
// 测试新增操作
echo '消息:'.DB::db_Insert($link,['李继承',sha1('584627'),'zhang_chenghao@mayitiyu.cn','17569842711',date('yy-m-d h:i:s',time())]);
echo '<hr>';
// 测试查询
foreach (DB::db_Select($link, 'f_id > 2') as $user) {
echo '用户名:'.$user['f_name'].',的邮箱是:'.$user['f_email'].',用户注册时间:'.$user['f_regtime'].'<br>';
}
echo '<hr>';
// 更新测试
echo DB::db_Update($link,['f_name'=>'逍遥王子', 'f_email'=>'xiaoyao_wangzi@mayitiyu.cn'], 'f_id=5');
echo '<hr>';
// 删除操作
echo DB::db_Delete($link,'f_id=13');
<?php
/**
* Created by PhpStorm.
* User: Air15_2019
* Date: 2020/2/12
* Time: 17:55
* Description: 通过BD类,使用MySQLi方式访问数据库
*/
namespace Database;
//加载文件
require 'DB_mysqli.php';
require 'DB.php';
// 拼接数组参数
$paranms=[
inter_DbParam::HOST,
inter_DbParam::USER_NAME,
inter_DbParam::PASSWORD,
inter_DbParam::DB_NAME
];
//创建PDO
$link=new db_MySQLi($paranms);
echo '===========MySQLi测试============<br>';
// 测试新增操作
echo '消息:'.DB::db_Insert($link,['王重阳',sha1('75264889'),'wang_chongyang@mayitiyu.cn','17569842711',date('yy-m-d h:i:s',time())]);
echo '<hr>';
// 测试查询
foreach (DB::db_Select($link, 'f_id > 2') as $user) {
echo '用户名:'.$user['f_name'].',的邮箱是:'.$user['f_email'].',用户注册时间:'.$user['f_regtime'].'<br>';
}
echo '<hr>';
// 更新测试
echo DB::db_Update($link,['f_name'=>'逍遥王孙', 'f_email'=>'xiaoyao_wangsun@mayitiyu.cn'], 'f_id=5');
echo '<hr>';
// 删除操作
echo DB::db_Delete($link,'f_id=14');