一、mysqli类操作mysql数据库的介绍
1、从PHP5.0开始可以使用mysql(i), 是一个面向对象的技术(新加功能都会以对象形式添加)
2、i:表示改进,1. 功能增加了, 2,效率大大增加(以后的PHP项目改成mysqli),3,更稳定
3、mysqli使用面向对象技术,但也支持过程化的使用方式
4、mysqli扩展中给我们提供了三个类:
① mysqli和连接有关的类
② mysqli_result表达了对数据库的查询所返回的结果集。 以上两个类就可以完成 mysql扩展功能
③ mysqli_stmt (后面重点介绍)
5、选择过程化编程,还是选择面向对象技术,选择面向对象的性能更高
mysql(i)_connect()
mysql(i)_select_db();
mysql(i)_query();
就算是使用mysqli中过程化的编程方式,也比使用mysql编程方式性能更高
使用mysqli扩展就要使用面向对象的编程方式进行开发
二、mysqli的简单对象实例化
1、mysqli的对象实例化和简单方法调用
<?php
$mysqli=@new mysqli("localhost", "root", "123456", "xsphpdb");
if(mysqli_connect_errno()){
echo "连接数据库失败:".mysqli_connect_error();
$mysqli=null;
exit;
}
echo $mysqli->character_set_name()."<br>";
echo $mysqli->get_client_info()."<br>";
echo $mysqli->host_info."<br>";
echo $mysqli->server_info."<br>";
echo $mysqli->server_version."<br>";
$mysqli->close();
?>
2、mysqli处理sql语句及遇到错误的错误输出
<?php
$mysqli=@new mysqli("localhost", "root", "123456", "xsphpdb");
if(mysqli_connect_errno()){
echo "连接数据库失败:".mysqli_connect_error();
$mysqli=null;
exit;
}
//select语句(结果集), 非select语句,会影响行数
$sql="insert into shops(name,price,num,desn) values('hello','34.56','22','good123')";
$result=$mysqli->query($sql);
if(!$result){
echo "SQL语句有误<br>";
echo "ERROR:".$mysqli->errno."|".$mysqli->error;
exit;
}
echo $mysqli->affected_rows;
if($mysqli->affected_rows > 0){
echo "有行数被影响<br>";
}
echo "最后自动增长的ID:".$mysqli->insert_id;
$mysqli->close()
?>
三、mysqli处理数据库结果集
1. 使用select语句后,得到的结果集的处理mysqli_result
2、处理记录
属性:num_rows
方法:data_seek();fetch_assoc();fetch_row();fetch_array();fetch_object();
释放资源:free() close() free_result()
3、处理字段信息
属性:field_count;current_field;lengths
方法:data_field();fetch_field();fetch_fields()
四、处理结果集程序函数
1、获取结果集资源的方法
<?php
$mysqli=new mysqli("localhost", "root", "123456", "xsphpdb");
if(mysqli_connect_errno()){
echo "错误:".mysqli_connect_error();
exit;
}
//执行select语句,返回来的就是结果集(对象)
$sql="select id,name from shops where id <50";
$result=$mysqli->query($sql);
$rows=$result->num_rows; //结果集行数
$cols=$result->field_count; //结果集列数
echo "表中{$rows}行,{$cols}列<br>";
$mysqli->close();
?>
2、处理结果集使用到的函数
<?php
$mysqli=new mysqli("localhost", "root", "123456", "xsphpdb");
if(mysqli_connect_errno()){
echo "错误:".mysqli_connect_error();
exit;
}
//执行select语句,返回来的就是结果集(对象)
$sql="select id cid, name shopname, price shopprice, num shopnum, desn shopdesn from shops";
$result=$mysqli->query($sql);
$rows=$result->num_rows;
$cols=$result->field_count;
echo "表中{$rows}行,{$cols}列<br>";
//记录信息
/* $result->fetch_row() ---- mysql_fetch_row() 索引数组
* $result->fetch_assoc() --- mysql_fetch_assoc() 关联数组(下标就是列名)
* $result->fetch_array() ---- mysql_fetch_array() 两个数组都返回(MYSQLI_ASSOC, MYSQLI_NUM,MYSQLI_BOTH(default))
* $result->fetch_object() --- mysql_fetch_object()
*
* 每次执行一次,就会从结果集中取出当前一条记录(当前记录就是第一个行,可以使用data_seek(5))
*
* 指针指向下一行,下次再取时,就会取出下一行,当结果集中没有记录时,则返回false
*
*/
echo '<table border=1 align="center" width=900>';
echo '<tr>';
// $result->field_seek(2); //指针移到第二行
while($field=$result->fetch_field()){
echo '<th>'.$result->current_field.'_['.$field->orgname.']'.$field->name.'('.$field->max_length.')</th>';
}
echo '</tr>';
// $result->data_seek(50); //指针移到第50行
while($row=$result->fetch_assoc()){
echo '<tr>';
foreach($row as $col){
echo '<td>'.$col.'</td>';
}
echo '</tr>';
}
echo '</table>';
$result->free();
$mysqli->close();
?>
五、使用mysqli执行多条语句,使用分号进行分割
分两种情况:有结果集的sql语句和没结果集的sql语句
1、就是没有结果集的sql语句,insert update delete
<?php
$mysqli=new mysqli("localhost", "root", "123456", "xsphpdb");
//没有结果集insert update delete
$sqls="insert into shops(name, price, num,desn) values('XSPHP', '79', '100000', 'very good for PHP');";
$sqls.="update shops set name='LAMP' where id > 40;";
$sqls.="delete from shops where id < 30";
echo $sqls."<br>";
if($mysqli->multi_query($sqls)){
echo "多条语句执行成功!<br>";
echo "最后插入的ID:".$mysqli->insert_id."<br>";
// echo "影响的行数为:".$mysqli->affected_rows; //这一条就不准确了,得到的影响的行数不正确
}else{
echo "ERROR:".$mysqli->errno."--".$mysqli->error;
}
$mysqli->close();
?>
2、多条语句有结果集select,$mysqli->multi_query($sqls),$result=$mysqli->store_result();,$mysqli->next_result()
<?php
$mysqli=new mysqli("localhost", "root", "123456", "xsphpdb");
//有结果集多个select语句
$sqls="select current_user();";
$sqls.="desc shops;";
$sqls.="select * from shops;";
$sqls.="select current_date()";
if($mysqli->multi_query($sqls)){
echo "执行成功!<br>";
do{
$result=$mysqli->store_result();
echo '<table align="center" border="1" width='.(100*$result->field_count).'>';
echo '<tr>';
while($field=$result->fetch_field()){
echo '<th>'.$field->name.'</th>';
}
echo '</tr>';
while($row=$result->fetch_assoc()){
echo '<tr>';
foreach($row as $col){
echo '<td>'.$col.'</td>';
}
echo '</tr>';
}
echo '</table>';
if($mysqli->more_results()){
echo '<p>--<p>--<p>';
}
}while($mysqli->next_result()); //取下个结果集的函数方法
}else{
echo "ERROR:".$mysqli->errno."--".$mysqli->error;
}
$mysqli->close();
?>
六、使用mysqli完成事务处理
1、事务处理:将多个SQL要完成的任务看为是一个事务,一件事有任何一个环节出错,都整个事务撤消, 如果都成功才去提交
目前只有InnoDB 支持事务 (MyISAM不支持)
默认表都是自动提交的(autocommit),开启事物处理的方法
1. 关闭自动提交 语句:set autoconmit=0;
2. 开启事务 语句:start transaction;
3. 提交sql语句
4. conmit ,提交就不能回滚了
5. 回滚:rollback
2、下面是事物处理的程序过程
<?php
$mysqli=new mysqli("localhost", "root", "123456", "xsphpdb");
//事务处理
$mysqli->autocommit(0); //关闭自动提交
$error=true;
$price=50;
//钱转出
$sql="update zh set ye=ye-{$price} where name='zhangsan'";
$result=$mysqli->query($sql);
if(!$result){
$error=false;
echo "从张三转出失败<br>";
}else{
if($mysqli->affected_rows==0){
$error=false;
echo "张三的钱没有变化";
}else{
echo "从张三账号中转出成功!<br>";
}
}
//钱转入
$sql="update zh set ye=ye+{$price} where name='lisi1'";
$result=$mysqli->query($sql);
if(!$result){
$error=false;
echo "从李四转入失败<br>";
}else{
if($mysqli->affected_rows==0){
$error=false;
echo "李四的钱没有变化";
}else{
echo "向李四账号中转入成功!<br>";
}
}
if($error){
echo "转账成功!";
$mysqli->commit(); //没有事物的错误,则把事物提交,提交后则不能回滚了
}else{
echo "转账失败!";
$mysqli->rollback(); //事物中有sql的执行错误,则回滚,回滚到没执行事物之前
}
$mysqli->autocommit(1); //执行完事物后,则开启数据库的自动提交
$mysqli->close();
?>
七、其他的mysqli类的中的成员使用
详细查看手册
例如:$mysqli->set_charset("utf8");
八、mysqli_stmt预处理类,它效率高,安全(推荐你使用的类)
和mysqli和mysqli_result相比优点:
1. mysqli和mysqli_result参完成的功能,都可以使用mysqli_stmt完成
2. 效率上:高, 就是如果执行多次相同的语句,只有语句数据不同, 因为将一条语句在服务器端准备好,然后将不同的值传给服务器,再让这条语句执行
编译一次,使用多次
3. 安全上:SQL注入(? 占位) ,后期传的值不会当成SQL语句
九、程序的代码说明
1、没有结果集的sql语句处理
<?php
$mysqli=new mysqli("localhost", "root", "123456", "xsphpdb");
//准备好一条语句放到服务器中,插入语句
$sql="insert into shops(name, price, num, desn) values(?, ?, ?, ?)";
$stmt=$mysqli->prepare($sql);
//给占位符号每个?号传值(绑定参数) i:int。 d;double s:string b:bool是数据的类型
$stmt->bind_param("sdis", $name, $price, $num, $desn);
/****准备好一条语句放到服务器中,插入语句,这是update的sql语句
$sql="update shops set name=?, price=?, num=?, desn=? where id=?";
$stmt=$mysqli->prepare($sql);
//给占位符号每个?号传值(绑定参数) i d s b
$stmt->bind_param("sdisi", $name, $price, $num, $desn,$id);
***/
$name="zhangsan";
$price=56.78;
$num=66;
$desn="hello good";
//执行
$stmt->execute();
$name="lisi";
$price=56.78;
$num=66;
$desn="aaaaaaaa";
//执行
$stmt->execute();
$name="wangwu";
$price=56.78;
$num=96;
$desn="bbbbbbbbb";
//执行
$stmt->execute();
$name="zhaoliu";
$price=56.78;
$num=68;
$desn="cccccccccccc";
//执行
$stmt->execute();
echo "最后ID".$stmt->insert_id."<br>";
echo "影响了".$stmt->affected_rows."行<br>";
$stmt->close();
?>
2、有结果集的sql语句处理:select
<?php
$mysqli=new mysqli("localhost", "root", "123456", "xsphpdb");
$stmt=$mysqli->prepare("select id, name, price, num, desn from shops where id>?");
$stmt->bind_param("i", $id);
$stmt->bind_result($id, $name, $price, $num, $desn);
$id=99;
$stmt->execute();
$stmt->store_result(); //一次性将结果都取过来 重要
//字段信息
$result=$stmt->result_metadata();
while($field=$result->fetch_field()){
echo $field->name."--";
}
echo '<br>';
//记录信息
//$stmt->data_seek(2);
while($stmt->fetch()){
echo "$id--$name---$price---$num---$desn <br>";
}
echo "记录总数:".$stmt->num_rows;
$stmt->free_result();
$stmt->close();
?>