前言
這篇文章會對PHP的MySQL擴充套件庫,MySQLI的擴充套件庫,SQL批量執行,事務控制等等進行一些簡單的講解。
MySQL擴充套件
PHP中MySQL擴充套件,雖然因為安全的原因,在PHP5.6及往上不在支援MySQL擴充套件庫,但是還是要學習的,通過編寫案例的方式來講解。
案例
先說下運算元據庫的大體思路吧,就是先獲取連線-》選擇資料庫-》設定操作編碼-》傳送sql指令-》對返回的結果進行處理-》釋放資源,斷開連線。案例是一個線上詞典查詢。下面是建立表的sql語句:
create database worddb
create 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工具類,程式碼如下:
<?php
class 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");
}
//完成select
function execute_dql($sql){
$res=mysql_query($sql) or die(mysql_error());
return $res;
}
//完成insert,update,delete
function 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);
}
?>
現在來測試一下吧,首先開啟前端頁面,如下圖:
接下來輸入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','12345@.com',30);
因為一會兒要插入資料,所以先插入一條,構造好後,開啟資料庫,查詢,發現沒有問題
接下來構造mysqli工具類程式碼如下:
<?php
class 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");
}
//進行select
public function execute_dql($sql){
$res=$this->mysqli->query($sql) or die($this->mysqli->error);
return $res;
}
//進行update,insert,delete
public 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,123@qq.com,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操作的作用是一次性取回多個結果集,下面看案例程式碼:
<?php
header("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擴充套件庫,批量執行SQL語句,接下來說一說MySQL事務控制。
資料庫配置
說MySQL事務控制之前,先檢視並修改資料庫引擎,檢視引擎的命令如下:
show engines
我們發現,只有InnoDB是支援事務的,所以先檢視一下現在得資料庫引擎:
發現是MyISAM,我們將它修改為InnoDB,開啟配置檔案my.ini,將“default-storage-engine=MYISAM”改為你想設定的,然後重啟即可。修改成功後,然後下一步就是程式碼實現。
案例
我們為什麼需要事務控制呢?想一想,如果這是一個轉賬得場景,是不是需要同時控制住,必須我減金額得同時你加金額,任何一個出錯都得轉賬失敗。也就是說要保持一致。這也是要進行事務控制得必要性。下面看案例程式碼:
<?php
header("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();
?>
當我們提交頁面後,查詢資料庫,發現資料沒有變化,說明回滾有效果,事務控制起了效果,事務控制就說到這裡。以上就是本篇文章的全部內容啦,如有錯誤,請斧正。