前言
这篇文章会对PHP的MySQL扩展库,MySQLI的扩展库,SQL批量执行,事务控制等等进行一些简单的讲解。
MySQL扩展
PHP中MySQL扩展,虽然因为安全的原因,在PHP5.6及往上不在支持MySQL扩展库,但是还是要学习的,通过编写案例的方式来讲解。
案例
先说下操作数据库的大体思路吧,就是先获取连接-》选择数据库-》设置操作编码-》发送sql指令-》对返回的结果进行处理-》释放资源,断开连接。案例是一个在线词典查询。下面是创建表的sql语句:
create database worddbcreate table words(id int primary key auto_increment,enword varchar(32) not null,chword varchar(256) not null);insert into words(enword,chword) values (\'boy\',\'男孩\')insert into words(enword,chword) values (\'school\',\'学校\')
因为是练习,所以就插入了两条数据。接下来就是编写SQL工具类,代码如下:
<?phpclass SqlTool{private $conn;private $host=\"localhost\";private $user=\"root\";private $password=\"XFAICL1314\";private $db=\"worddb\";//初始化function SqlTool(){$this->conn=mysql_connect($this->host,$this->user,$this->password);if (!$this->conn){die(\"连接数据库失败!\".mysql_error());}mysql_select_db($this->db,$this->conn);mysql_query(\"set names utf8\");}//完成selectfunction execute_dql($sql){$res=mysql_query($sql) or die(mysql_error());return $res;}//完成insert,update,deletefunction execute_dml($sql){$b=mysql_query($sql,$this->conn);if (!$b){return 0;}else{//因为有些情况执行成功,但没有行数影响,所以在判断一下。if (mysql_affected_rows($this->conn)>0){return 1;}else{return 2;}}}}?>
之后就是前端页面的编写了,代码如下,有点丑:
<html><head><title>在线词典</title><meta http-equiv=\"content-type\" charset=\"UTF-8\"></head><body><center><h1>字典</h1></center><h2>查询英文</h2><form action=\"wordprocess.php\" method=\"post\">请输入英文:<input type=\"text\" name=\"yingyu\"><!--为了区分两个表单,这里选择用隐藏域的方式--><input type=\"hidden\" value=\"search1\" name=\"type\"><input type=\"submit\" value=\"提交\"></form><h2>查询中文</h2><form action=\"wordprocess.php\" method=\"post\">请输入中文:<input type=\"text\" name=\"hanyu\"><!--为了区分两个表单,这里选择用隐藏域的方式--><input type=\"hidden\" value=\"search2\" name=\"type\"><input type=\"submit\" value=\"提交\"></form></body></html>
接下来就是后端逻辑代码了,如下:
<?php//引入工具类require_once \'SqlTool.class.php\';header(\"Content-type:text/html;charset=utf-8\");if (isset($_POST[\'type\'])){$type=$_POST[\'type\'];}else{echo \"查询失败<br>\";echo \"<a href=\'wordVeiw.php\'>回到主页面</a>\";}if ($type==\"search1\") {if (isset($_POST[yingyu])) {$en_word = $_POST[yingyu];} else {echo \"请输入\";echo \"<a href=\'wordVeiw.php\'>回到主页面</a>\";}$sql = \"select chword from words where enword=\'\" . $en_word . \"\' limit 0,1\";//查询,调用sql工具类$SqlTool = new SqlTool();$res = $SqlTool->execute_dql($sql);if ($row = mysql_fetch_assoc($res)) {echo $en_word . \"对应的中文为\" . $row[\'chword\'];} else {echo \"查询没有这个词条.<br>\";echo \"<a href=\'wordVeiw.php\'>回到主页面</a>\";}//释放资源mysql_free_result($res);}else if($type == \"search2\") {if (isset($_POST[hanyu])) {$ch_word = $_POST[hanyu];} else {echo \"请输入\";echo \"<a href=\'wordVeiw.php\'>回到主页面</a>\";}$sql = \"select enword from words where chword like \'%\" . $ch_word . \"%\'\";//查询,调用sql工具类$SqlTool = new SqlTool();$res = $SqlTool->execute_dql($sql);if (mysql_num_rows($res) != 0) {while ($row = mysql_fetch_assoc($res)) {echo \"<br>\".$ch_word . \"对应的英文为\" . $row[\'enword\'];}} else {echo \"查询没有这个词条.<br>\";echo \"<a href=\'wordVeiw.php\'>回到主页面</a>\";}//释放资源mysql_free_result($res);}?>
现在来测试ad8一下吧,首先打开前端页面,如下图:
接下来输入boy进行查询,结果如下,查询成功:
因为是案例,所以直接将前端传过来的参数没有做任何处理直接拼接到SQL语句中,这样是非常危险的!!,存在SQL注入攻击,现在我来演示一下,在输入框中输入:
boy\' and updatexml(1,concat(0x7e,(select user()),0x7e),1)#
结果如下图直接报出使用者!!
所以在开发功能时,要秉持“外部参数皆不可信原则”进行开发。
MYSQLI扩展
其实mysqli扩展是mysql扩展的加强版,因为历史原因,有一些老程序员擅长面向过程写法,所以PHP设计者为mysqli设计了两套方案,一套面向对象,一套面向过程,甚至一个聊本里可以混着用,不过那样很怪,下面的案例都是采用面向对象的那套方案。
案例
做一个小功能吧,向数据库中插入数据。先设计一下SQL表,语句如下:
create database day1;use day1;create table user1 (id int(6) unsigned auto_increment primary key,name varchar(20) not null,password varchar(256) not null,email varchar(80) not null,age int(128) not null);INSERT INTO user1(name,password,email,age) VALUES(\'Lucia\',\'13568\',\'[email protected]\',30);
因为一会儿要插入数据,所以先插入一条,构造好后,打开数据库,查询,发现没有问题
接下来构造mysqli工具类代码如下:
<?phpclass SqlTest{private $mysqli;private $host=\"localhost\";private $user=\"root\";private $pass=\"XFAICL1314\";private $db=\"day1\";//初始话public function __construct(){$this->mysqli=new mysqli($this->host,$this->user,$this->pass,$this->db);if ($this->mysqli->connect_error){echo \"连接失败\";}$this->mysqli->query(\"set names utf8\");}//进行selectpublic function execute_dql($sql){$res=$this->mysqli->query($sql) or die($this->mysqli->error);return $res;1b14}//进行update,insert,deletepublic function execute_dml($sql){$res=$this->mysqli->query($sql) or die($this->mysqli->error);if (!$res){return 0;}else{if ($this->mysqli->affected_rows>0){return 1;//成功}else{return 2;//没有行数收影响}}}}?>
下面就是前端页面了,这里我用表单向后端提交数据,代码如下:
<html><head><meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\"/><center><title>添加联系人</title></center><style type=\"text/css\">div{background-color: aqua;width: 1250px;height: 500px;}div{text-align: center;}</style></head><body><div><div><form action=\"addprocess.php\" method=\"post\"><br><br><br><br><br>姓名:<input type=\"text\" name=\"user\"><br><br>密码:<input type=\"password\" name=\"password\"><br><br>email:<input type=\"text\" name=\"email\"><br><br>年龄:<input type=\"text\" name=\"age\"><br><br><input type=\"submit\" value=\"提交\" style=\"height: 36px;width: 60px;background-color: blue;color: azure;border: 0px\"> <input type=\"reset\" value=\"重置\" style=\"height: 36px;width: 60px;background-color: blue;color: azure;border: 0px\"></form></div></div></body></html>
效果如下图:
然后就是后端的逻辑设计了,代码如下:
<?php//引入工具类require_once \'SqlTest.class.php\';//创建实例$SqlTest=new SqlTest();$sql=\"insert into user1 (name,password,email,age) values (\'$_POST[user]\',md5(\'$_POST[password]\'),\'$_POST[email]\',\'$_POST[age]\')\";$res=$SqlTest->execute_dml($sql);if ($res==1){echo \"添加成功\";}else{if ($res==0){echo \'添加失败\';}else{echo \"行数没有变化\";}}?>
现在测试一下,我们在表单页面输入 小明,12345678,[email protected],25 数据,如下图:
然后提交表单,看看有没有插入到数据库中。
我们发现成功插入到数据库中如下:
关于mysqli扩展就说到这里。
MySQL批量执行SQL语句
上面简单介绍了MySQL扩展和MySQLI扩展,接下来说一说批量执行sql语句。
先提一个需求,如果我们像数据库批量添加用户,如果按照之前的办法一条一条的发送sql语句来处理,这样很占用资源,并且效率低。所以采用批量执行sql语句的方式。接下来用两个案例来讲解,因为增加,修改,删除操作返回的是布尔值,而查询操作返回的是结果集,所以分来来处理比较好。
批量执行dml语句
因为dml返回的是布尔值,所以处理起来也比较好处理。先创建表,顺便插入一条数据如下:
create database test;use test;create table users(id int(8) unsigned auto_increment primary key,name varchar(128) not null,password varchar(256) not null);insert into users(name,password) values(\'test\',\'13579\');
下面就是批量执行dml操作的代码:
<?php$mysqli=new mysqli(\"localhost\",\"root\",\"XFAICL1314\",\"test\");if ($mysqli->connect_error){echo \"连接失败\";}$sqli=\"insert into users(name,password) values (\'小利\',md5(\'13568\'));\";//批量执行dml操作时,注意上一级句的;和下一句的.两个符号$sqli.=\"insert into users(name,password) values (\'小利\',md5(\'13568\'));\";$sqli.=\"insert into users(name,password) values (\'小利和小峰\',md5(\'13568\'))\";$b=$mysqli->multi_query($sqli);if (!$b){echo \"插入失败\";}else{echo \"ok!\";}$mysqli->close();?>
然后访问页面,返回ok,说明插入到数据库了,现在打开数据库查看,果然插入进去了,如下图:
批量执行dql操作
批量执行dql操作的作用是一次性取回多个结果集,下面看案例代码:
<?phpheader(\"Content-type:text/html;charset=utf-8\");$mysqli=new mysqli(\"localhost\",\"root\",\"XFAICL1314\",\"test\");if ($mysqli->connect_error){echo \"连接失败\";}$sqli=\"select * from users;\";$sqli.=\"select * from lsp\";//因为multi_query这个函数比较傻,不会去判断有没有下一个结果集,所以最后再用more_results函数检查一下。if ($mysqli->multi_query($sqli)){do{ //从mysqli中取出第一个结果集$result=$mysqli->store_result();//显示mysqli $res对象while ($row=$result->fetch_row()){foreach ($row as $key=>$val){echo \"--$val\";}echo \"<br>\";}$result->free();//判断有没有下一个结果集,如果没有退出循环if (!$mysqli->more_results()){break;}echo \"<br>*************新得结果集<br/>\";} while ($mysqli->next_result());}?>
结果如下图:
关于MySQL的批量执行sql语句就说到这里。
MySQL事务控制
上面简单介绍了MySQL扩展库,MySQLI扩展库,批量执行17dbSQL语句,接下来说一说MySQL事务控制。
数据库配置
说MySQL事务控制之前,先查看并修改数据库引擎,查看引擎的命令如下:
show engines
我们发现,只有InnoDB是支持事务的,所以先查看一下现在得数据库引擎:
发现是MyISAM,我们将它修改为InnoDB,打开配置文件my.ini,将“default-storage-engine=MYISAM”改为你想设定的,然后重启即可。修改成功后,然后下一步就是代码实现。
案例
我们为什么需要事务控制呢?想一想,如果这是一个转账得场景,是不是需要同时控制住,必须我减金额得同时你加金额,任何一个出错都得转账失败。也就是说要保持一致。这也是要进行事务控制得必要性。下面看案例代码:
<?phpheader(\"Content-type:text/html;charset=utf-8\");$mysqli=new mysqli(\"localhost\",\"root\",\"XFAICL1314\",\"test\");if ($mysqli->connect_error){echo \"连接失败\";}//将提交设置为假,因为事物一旦提交就没有机会回滚$mysqli->autocommit(false);$sql1=\"update person set money=money-3 where id=1\";//这里第二条语句我故意写错表名$sql2=\"update persons set money=money+3 where id=2\";$b1=$mysqli->query($sql1);$b2=$mysqli->query($sql2);if (!$b1 || !$b2){echo \"修改失败,回滚\".$mysqli->error;$mysqli->rollback();}else{echo \"修改成功!\";$mysqli->commit();}$mysqli->close();?>
当我们提交页面后,查询数据库,发现数据没有变化,说明回滚有效果,事务控制起了效果,事务控制就说到这里。以上就是本篇文章的全部内容啦,如有错误,请斧正。