PHP面向物件操作資料庫--MySQLI類
自學PHP,這幾天學到了連線資料庫,乾脆把MySQLI的API全過一遍吧!
MySQLI
代表PHP和Mysql資料庫之間的一個連線。
1.mysqli::affected_rows :
返回影響到資料表的行數
<?php $con=new MySQLi("localhost","root","123456"); $con->select_db("mysql"); $sql="insert into t_member values('馬六','maliu')"; $con->query($sql); echo $con->affected_rows; ?>
2.mysqli::autocommit :
檢視 MySQL 客戶端的事務提交方式命令:select @@autocommit;
修改 MySQL 客戶端的事務提交方式為手動提交命令:set @@autocommit = 0;
關閉自動提交的原因,事務作為一個獨立處理最小單元,往往需要處理一系列連續的資料操作,這些操作被視為一個整體,需要同時成功或同時失敗,而不能其中某個操作成功;比如:A匯款給B,B接收到歀;即 A的賬戶扣款,而B的賬戶增加;必須同時成功或同時失敗;如果成功則commit否則整體回滾;只對區域性(當前命令列視窗)有效;若全域性有效得修改檔案;
下面程式碼如果不加帶星號那行程式碼,則資料不會插入到表中,但會存在快取裡,然後select會從快取裡取結果,結果裡會含有剛剛存入快取裡的資料,但是沒有插入到表中。如果程式結束而沒有commit,資料就不會存入到資料表中;如果加了帶星號的那行程式碼,則不上面事務做任何處理
<?php $con=new MySQLi("localhost","root","123456"); $con->select_db("mysql"); $con->autocommit(false); $sql="insert into t_member values('wewwwwww','aliu')"; $con->query($sql); * $con->rollback(); $sql="select * from t_member"; $result=$con->query($sql); while($row=$result->fetch_row()){ print_r($row); } ?>
3.mysqli::begin_transaction :
等同於上一個的功能;
<?php
$con=new MySQLi("localhost","root","123456");
$con->select_db("mysql");
$con->begin_transaction();
$sql="insert into t_member values('b','aliu')";
$con->query($sql);
$con->commit();//此處不可改為autocommit(true),這就是說$con->begin_transaction()不等於將autocommit()的值設為false
?>
4.mysqli::change_user;
改變當前所連線的資料庫
$con->change_user("root","123456","sys");//轉到了sys資料庫
5.mysqli::character_set_name :
返回當前資料庫連線的預設字元編碼
6.mysqli::close :
$con->close();不需要引數,過程化如mysqli_close()需要引數
7.mysqli::commit()
提交事務
8.mysqli::$connect_errno
返回連線資料庫時的錯誤程式碼
9.mysqli::$connect_errno
返回連線資料庫時的錯誤字串,即描述資訊
10.mysqli::__construct
mysqli的建構函式,當new mysqli的建構函式,當new物件的時候,自動呼叫
11.mysqli::errno
返回最近函式呼叫的錯誤程式碼,$con->errno 注意沒有括號
12.mysqli::$error_list
返回最近函式呼叫的一系列錯誤資訊,包含錯誤程式碼,sqlstate,錯誤描述,以陣列返回,可以利用print_r輸出
13.mysqli::$error
返回最近函式呼叫的錯誤描述資訊
14.mysqli_$field_count
返回最近查詢的列數,注意是列數
15.mysqli::get_charset
得到一個含有指定字符集的物件,可以用var_dump()來輸出這個物件,因為不是陣列所以不能用print_r
16.mysqli::$client_info
獲取MySQL客戶端資訊
17.mysqli::$client_version
作為一個整數返回MySQL客戶端的版本
18.mysqli::get_connection_stats
返回客戶端連線的統計資料,陣列形式
19.mysqli::$host_info
返回一個表述使用的連線型別的字串
20.mysqli::$protocol_version
返回MySQL使用的協議版本號
21.mysqli::init
初始化 MySQLi 並返回一個資源型別的值,這個值可以作為 mysqli_real_connect() 函式的傳入引數,mysqli::real_connect()不需要這種資源型別的值
22.mysqli::$insert_id
函式返回最後一個 SQL 語句(通常是 INSERT 語句) 所操作的表中設定為 AUTO_INCREMENT 的列的值。 如果最後一個 SQL 語句不是 INSERT 或者 UPDATE 語句, 或者所操作的表中沒有設定為 AUTO_INCREMENT 的列, 返回值為 0。
Note:
如果在所執行的 INSERT 或者 UPDATE 語句中使用了資料庫函式 LAST_INSERT_ID()。 有可能會影響 mysqli_insert_id() 函式的返回值。
23.mysqli::kill
本函式可以用來讓伺服器殺掉 processid 引數指定的 執行緒 ID。資料庫連線對應的執行緒 ID 可以通過 呼叫 mysqli::$thread_id 得到。如果僅僅想中止某個查詢,請使用這個 SQL 語句: KILL QUERY processid。
<?php
$con=new MySQLi("localhost","root","123456");
$con->select_db("mysql");
$id=$con->thread_id;
$con->kill($id);
$sql="select * from t_member where name='b'";
$ree=$con->query($sql);
?>
24.mysqli::multi_query
用來一次執行多條語句的函式
<?php
$con=new mysqli("localhost","root","123456");
$con->select_db("mysql");
$sql="select * from t_member where name='b';";//注意每一條語句都以分號結尾
$sql.="select * from t_member where name='c'";
/* 批量執行查詢 */
if ($con->multi_query($sql)) { //判斷此函式執行是否成功
do {
/* store first result set */
if ($result = $con->store_result()) { //用來獲取多條查詢結果中的第一條查詢的結果,這個結果非陣列和query得到的是一樣的 所以還得用mysqli_result中的方法
while ($row = $result->fetch_row()) { //用fetch_row來得到結果集中的第一行,雖然只有一行
printf("%s\n", $row[0]);
}
}
/* print divider */
if ($con->more_results()) {
printf("-----------------\n");
}
} while (@$con->next_result());//為讀取下一個結果集作準備
}
?>
25.mysqli::more_results
檢查批量查詢中是否還有查詢結果
26.mysqli::next_result
mysqli::multi_query() 函式執行之後, 為讀取下一個結果集做準備, 然後可以使用 mysqli::store_result() 或 mysqli::use_result() 函式讀取下一個結果集。
27.mysqli::options
設定一個連線的擴充套件選項,這些選項可以改變這個連線的行為。
如果要對多個選項進行設定,可以多次呼叫此函式來。
mysqli::options() 需要在 mysqli::init() 函式之後、 mysqli::real_connect() 函式之前被呼叫。
---------------------------------------------------------------------------------------------------------------
| MYSQLI_OPT_CONNECT_TIMEOUT 連線超時設定,以秒為單位(在 Windows 平臺上,PHP 5.3.1 之後才支援此選項)。 |
| MYSQLI_OPT_LOCAL_INFILE 啟用或禁用 LOAD LOCAL INFILE 語句 |
| MYSQLI_INIT_COMMAND 成功建立 MySQL 連線之後要執行的 SQL 語句 |
| MYSQLI_READ_DEFAULT_FILE 從指定的檔案中讀取選項,而不是使用 my.cnf 中的選項 |
| MYSQLI_READ_DEFAULT_GROUP 從 my.cnf 或者 MYSQL_READ_DEFAULT_FILE 指定的檔案中 讀取指定的組中的選項。 |
| MYSQLI_SERVER_PUBLIC_KEY SHA-256 認證模式下,要使用的 RSA 公鑰檔案。 |
| MYSQLI_OPT_NET_CMD_BUFFER_SIZE 內部命令/網路緩衝大小, 僅在 mysqlnd 驅動下有效。 |
| MYSQLI_OPT_NET_READ_BUFFER_SIZE 以位元組為單位,讀取 MySQL 命令報文時候的塊大小, 僅在 mysqlnd 驅動下有效 |
| MYSQLI_OPT_INT_AND_FLOAT_NATIVE 將整數和浮點數型別的列轉換成 PHP 的數值型別, 僅在 mysqlnd 驅動下有效 |
| MYSQLI_OPT_SSL_VERIFY_SERVER_CERT |
---------------------------------------------------------------------------------------------------------------
<?php
$mysqli = mysqli_init();
if (!$mysqli) {
die('mysqli_init failed');
}
if (!$mysqli->options(MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT = 0')) {
die('Setting MYSQLI_INIT_COMMAND failed');
}
if (!$mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5)) {
die('Setting MYSQLI_OPT_CONNECT_TIMEOUT failed');
}
if (!$mysqli->real_connect('localhost', 'my_user', 'my_password', 'my_db')) {
die('Connect Error (' . mysqli_connect_errno() . ') '
. mysqli_connect_error());
}
echo 'Success... ' . $mysqli->host_info . "\n";
$mysqli->close();
?>
28.mysqli::ping
檢查到伺服器的連線是否還正常。
在啟用 mysqli.reconnect 選項的前提下, 如果連線已經斷開, ping 操作會嘗試重新建立連線。
Note: mysqlnd 驅動會忽略 php.ini 中的 mysqli.reconnect 選項, 所以它不會自動重連。
客戶端建立連線之後,長時間處於閒置狀態, 可以用此函式來檢查伺服器是否關閉了這個連線, 如有必要,將會自動重新建立到伺服器的連線。
29.mysqli::prepare ( string $query )
做好執行 SQL 語句的準備,返回一個語句控制代碼,可以對這個控制代碼進行後續的操作。 這裡僅僅支援單一的 SQL 語句,不支援多 SQL 語句。
在執行語句之前,需要使用 mysqli_stmt::bind_param() 函式 對佔位符引數進行繫結。 同樣,在獲取結果之前,必須使用 mysqli_stmt::bind_result() 函式對返回的列值進行繫結。
SQL 語句中可以包含一個或者多個問號(?) 表示語句的引數。
SQL 語句中,僅允許在特定的位置出現問號引數佔位符。 例如,在 INSERT 語句中的 VALUES() 子句中可以使用引數佔位符,來表示對應列的值。也可以在 WHERE 字句中使用引數來表示 要進行比較的值。
但是,並不是所有的地方都允許使用引數佔位符, 例如對於表名、列名這樣的 SQL 語句中的標識位置, 就不可以使用引數佔位。 SELECT 語句中的列名就不可以使用引數。 另外,對於 = 這樣的邏輯比較操作也不可以在兩側都使用引數, 否則伺服器在解析 SQL 的時候就不知道該如何檢測引數型別了。 也不可以在 NULL 條件中使用問號, 也就是說不可以寫成:? IS NULL。 一般而言,引數也只能用在資料操作(DML)語句中, 不可以用在資料定義(DDL)語句中。
<?php
$con=new mysqli("localhost","root","123456");
$con->select_db("mysql");
if($bin=$con->prepare("select * from t_member where name=? and password=?")){//返回一個控制代碼,必須用一個派一個變數
$name1="c";
$password1="2";
$bin->bind_param("ss",$name1,$password1);//繫結引數,除了第一個引數外不能用直接量,得用變數
$bin->execute();//mysqli_stmt中的執行查詢,不像Mysqli中的query返回的是一個物件,而是將查詢的結果放在mysql伺服器,等待fetch逐條來取,然後相應的繫結再bind_result中的各個變數中
$bin->bind_result($name,$result);//將查詢結果的列值繫結到變數,
while($bin->fetch()){//獲取查詢結果的值
printf("%s %s",$name,$result);
}
$bin->close();// 關於語句物件
}
?>
使用預處理的好處:
(1)可以通過驅動讓服務端快取查詢計劃,從而提高查詢效率;
(2)可以防止SQL注入,自動轉義一些特殊字元.
壞處:
(1)本地到一個連線,以便另一個連線不能再使用
(2)儲存函式中不能使用(儲存過程是可以的)
(3)有可能會導致“洩漏”如果你忘記釋放它
30.mysqli::query ( string $query [, int $resultmode = MYSQLI_STORE_RESULT ] )
對資料庫執行一次查詢
其後第二個引數預設為MYSQLI_STORE_RESULT,也可以是MYSQLI_USE _RESULT,他們的區別是 mysql_use_result()的結果必須“一次性用完”,也就是說用它得到一個result後,必須反覆用mysql_fetch_row()讀取其結果直至該函式返回null為止,否則如果你再次進行mysql查詢,會得到“Commands out of sync; you can't run this command now”的錯誤。 而mysql_store_result()得到result是存下來的,你無需把全部行結果讀完,就可以進行另外的查詢。比如你進行一個查詢,得到一系列記錄,再根據這些結果,用一個迴圈再進行資料庫查詢,就只能用mysql_store_result()。
<?php
$con=new mysqli("localhost","root","123456");
$con->select_db("mysql");
$sql="select * from t_member";
$re=$con->query($sql,MYSQLI_USE_RESULT);
$row=$re->fetch_row();
printf("%s %s",$row[0],$row[1]);
$sql="select * from t_member";
$re=$con->query($sql,MYSQLI_USE_RESULT);
$row=$re->fetch_row();
printf("%s %s",$row[0],$row[1]);
?>//這樣會報錯
<?php
$con=new mysqli("localhost","root","123456");
$con->select_db("mysql");
$sql="select * from t_member";
$re=$con->query($sql);
while($row=$re->fetch_row()){
printf("%s %s",$row[0],$row[1]);
}
?>//這樣則不會
31.mysqli::real_connect
建立一個 MySQL 伺服器連線
32.mysqli::real_escape_string
根據當前連線的字符集,對於 SQL 語句中的特殊字元進行轉義
此函式用來對字串中的特殊字元進行轉義, 以使得這個字串是一個合法的 SQL 語句。 傳入的字串會根據當前連線的字符集進行轉義,得到一個編碼後的合法的 SQL 語句。
在呼叫 mysqli_real_escape_string() 函式之前, 必須先通過呼叫 mysqli_set_charset() 函式或者在 MySQL 伺服器端設定字符集。 更多資訊請參考 字符集。
<?php
// 假定資料庫使用者名稱:root,密碼:123456,資料庫:RUNOOB
$con=mysqli_connect("localhost","root","123456","mysql");
if (mysqli_connect_errno($con))
{
echo "連線 MySQL 失敗: " . mysqli_connect_error();
}
$newname="菜鳥'";
// 沒有轉義 $newname 中特殊字元,執行失敗
//mysqli_query($con,"INSERT into websites2 (name,password) VALUES ('$newname','$newname')");
// 轉義特殊字元
$con->real_escape_string($newname);
// 轉義後插入,執行成功
$re=$con->query("INSERT into websites2 (name,password) VALUES ('$newname','$newname')");
if(!$re){
echo $con->error;
}
mysqli_close($con);
?>
33.mysqli::real_query
執行一個mysql查詢
返回值是bool值
<?php
$con=new MySQLi("localhost","root","123456");
$con->select_db("mysql");
$sql="select * from t_member";;
$re=$con->real_query($sql);
var_dump($re);
?>
34.mysqli::refresh
重新整理
35.mysqli::rollback
回退當前事務
<?php
$con=new MySQLi("localhost","root","123456");
$con->select_db("mysql");
$con->autocommit(false);
$sql="insert into t_member values('m','m')";
$con->query($sql);
$con->rollback();
$con->autocommit(true);
$con->close();
?>
36.mysqli::select_db
選擇用於資料庫查詢的預設資料庫
37.mysqli::set_charset
這應該是首選的用於改變字元編碼的方法,不建議使用mysqli_query()執行SQL請求的SET NAMES ...(如 SET NAMES utf8)。
38.mysqli::$sqlstate
返回一個包含 SQLSTATE 錯誤碼的字串,表示上一次 SQL 操作的錯誤。 錯誤碼是由 5 個字元構成,'00000' 表示沒有發生錯誤。 需要注意的是,並不是所有的 MySQL 錯誤都對映到 SQLSTATE 了, 未對映的錯誤訊息使用 HY000(綜合錯誤)表示。
<?php
$con=new MySQLi("localhost","root","123456");
$con->select_db("mysql");
$sql="CREATE TABLE City (ID INT, Name VARCHAR(30))";
$re=$con->query($sql);
if(!$re){
printf("%s",$con->error);
}
if(!$re){
printf("%s",$con->sqlstate);
}
$con->close();
?>
39.mysqli::set_local_infile_default
取消使用者指定的回撥函式
40.mysqli_set_local_infile_handler
設定 LOAD DATA LOCAL INFILE 命令的回撥函式
41.mysqli::stat
獲取當前系統狀態資訊
<?php
$con=new MySQLi("localhost","root","123456");
$con->select_db("mysql");
$sql="CREATE TABLE City (ID INT, Name VARCHAR(30))";
$re=$con->query($sql);
printf("%s",$con->stat());
$con->close();
?>
輸出:Uptime: 105949 Threads: 1 Questions: 11908 Slow queries: 0 Opens: 723 Flush tables: 1 Open tables: 608 Queries per second avg: 0.112
42.mysqli::stmt_init
初始化一條語句並返回一個用於mysqli_stmt::prepare(呼叫)的物件
<?php
$con=new MySQLi("localhost","root","123456");
$con->select_db("mysql");
$con->stmt_init();
$sql="select * from t_member";
$pre=$con->prepare($sql);
$pre->execute();
$pre->bind_result($name,$result);
while($row=$pre->fetch())
{
printf("%s %s",$name,$result);
}
?>
43.mysqli::store_result
select語句查詢之後的結果是出於快取區的,轉移上一次查詢返回的結果集
如果上一查詢並不產生結果集(例如,執行了一個 INSERT 語句), 那麼 mysqli_store_result() 會返回 FALSE。 如果讀取結果集失敗了,也會返回 FALSE。 如何區分是上面哪種情況導致此函式的呼叫返回了 FALSE? 你可以通過下面的方法來檢測: mysqli_error() 返回了非空的字串, mysqli_errno() 返回了非零值, 或者 mysqli_field_count() 返回了非零值, 都表示發生錯誤了。 還有一種可能的情況會導致此函式的呼叫返回 FALSE:上一次查詢 mysqli_query() 本身是成功的, 但是由於返回的結果集太大,無法為其分配足夠的記憶體來進行結果集轉移。 如果 mysqli_field_count() 函式返回了一個非零值,那麼表示 SQL 語句產生了一個非空的結果集。
執行查詢之後, 使用 mysqli_free_result() 函式來釋放結果集所佔用的記憶體, 是一個很有用的實戰經驗。 尤其是當使用 mysqli_store_result() 函式來轉移數量較大的結果集的時候, 釋放結果集記憶體的操作尤為重要。
44.mysqli::$thread_id
返回當前連線的執行緒 ID
執行緒 ID 是每次連線都重新分配的,也就是說它和連線是緊密相關的, 如果某個連線異常斷開了,然後重新建立了到資料庫的連線, 這個執行緒 ID 就不再是原來的那個了,它會發生變化。可以通過執行 SQL 語句:KILL QUERY processid 來殺掉對應連線上正在執行的 SQL 語句。
45.mysqli::thread_safe
返回是否是執行緒安全的,如果是的話,返回TRUE,否則返回FALSE。
46.mysqli::$warning_count
返回最近一次連線所出現的警告條數
MySQLI::result
代表從一個數據庫查詢中獲取的結果集。
1.mysqli_result::fetch_field
從結果集中取得列資訊並作為物件返回。自動指向下一個欄位
被返回的物件的屬性為:
name - 列名
table - 該列所在的表名
max_length - 該列最大長度
not_null - 1,如果該列不能為 NULL
primary_key - 1,如果該列是 primary key
unique_key - 1,如果該列是 unique key
multiple_key - 1,如果該列是 non-unique key
numeric - 1,如果該列是 numeric
blob - 1,如果該列是 BLOB
type - 該列的型別
unsigned - 1,如果該列是無符號數
zerofill - 1,如果該列是 zero-filled
2.mysqli_result::current_field
指向取得的結果集中的第一個欄位,然後每次迴圈依次往後值
<?php
$con=new mysqli("localhost","root","123456");
$con->select_db("mysql");
$sql="select * from t_member";
$res=$con->query($sql);
while($col=$res->fetch_field()){
$current=$res->current_field;
printf("col: %d\n", $current);
printf("Name: %s\n", $col->name);
printf("Table: %s\n", $col->table);
printf("max. Len: %d\n", $col->max_length);
printf("Flags: %d\n", $col->flags);
printf("Type: %d\n\n", $col->type);
}
?>
3.mysqli_result::data_seek
將取得的結果集中的指標指向指定的行數,一開始是0
<?php
$con=new mysqli("localhost","root","123456");
$con->select_db("mysql");
$sql="select * from t_member";//注意每一條語句都以分號結尾
$res=$con->query($sql);
$res->data_seek(2);//此處就是將指標指向第2+1行
$re=$res->fetch_row();
printf("%s %s",$re[0],$re[1]);
?>
4.mysqli_result::fetch_all([ int $resulttype = MYSQLI_NUM ])
將結果集轉換成陣列,引數resulttype有MYSQLI_ASSOC(鍵值對應不包含數字角標值對應),MYSQLI_NUM(數字角標值對應不包含鍵值對應),MYSQLI_BOTH(兩者都有)
<?php
$con=new mysqli("localhost","root","123456");
$con->select_db("mysql");
$sql="select * from t_member";//注意每一條語句都以分號結尾
$res=$con->query($sql);
/*
$post=$res->fetch_all( MYSQLI_BOTH);
print_r($post);
結果:Array (
[0] => Array ( [0] => b [name] => b [1] => 5 [password] => 5 )
[1] => Array ( [0] => c [name] => c [1] => 2 [password] => 2 )
[2] => Array ( [0] => j [name] => j [1] => 2 [password] => 2 )
[3] => Array ( [0] => m [name] => m [1] => m [password] => m )
[4] => Array ( [0] => n [name] => n [1] => m [password] => m )
)
*/
/*
$post=$res->fetch_all( MYSQLI_ASSOC);
print_r($post);
結果:Array (
[0] => Array ( [name] => b [password] => 5 )
[1] => Array ( [name] => c [password] => 2 )
[2] => Array ( [name] => j [password] => 2 )
[3] => Array ( [name] => m [password] => m )
[4] => Array ( [name] => n [password] => m )
)
*/
/*
$post=$res->fetch_all( MYSQLI_NUM);
print_r($post);
結果:Array (
[0] => Array ( [0] => b [1] => 5 )
[1] => Array ( [0] => c [1] => 2 )
[2] => Array ( [0] => j [1] => 2 )
[3] => Array ( [0] => m [1] => m )
[4] => Array ( [0] => n [1] => m )
)
*/
?>
5.mysqli_result::fetch_array
從結果集中取得一行,作為陣列,型別為BOTH,指標指向下一行
<?php
$con=new mysqli("localhost","root","123456");
$con->select_db("mysql");
$sql="select * from t_member";//注意每一條語句都以分號結尾
$res=$con->query($sql);
while($row=$res->fetch_array()){
printf("%s %s",$row[0],$row[1]);
}
?>
6.mysqli_result::fetch_assoc
從結果集中取得一行作為關聯陣列(鍵值陣列即BOTH中非array的那一半),指標指向下一行
7.mysqli_result::fetch_fields
返回結果集中每一行的欄位資訊,以陣列返回;
8.mysqli_result::fetch_object
將結果集的一行作為物件返回
9.mysqli_result::fetch_row
從結果集中取得一行作為關聯陣列(鍵值陣列即BOTH中非關聯陣列的那一半),指標指向下一行
10.mysqli_result::$field_count
獲取結果中的欄位數
11.mysqli_result::free_result
從結果集中取得行,然後釋放結果記憶體
<?php
$con=new mysqli("localhost","root","123456");
$con->select_db("mysql");
$sql="select * from t_member";//注意每一條語句都以分號結尾
$res=$con->query($sql);
while($array=$res->fetch_row()){
print_r($array);
}
$res->free_result(); //注意不是$array
?>
12.mysqli_result::$num_rows
獲取結果集長度,在不需要轉換成陣列的情況下
<?php
$con=new mysqli("localhost","root","123456");
$con->select_db("mysql");
$sql="select * from t_member";//注意每一條語句都以分號結尾
$res=$con->query($sql);
echo $res->num_rows;
?>