php查詢mysql總結和預處理

任務:進一步深入mysqli_multi_query()用法.

 

一、連接到mysql: $dbc = mysqli_connect(host,user,password,databasename);

等價於:

 $dbc = mysqli_connect(host,user,pwd); mysqli_select_db($dbc,db_name);

 

如果發生錯誤,可以調用:mysqli_connect_error() 返回錯誤信息,不帶參數。

 

 $dbc = @mysqli_connect(host,user,pwd,db) or die('無法連接到mysql:'.mysqli_connect_error());

 

@是錯誤控制運算符,防止在web瀏覽器顯示php錯誤。此外,@也可以放在mysqli_query前面。上面是一種首選做法,因爲錯誤將由or

 

 die處理。die()會終止腳本執行。 可以將連接文件放在路徑外。

 

 設置編碼:mysqli_query("set names gb2312");

 

二、執行查詢:不管是select, delete, update,insert 查詢都是用: $result=mysqli_query($dbc,SQL); 對於

 

insert ,delete,update等查詢不會返回結果,$result將返回true或false,因此可以用這個來判斷下一步: $result = mysqli_query

 

($dbc,sql); if($result) {//susses} 如果查詢沒有成功,必定發生某種mysql錯誤,可能調用 mysqli_error($dbc) //注意和

 

mysqli_connect_error()區別

 

 三、關閉連接: mysqli_close($dbc) 這不是必需要的,php會在腳本最後自動關閉,但最好寫上。

 

 四、多條查詢: mysqli_multi_query()允許同時執行多條查詢。但語法更復雜一點。特別是當返回結果時。 五、檢索select查詢結果:

 

 mysqli_fetch_array($result [, type])是最常用的,以數組格式一次返回一行數據。由它來配合while()來遍歷返回數據。帶有一個可

 

選參數type,用於指定返回的數組類型:關聯的還是索引的,或二者均可。參數類型如下: MYSQLI_ASSOC 示例:$rows

 

['columnName'] MYSQLI_NUM 示例:$rows[0] ,這一種效率較高一點。 MYSQLI_BOTH 示例:$rows[0]或$rows

 

['columnName'] 當使用mysqli_fetch_array($result [, type])後,可以採取一個可選步聚的是:一旦查詢結果完成了工作,即可釋放這

 

些信息,來消除$result佔用的系統內存開銷。這一步是可選的,PHP同樣也在會結果時自動清理: mysqli_free_result($result) //注意

 

參數是不是$rows! 流程如下: while($rows=mysqli_fetch_array($result)) //或while($rows=mysqli_fetch_array

 

($result,MYSQLI_ASSOC)) {//遍歷 .......code do something....... echo $rows[0] mysqli_free_result($result) }

 

注意:

 

mysqli_fetch_array() 可以是 MYSQLI_NUM 或 MYSQLI_ASSOC

 

mysqli_fetch_assoc()和mysqli_fetch_array($result,MYSQLI_ASSOC)等價。

 

六、確保sql安全,使用轉義函數: mysqli_real_escape_string($dbc,para) 該函數用於檢驗用戶提交的並將組合到sql查詢語句的變量

 

值,它將轉義那些有可能無意或帶惡意的字符。如單引號,在外國人的姓名有可能會包含該符號(如O'Toole),這時就需要用它。案例:

 

$name = $_POST['name']; $name = mysqli_real_escape_string($dbc,$name); $query = "Select ... From tb where

 

name='$name'"; //這樣可以確保帶入sql 時參數的安全。注意:如果在使用php6之前的版本,若啓用MAGIC QUOTES魔法引用時,那

 

麼在使用mysqli_real_escape_string前,需要用stripslashes(para)刪除魔法引用添加的任何斜槓,如下: $fn =

 

mysqli_real_escape_string($dbc,trim(stripslashes($_POST['firstName'])));

 

七、統計select返回的記錄數:使用mysqli_num_rows($result)統計select 返回的結果行數。$num=mysqli_num_rows($r),對於

 

上面所說的while流程,可以更改成以下更嚴謹的寫法,而不只是分析查詢是否成功,因爲如果數據庫爲空的話,就不會出錯。 $sql =

 

"select * from tb where id=$id"; $r = @mysqli_query($dbc,$sql); $num = mysqli_num_rows($r); if($num>0){ //這樣比if

 

($r)更準確。不是僅僅分析是否成功運行。 // Do something; mysqli_free_result($r) } mysqli_close($dbc);

 

八、返回insert ,update,delete受影響行數:和上面不同的是,如果查詢不是select則用mysqli_affected_rows()函數返回受影響行

 

數。用法如下: $num = mysqli_affected_rows($dbc); //注意參數是$dbc; 如: $q = "update tb set pass=SHA1

 

('$newpassword') where id=$row[0]"; $r = @myslqi_query($dbc,$q); if(mysqli_affected_rows($dbc)==1){ //Do

 

something }else{ echo mysqli_error($dbc); exit(); //終止腳本。 }

 

注意: 1、如果使用truncate tb清空表時,則

 

mysqli_affected_rows()會返回0,即使查詢成功執行並且刪除了每一行。

 

 2、如果用update查詢時,但實質上沒有更改任何列的值,比如用相同的密碼代替一箇舊密碼,則也會返回0。

 

九、批量查詢:預處理語句

 

(第12章第4節:P311)版本:MYSQL 4.1開始添加預處理。

 

php5可以使用。預處理的好處: 1、更大安全性。2、更好性能。3、批量查

 

詢。對於預處理語句,只會把查詢本身發送給mysql,並且只會解析一次,然後單獨把值發送給mysql。

 

$q = 'Insert into tb(num) values (?)';

 

 $stmt = mysqli_prepare($dbc,$q);

 

 mysqli_stmt_bind_param($stmt,'i',$n);

 

 for($n=1;$n<=100;$n++) { mysqli_stmt_execute($stmt); } 可以通過insert , update , delete , select 查詢創建預處理,

 

步驟:

 

1、定義查詢: $q = "select firstname,lastname from users where uid = ?"; //(正常則是uid=$id)

 

2、將查詢傳給mysql預處理: $stmt = mysqli_prepare($dbc,$q); //此時mysql會解析查詢,但不會執行。

 

3、將變量綁定到查詢佔位符"?",如下: mysqli_stmt_bind_param($stmt,'i',$id); 其中'i'的含義是mysql_stmt_bind_param函數

 

期望接收到的值爲int類型,

 

共有以下幾種:

 

字母               表示綁定的值類型

d                    Decimal

 

i                     Integer

 

b                    Blob (二進制類型)

 

 s                    所有其它類型 

 

 如果查詢語句有多個變量,如: $q = "select uid,firstname from users where email=? AND pass=SHA1(?)"; //注意這裏都沒有

 

對?問號加單引號,即使是字符型。這是和標準查詢的區別。多個變量直接在綁定時按順序在引號內列出即可。如下: $stmt =

 

mysqli_prepare($dbc,$q); mysqli_stmt_bind_param($stmt,'ss',$e,$p); 還需要注意的時,在調用綁定函數前,可以不需要先對變

 

量定義設置,如上面的$e,$p在下面才設置,這不會出錯。 4、完成綁定後,可以給php變量賦值(如果還沒有值的話)。然後執行語句。

 

$id=15; mysqli_stmt_execute($stmt); 5、關閉預處理: mysqli_stmt_close($stmt); 6、關閉連接 mysqli_close($dbc); 執行

 

預處理時,如有出錯則用mysqli_stmt_error($stmt)調用。 示例: $dbc =mysqli_connect

 

('localhost','username','pwd','forum'); $q = 'insert into messages(forumid,parentid,userid,subject,body,forumdate)

 

values(?,?,?,?,?,NOW())'; $stmt = mysqli_prepare($dbc,$q); mysqli_stmt_bind_param

 

($stmt,'iiiss',$forumid,$parentid,$userid,$subject,$body); $forumid = (int)$_POST['forumid']; $parentid=(int) $_POST

 

['parentid']; $user_id =3; $subject = strip_tags($_POST['subject']); //strip_tags $body = strip_tags($_POST['body']);

 

mysqli_stmt_execute($stmt); if(mysqli_stmt_affected_rows($stmt)==1) { //do .... }else{ echo mysqli_stmt_error

 

($stmt); } mysqli_stmt_close($stmt); mysqli_close($dbc); 以上演示了預處理的一種語句,

 

實際上預處理有兩種語句:

 

1、綁定參數(bound parameter):如上面的示例

 

2、綁定結果(bound result):將查詢結果綁定到php變量。

 

十、阻止sql注入:(第12章第4節:P311) 1、驗證在查詢中要使用的數據,如果有可能,就可執行類型強制轉換。如: $forumid =

 

(int)$_POST['forumid']; if($forumid>0) .... //如果強制轉換成int完=0時,則不符數據型要求。 2、使用

 

mysqli_real_escape_string($dbc,para) 3、使用mysqli_real_escape_string($dbc,para)替代辦法:預處理,參上面。

 

十一、早先的php和mysql連接方式: mysql_connect,在寫法上只差上面一個字母i,但用法差不多。以下簡單示例: $conn =

 

mysql_connect("127.0.0.1","mysqltest","123456");

 

 mysql_select_db("shop"); //如果用$selectdb = mysql_select_db("shop");則$selectdb=1

 

mysql_query("set names gb2312"); //mysql_query("set names utf8");

 

 $exec="select * from product"; $result=mysql_query($exec,$conn); //或:$result=mysql_query($exec); while

 

($rs=mysql_fetch_object($result)) { echo "品名:[".$rs->pname . "]   "; echo "價格:". $rs->price . "  "; echo "入庫時

 

間:".$rs->addTime . "  "; echo ""; } echo $result; 如果要進行結果判斷有無再輸出,則可以用: $conn = mysql_connect

 

("127.0.0.1","mysqltest","123456");

 

 mysql_select_db("shop");

 

 mysql_query("set names gb2312"); //mysql_query("set names utf8");

 

 $exec="select * from product"; if($result=mysql_query($exec,$conn)){ while($rs=mysql_fetch_object($result))

 

{ echo "品名:[".$rs->pname . "]   "; echo "價格:". $rs->price . "  "; echo "入庫時間:".$rs->addTime . "  "; echo "

"; } }

 

附:

 

A、在insert後取得最後一條記錄:2種方法:

 

1、使用mysql的:last_insert_id() 函數。“insert into ....;select last_insert_id()”

 

2、使用php 的 mysql_insert_id() 或mysqli_insert_id() 返回同樣的值: PHP的 mysql_insert_id ( [resource $link_identifier] )

 

函數可以返回你需要的ID。 可選參數是php連接mysql的句柄。 每個連接都有不同的句柄。如: mysql_query("INSERT INTO

 

mytable (product) values ('kossu')"); printf ("Last inserted record has id %d/n", mysql_insert_id());

 

 B、幾個函數: trim() , ltrim(), rtrim() exit(), strip_tags()去掉字符串中包含的任何 HTML 及 PHP 的標記字符串。若是字符串的

 

HTML 及 PHP 標籤原來就有錯,例如少了大於的符號,則也會返回錯誤。而本函數和 fgetss() 有着相同的功能。 $text = '

 

Test paragraph.

 

 

Other text'; echo strip_tags($text); //結果:Test paragraph. Other text // 許可用

 

 

and echo strip_tags($text, ''); //結果:

 

Other text

 

 

Test paragraph.

 

 

 

http://blog.sina.com.cn/s/blog_5674da320100i6tr.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章