HP 5 及以上版本建议使用以下方式连接 MySQL :
- MySQLi extension ("i" 意为 improved)
- PDO (PHP Data Objects)
PDO 应用在 12 种不同数据库中, MySQLi 只针对 MySQL 数据库。
如果你的项目需要在多种数据库中切换,建议使用 PDO
两者都是面向对象, 但 MySQLi 还提供了 API 接口
两者都支持预处理语句。 预处理语句可以防止 SQL 注入,对于 web 项目的安全性是非常重要的
连接mysql实例
,我们会使用以下三种方式来演示 PHP 操作 MySQL:
- MySQLi (面向对象)
- MySQLi (面向过程)
- PDO
mysqi的面向过程
如下包含连接数据库、创建数据库、创建表、插入一条数据、插入多条数据
<?php //面向过程连接数据库 $conn = mysqli_connect('localhost','root','root'); //判断是否连接成功 if(!$conn){die('连接数据库失败'.mysqli_connect_error()); }else{echo '连接成功';//创建数据库mytest$sql = 'create database mytest';if(mysqli_query($conn,$sql)){echo '执行成功'.$sql;}else{echo '执行失败'.mysqli_error($conn);}//选择数据库并且创建表执行插入语句if(mysqli_query($conn,'use mytest')){echo '切换数据库成功';$sql = "create table mytest(id int auto_increment primary key,name varchar(14) not null) ";//如创建表成功if(mysqli_query($conn,$sql)){echo '创建成功'.$sql;}else{echo '创建失败'.mysqli_error($conn);}//插入多条数据 插入一条数据时候后面不需要分号$sql="insert into mytest (name) values ('webcyh');";$sql.="insert into mytest (name) values ('hony');";//如果只是插入一条数据这里可以改为普通查询函数mysqli_query()if(mysqli_multi_query($conn,$sql)){echo '插入成功'.$sql;}else{echo '插入失败'.mysqli_error($conn);}}//关闭数据库连接mysqli_close($conn); }
语句预处理
预处理语句对于防止 MySQL 注入是非常有用的
预处理语句用于执行多个相同的 SQL 语句,并且执行效率更高
预处理语句的工作原理如下:
-
预处理:创建 SQL 语句模板并发送到数据库。预留的值使用参数 "?" 标记 。例如:
INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)
-
数据库解析,编译,对SQL语句模板执行查询优化,并存储结果不输出。
-
执行:最后,将应用绑定的值传递给参数("?" 标记),数据库执行语句。应用可以多次执行语句,如果参数的值不一样。
相比于直接执行SQL语句,预处理语句有两个主要优点:
-
预处理语句大大减少了分析时间,只做了一次查询(虽然语句多次执行)。
-
绑定参数减少了服务器带宽,你只需要发送查询的参数,而不是整个语句。
-
预处理语句针对SQL注入是非常有用的,因为参数值发送后使用不同的协议,保证了数据的合法性。
mysqli查询语句遇到问题
原因分析:
消息说明MYSQL数据库认为是这一个错误的命令执行顺序。原因在于MYSQL的存储过程执行完成后除了返回实际结果集还会返回存储过程执行的转态
,而上面的代码仅处理了第一个结果集,第二个结果集并没有被释放掉
建议使用mysqli_query()插入数据 每条语句只插入一条数据
解决后的代码:
<?php //面向过程连接数据库 $conn = mysqli_connect('localhost','root','root'); //判断是否连接成功 if(!$conn){die('连接数据库失败'.mysqli_connect_error()); }else{echo '连接成功';//创建数据库mytest$sql = 'create database mytest';if(mysqli_query($conn,$sql)){echo '执行成功'.$sql;}else{echo '执行失败'.mysqli_error($conn);}//选择数据库并且创建表执行插入语句if(mysqli_query($conn,'use mytest')){echo '切换数据库成功';$sql = "create table mytest(id int auto_increment primary key,name varchar(14) not null) ";//如创建表成功if(mysqli_query($conn,$sql)){echo '创建成功'.$sql;}else{echo '创建失败'.mysqli_error($conn);}//插入多条数据$sql="insert into mytest (name) values ('webcyh');";$sql.="insert into mytest (name) values ('hony');"; mysqli_autocommit($conn,FALSE);if (mysqli_multi_query($conn,$sql)){do {if ($result = mysqli_store_result()) {while ($row = result_fetch_row($rst)) {echo $row[0];}}} while (mysqli_next_result($conn));}mysqli_commit($conn);$sql='select name from mytest';$rst=mysqli_query($conn,$sql);var_dump($rst);//判断是否有结果if(mysqli_num_rows($rst)>0){echo '查询结果如下';while($row=mysqli_fetch_assoc($rst)){echo '姓名'.$row["name"];}}else{echo '没有结果'.mysqli_error($conn);}//查询数据并且输出 }//关闭数据库连接mysqli_close($conn); }
输出结果:
mysqli面向对象方式连接mysql数据库
<?php //mysqli面向对象使用mysql实例 如果你使用其他端口(默认为3306),为数据库参数添加空字符串,如: new mysqli("localhost", "username", "password", "", port) $conn = new mysqli('localhost','root','root'); //判断是否连接成功 if($conn->connect_error){echo '连接失败'.$conn->connect_error;//或者mysqli_connect_error(); }else{ //切换数据库$sql='use mytest';if($conn->query($sql) == TRUE){echo '切换成功';//插入数据使用语句预处理操作$stml=$conn->prepare("insert into test(name) values(?)");//绑定参数$stml->bind_param("s",$name);$name='webcyh';$stml->execute();echo '插入成功';$stml->close();//查询数据$sql='select * from test';$rst=$conn->query($sql);if($rst->num_rows>0){while($row = $rst->fetch_assoc()){echo $row['name'];}}}else{echo '切换失败'.$conn->error;}}//关闭数据库 $conn->close();
"INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)"
在 SQL 语句中,我们使用了问号 (?),在此我们可以将问号替换为整型,字符串,双精度浮点型和布尔值。
$stmt->bind_param("sss", $firstname, $lastname, $email);
该函数绑定了 SQL 的参数,且告诉数据库参数的值。 "sss" 参数列处理其余参数的数据类型。s 字符告诉数据库该参数为字符串。
参数有以下四种类型:
- i - integer(整型)
- d - double(双精度浮点型)
- s - string(字符串)
- b - BLOB(binary large object:二进制大对象)