你需要的是Transaction吧
網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、微信小程序開(kāi)發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了壽縣免費(fèi)建站歡迎大家使用!
START?TRANSACTION
SELECT?******
UPDATE?******
UPDATE?******
COMMIT
PHP 使用 Mysqli 的 prepare 語(yǔ)句有什么好處
好處:
(1)解析查詢只有一次
(2)執(zhí)行一些查詢優(yōu)化步驟只有一次
(3)通過(guò)二進(jìn)制協(xié)議發(fā)送參數(shù)比送他們?yōu)锳SCII文本更有效
比如DATE,對(duì)于準(zhǔn)備之后,發(fā)送日期只用3個(gè)字節(jié);如果沒(méi)有準(zhǔn)備,日期必須以字符串的形式發(fā)送,需要數(shù)據(jù)庫(kù)方再解析,這樣需要發(fā)送10個(gè)字節(jié)。
(4)只有參數(shù)(不是整個(gè)查詢文本)需要為每個(gè)執(zhí)行要發(fā)送
(5)的MySQL直接存儲(chǔ)parameteres到服務(wù)器上的緩沖區(qū)
(6)安全性也有幫助,就沒(méi)有必要逃避或引用值。
壞處:
(1)本地到一個(gè)連接,以便另一個(gè)連接不能再使用
(2)不能使用MySQL查詢緩存(5.1版本之前)
(3)不總是更有效,如果你使用它只有一次
(4)存儲(chǔ)函數(shù)中不能使用(存儲(chǔ)過(guò)程是可以的)
(5)有可能會(huì)導(dǎo)致“泄漏”如果你忘記釋放它
1:可以在自己在文本里面寫好相關(guān)的建表語(yǔ)句,然后用phpmyadmin之類的工具導(dǎo)入到你的數(shù)據(jù)庫(kù),然后在通過(guò)程序連接數(shù)據(jù)庫(kù),插入,修改,刪除,查詢。一般開(kāi)發(fā)流程都是在程序開(kāi)發(fā)之前就需要規(guī)劃數(shù)據(jù)表的結(jié)構(gòu)的。(個(gè)人和企業(yè)自身用這樣就可以了)
2:就像你說(shuō)的那樣創(chuàng)建一個(gè)文件專門用來(lái)創(chuàng)建數(shù)據(jù)庫(kù)和表,也就是程序的安裝模塊,當(dāng)然也是需要在文本中寫相關(guān)的sql語(yǔ)句的,之后通過(guò)程序?qū)氲綌?shù)據(jù)庫(kù)去,創(chuàng)建好了之后可以把他刪除。(這種一般給別人開(kāi)發(fā)的時(shí)候用,像那些開(kāi)源的cms都是這樣的)
$sql
=
$mysqli-query("call
pro_login1('".$username."',
'".$password."')");
#這句假設(shè)是執(zhí)行SQL,那么這句話的意思是,調(diào)用query函數(shù),執(zhí)行
存儲(chǔ)過(guò)程pro_login1(存儲(chǔ)過(guò)程類似程序中的函數(shù)
$info
=
$sql-fetch_array(MYSQLI_ASSOC);
#如果$sql
變量實(shí)例的類和$mysqli實(shí)例化的類是同一個(gè)的話,這里是把剛剛query執(zhí)行返回的參數(shù)轉(zhuǎn)換成數(shù)組。MYSQLI_ASSOC是mysqli_query的一個(gè)參數(shù),具體你可以看看手冊(cè)
1
if(isset($_POST['username'])
trim($_POST['username'])!='')
2
{
3
require_once
'Db.php';
4
$username
=
trim($_POST['username']);
5
$password
=
trim($_POST['password']);
6
$sql
=
$mysqli-query("call
pro_login1('".$username."',
'".$password."')");
7
$info
=
$sql-fetch_array(MYSQLI_ASSOC);
8
if($info
!=
null){
9
$_SESSION['loginUsername']
=
$username;
10
echo
'scriptwindow.location.href="success.php";/script';
11
}else
{
12
echo
'div
style="width:300px;
height:30px;
line-height:30px;
border:1px
solid
#E59B04;
background-color:#FCF2E0;
color:#FF0000;"用戶名或密碼輸入有誤/div';
13
}
14
}
第一行先判斷傳如的用戶名是否存在并且密碼不能帶有空格
第三行引用的db.php,應(yīng)該是連接數(shù)據(jù)庫(kù)的配置文件
第四、五行是把用戶名和密碼的中的空格去掉
第六行把用戶名和密碼傳入到存儲(chǔ)過(guò)程中執(zhí)行
第七行返回一個(gè)數(shù)組
第八至十三行,判斷這個(gè)數(shù)組不是空,如果不是,就給一個(gè)session作為登錄標(biāo)識(shí),跳轉(zhuǎn)到另外一個(gè)頁(yè)面;否則就是提示用戶密碼錯(cuò)誤。
------------------------------
不懂就追問(wèn)把。
?php
/* 連接數(shù)據(jù)庫(kù)類 MysqlConnect */
class MysqlConnect{
private $dbhost=null;
private $dbuser=null;
private $dbpwd=null;
private $dbname=null;
private $dbport=null;
private $ifpdo=null;
private $dburi=null;
private $handler=null;
function __construct($dbhost,$dbuser,$dbpwd,$dbname,$dbport,$ifpdo,$dburi){
$this-dbhost=$dbhost;
$this-dbuser=$dbuser;
$this-dbpwd=$dbpwd;
$this-dbname=$dbname;
$this-dbport=$dbport;
$this-ifpdo=$ifpdo;
$this-dburi=$dburi;//PDO的URI參數(shù),可以查手冊(cè)
if($this-ifpdo==1){//表示調(diào)用PDO來(lái)操作數(shù)據(jù)庫(kù)
$this-handler=$this-CreatePdo();
}elseif($this-ifpdo==0){//這里可以寫MYSQLI的方法
$this-handler=null;
}
}
/* ----------------這里是入口--------------------- */
//@param sql:外部調(diào)用時(shí)傳遞的完整SQL語(yǔ)句
//@param bindArray:綁定的參數(shù)數(shù)組,與sql語(yǔ)句有關(guān),如果沒(méi)有PDO占位符此處為空
//@param action:傳遞操作參數(shù),"select"/"update"/"delete"/"insert"
public function exeSql($sql,$bindArray=array(),$action=""){
$stmt=$this-handler-prepare($sql);
$stmt-execute($bindArray);
switch($action){
case "select":
return $stmt-fetch(PDO::FETCH_ASSOC);
break;
case "selectAll":
return $stmt-fetchAll(PDO::FETCH_ASSOC);
break;
case "update":
case "delete":
return $stmt-rowCount();
break;
case "insert":
return $this-handler-lastInsertId();
break;
case "count":
return $stmt-rowCount();
default:
return "";
}
}
public function query($sql){
return $this-handler-query($sql);
}
private function CreatePdo(){
try{
$handler=new PDO($this-dburi,$this-dbuser,$this-dbpwd);
$handler-setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
return $handler;
}catch(PDOException $e){
$e-getMessage();
$this-handler=null;
}
}
private function __get($args){
if($args=='handler'){
return $this-handler;
}
}
}
require(NEO_A_P.'\data\sqlconfig.php');//這里是sql的連接文件,下面創(chuàng)建對(duì)象的時(shí)候需要的變量就是這個(gè)文件里要有的
$handler=new MysqlConnect($dbhost,$dbuser,$dbpwd,$dbname,$dbport,$ifpdo,$dburi);
?
PHP MySQL 預(yù)處理語(yǔ)句
預(yù)處理語(yǔ)句對(duì)于防止 MySQL 注入是非常有用的。
預(yù)處理語(yǔ)句及綁定參數(shù)
預(yù)處理語(yǔ)句用于執(zhí)行多個(gè)相同的 SQL 語(yǔ)句,并且執(zhí)行效率更高。
預(yù)處理語(yǔ)句的工作原理如下:
預(yù)處理:創(chuàng)建 SQL 語(yǔ)句模板并發(fā)送到數(shù)據(jù)庫(kù)。預(yù)留的值使用參數(shù) "?" 標(biāo)記 。例如:
INSERT
INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)
數(shù)據(jù)庫(kù)解析,編譯,對(duì)SQL語(yǔ)句模板執(zhí)行查詢優(yōu)化,并存儲(chǔ)結(jié)果不輸出。
執(zhí)行:最后,將應(yīng)用綁定的值傳遞給參數(shù)("?" 標(biāo)記),數(shù)據(jù)庫(kù)執(zhí)行語(yǔ)句。應(yīng)用可以多次執(zhí)行語(yǔ)句,如果參數(shù)的值不一樣。
相比于直接執(zhí)行SQL語(yǔ)句,預(yù)處理語(yǔ)句有兩個(gè)主要優(yōu)點(diǎn):
預(yù)處理語(yǔ)句大大減少了分析時(shí)間,只做了一次查詢(雖然語(yǔ)句多次執(zhí)行)。
綁定參數(shù)減少了服務(wù)器帶寬,你只需要發(fā)送查詢的參數(shù),而不是整個(gè)語(yǔ)句。
預(yù)處理語(yǔ)句針對(duì)SQL注入是非常有用的,因?yàn)閰?shù)值發(fā)送后使用不同的協(xié)議,保證了數(shù)據(jù)的合法性。
MySQLi 預(yù)處理語(yǔ)句
以下實(shí)例在 MySQLi 中使用了預(yù)處理語(yǔ)句,并綁定了相應(yīng)的參數(shù):
實(shí)例 (MySQLi 使用預(yù)處理語(yǔ)句)
?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// 創(chuàng)建連接
$conn = new mysqli($servername, $username, $password, $dbname);
// 檢測(cè)連接
if ($conn-connect_error) {
die("連接失敗: " . $conn-connect_error);
}
// 預(yù)處理及綁定
$stmt = $conn-prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)");
$stmt-bind_param("sss", $firstname, $lastname, $email);
// 設(shè)置參數(shù)并執(zhí)行
$firstname = "John";
$lastname = "Doe";
$email = "john@example.com";
$stmt-execute();
$firstname = "Mary";
$lastname = "Moe";
$email = "mary@example.com";
$stmt-execute();
$firstname = "Julie";
$lastname = "Dooley";
$email = "julie@example.com";
$stmt-execute();
echo "新記錄插入成功";
$stmt-close();
$conn-close();
?
解析以下實(shí)例的每行代碼:
"INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)"
在 SQL 語(yǔ)句中,我們使用了問(wèn)號(hào) (?),在此我們可以將問(wèn)號(hào)替換為整型,字符串,雙精度浮點(diǎn)型和布爾值。
接下來(lái),讓我們來(lái)看下 bind_param() 函數(shù):
$stmt-bind_param("sss", $firstname, $lastname, $email);
該函數(shù)綁定了 SQL 的參數(shù),且告訴數(shù)據(jù)庫(kù)參數(shù)的值。 "sss" 參數(shù)列處理其余參數(shù)的數(shù)據(jù)類型。s 字符告訴數(shù)據(jù)庫(kù)該參數(shù)為字符串。
參數(shù)有以下四種類型:
i - integer(整型)
d - double(雙精度浮點(diǎn)型)
s - string(字符串)
b - BLOB(binary large object:二進(jìn)制大對(duì)象)
每個(gè)參數(shù)都需要指定類型。
通過(guò)告訴數(shù)據(jù)庫(kù)參數(shù)的數(shù)據(jù)類型,可以降低 SQL 注入的風(fēng)險(xiǎn)。
注意: 如果你想插入其他數(shù)據(jù)(用戶輸入),對(duì)數(shù)據(jù)的驗(yàn)證是非常重要的。
PDO 中的預(yù)處理語(yǔ)句
以下實(shí)例我們?cè)?PDO 中使用了預(yù)處理語(yǔ)句并綁定參數(shù):
實(shí)例 (PDO 使用預(yù)處理語(yǔ)句)
?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDBPDO";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// 設(shè)置 PDO 錯(cuò)誤模式為異常
$conn-setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 預(yù)處理 SQL 并綁定參數(shù)
$stmt = $conn-prepare("INSERT INTO MyGuests (firstname, lastname, email)
VALUES (:firstname, :lastname, :email)");
$stmt-bindParam(':firstname', $firstname);
$stmt-bindParam(':lastname', $lastname);
$stmt-bindParam(':email', $email);
// 插入行
$firstname = "John";
$lastname = "Doe";
$email = "john@example.com";
$stmt-execute();
// 插入其他行
$firstname = "Mary";
$lastname = "Moe";
$email = "mary@example.com";
$stmt-execute();
// 插入其他行
$firstname = "Julie";
$lastname = "Dooley";
$email = "julie@example.com";
$stmt-execute();
echo "新記錄插入成功";
}
catch(PDOException $e)
{
echo $sql . "br" . $e-getMessage();
}
$conn = null;
?