PHP學習筆記(二)--資料庫操作
下面使用簡單的例子說下在PHP中操作MySql資料庫,內容包括連線資料庫、查詢操作、事務及儲存過程。
1、訪問MySql一般步驟
1)連線MySql伺服器
使用mysql_connect()函式建立與MySql伺服器的連線。
2)選擇MySql資料庫
使用mysql_select_db()函式選擇MySql伺服器上的資料庫,並與資料庫建立連線。
3)執行SQL語句
使用mysql_query()函式執行SQL語句。(包括增加、刪除、修改、查詢、顯示)
4)關閉結果集
使用mysql_free_result($result)關閉結果集,以釋放資源。
5)關閉MySql伺服器連線
每一次呼叫mysql_connect()或mysql_query()函式都會消耗系統資源,使用mysql_close($link)關閉與伺服器的連線。
說明:PHP中與資料庫中的連線是非持久型連線,系統會自動回收。如果對資料庫的訪問頻繁可以建立持續連線,呼叫函式mysql_pconnect(0代替mysql_connect(),建立持續連線在本程式結束時不需要呼叫mysql_close()來關閉與資料庫伺服器的連線,下次執行mysql_pconnect()時,系統直接返回已經建立的持續連線ID號,而不是直接去連線資料庫。
2、操作MySql資料庫的方法
- 基本連線查詢函式
1)mysql_connect(‘hostname’,’username’,’password’);
注:hostname為伺服器的主機名或IP,預設埠號為3306.
2)mysql_select_db(‘databasename’,[,resource link_identifier]);
注:如果沒有指定resource link_identifier則使用上一個開啟的連線。如果沒有開啟的連線,則呼叫mysql_connect()函式來嘗試開啟一個數據庫並使用。
4)mysql_query(<SQL語句>,[,resource link_identifier]);
注:在mysql_query()函式中執行的SQL語句不應以分號”;”結尾。mysql_unbuffered_query()函式傳送一條SQL查詢語句,但是不獲取和快取結果集。
使用示例:(root使用者登入沒有設定密碼,資料庫名為students,資料庫表為score)
<?php
$link=mysql_connect("localhost","root") or die("Error,Can't connect mySql");
$db_selected=mysql_select_db("students",$link);
$result=mysql_query("insert into score values('kit',78)",$link);//執行插入操作
$result=mysql_query("delete from score where name ='zhangsan'",$link); //執行刪除操作
$result=mysql_query("update score set english=77 where name='zhangsan'");//執行更新操作
$result=mysql_query("select * from score",$link);//執行查詢操作
mysql_free_result($result);
mysql_close($link);
?>
- mysql_fetch_array()函式
mysql_fetch_array()函式從陣列結果集中獲取資訊
使用示例:
資料庫表score內容如下:
<?php
$link=mysql_connect("localhost","root") or die("Error,Can't connect mySql");
$db_selected=mysql_select_db("students",$link);
mysql_query("set names gb2312");//設定編碼格式為GB2312,防止亂碼
$result=mysql_query("select * from score where name like '%i%'",$link);//執行查詢操作
$info=mysql_fetch_array($result);
?>
<table>
<tr>
<td>姓名</td>
<td>英語分數</td>
</tr>
<?php
do{
?>
<tr>
<th><?php echo $info[name];?></th>
<th><?php echo $info[english];?></th>
</tr>
<?php
}while ($info = mysql_fetch_array($result));
?>
</table>
注意:設定編碼格式為GB2312,防止亂碼。萬用字元”%”可以匹配零個或任意多個字元。
- mysql_fetch_object()函式
使用mysql_fetch_object()函式從結果集中獲取一行作為物件
示例:
<?php
$link=mysql_connect("localhost","root") or die("Error,Can't connect mySql".mysql_errno());
$db_selected=mysql_select_db("students",$link);
mysql_query("set names gb2312");//設定編碼格式為GB2312,防止亂碼
$result=mysql_query("select * from score",$link);//執行查詢操作
$info=mysql_fetch_object($result);
?>
<table>
<tr>
<td>姓名</td>
<td>英語分數</td>
</tr>
<?php
do{
?>
<tr>
<th><?php echo $info->name;?></th>
<th><?php echo $info->english;?></th>
</tr>
<?php
}while ($info = mysql_fetch_object($result));
?>
</table>
- mysql_fetch_row()函式
該函式逐行獲取結果集中的每條記錄。
示例:
<?php
$link=mysql_connect("localhost","root") or die("Error,Can't connect mySql".mysql_errno());
$db_selected=mysql_select_db("students",$link);
mysql_query("set names gb2312");//設定編碼格式為GB2312,防止亂碼
$result=mysql_query("select * from score",$link);//執行查詢操作
$info=mysql_fetch_row($result);
?>
<table>
<tr>
<td>姓名</td>
<td>英語分數</td>
</tr>
<?php
do{
?>
<tr>
<th><?php echo $info[0];?></th>
<th><?php echo $info[1];?></th>
</tr>
<?php
}while ($info = mysql_fetch_row($result));
?>
</table>
- mysql_num_rows()函式
使用mysql_num_rows()函式可以獲取由select語句查詢到的結果集中行的數目。
示例:
<?php
$link=mysql_connect("localhost","root") or die("Error,Can't connect mySql".mysql_errno());
$db_selected=mysql_select_db("students",$link);
mysql_query("set names gb2312");//設定編碼格式為GB2312,防止亂碼
$result=mysql_query("select * from score",$link);//執行查詢操作
$count=mysql_num_rows($result);
echo "查詢結果總數為:".$count;
mysql_free_result($result);
mysql_close($link);
?>
注:要獲取有Insert、update、delete語句所影響的資料行數,則必須使用mysql_affected_rows()函式來實現。
3、PDO操作資料庫
要使用PDO需要在zend Studios安裝目錄下的php.ini檔案中加上extession=php_pdo_mysql.dll
及extestion=php.pdo.dll,入下圖:
- 連線資料庫
PDO建構函式如下:
_construct(string $dsn[,string $username[,string $password[,array $driver_options]]]);
引數說明:dsn為資料來源名稱,包括主機埠號和資料庫名稱。
【例1】連線mySql資料庫
<?php
//header(“Content-Type:text/html;charset=uft-8”);
$dsn="mysql:host=localhost;dbname=students";
try {
$pdo=new PDO($dsn, "root");
echo "PDO連線成功!";
} catch (Exception $e) {
echo "連線失敗!".$e->getMessage();
}
【例2】使用ODBC連線MS Sql Server資料庫
<?php
$dsn="odbc:Driver={SQL Server};server=localhost;database=tmp";
try {
$pdo=new PDO($dsn, "root");
echo "PDO連線成功!";
} catch (Exception $e) {
echo "連線失敗!".$e->getMessage();
}
- 執行sql語句
exec()方法返回sql語句收影響的行數,語法為:
int PDO::exec(string statement)
引數statement是要執行的SQL語句,通常用於INSERT,DELETE和UPDATE語句中。
query()方法通常用於返回執行查詢後的結果集,語法如下:
PDOStatement PDO::query(string statement)
引數statement為要執行的SQL語句。
Prepare()和execute()方法
prepaer()方法做查詢的準備工作,然後通過execte()方法執行查詢,還可以通過bindParam()方法來繫結引數提供 給execute()方法。語法如下:
PDOStatement PDO::prepare(string statement[,array driver_options])
bool PDOStatement::execute([array input_parameters])
示例:
<?php
$dsn="odbc:Driver={SQL Server};server=localhost;database=tmp";
$pdo=new PDO($dsn, "sa","123456");
$query="select * from Student";
$result=$pdo->prepare($query);
$result->execute();
?>
注:綠色背景部分可以用$result=$pdo->query($query);代替。
- PDO中獲取結果集—fetch()
fetch()方法獲取結果集中的下一行資料,語法格式:
mixed PDOStatement::fetch([int_fetch_style[,int cursor_orientation[,int cursor_offset]]])
引數說名:
引數fect_style可取值如下:
值 |
說明 |
PDO::FETCH_ASOC |
關聯陣列形式 |
PDO::FETCH_NUM |
關聯索引陣列形式 |
PDO::FETCH_BOTH |
兩者陣列形式都有,這是預設值 |
PDO::FETCH_OBJ |
按照物件的形式,類似於以前的mysql_fetch_object() |
PDO::FETCH_BOUND |
以布林值的形式返回結果,同時將獲取的列值賦給bindParam()方法中指定的變數 |
PDO::FECTH_LAZY |
以關聯陣列、索引陣列和物件3種形式返回結果 |
引數cursor_orientation可用於獲取指定的一行;
引數cursor_offset表示遊標的偏移量。
示例:
資料庫表student內容如下:
<?php
$dsn="odbc:Driver={SQL Server};server=localhost;database=tmp";
try {
$pdo=new PDO($dsn, "sa","123456");
$query="select * from Student";
$result=$pdo->prepare($query);
$result->execute();
?>
<table>
<tr>
<th>學號</th>
<th>姓名</th>
<th>性別</th>
<th>年齡</th>
<th>所在省份</th>
<th>居住城市</th>
</tr>
<?php
while ($res=$result->fetch(pdo::FETCH_ASSOC)){
?>
<tr>
<td><?php echo $res['no']?></td>
<td><?php echo $res['name']?></td>
<td><?php echo $res['sex']?></td>
<td><?php echo $res['age']?></td>
<td><?php echo $res['province']?></td>
<td><?php echo $res['city']?></td>
</tr>
<?php
}
?>
</table>
<?php
} catch (Exception $e) {
echo "連線失敗!".$e->getMessage();
}
- PDO中獲取結果集—fetchAll()
fetchAll()方法獲取結果集中的所有航,語法如下:
array PDOStatement::fetchAll([int fetch_style[,int column_index]]);
引數column_index為欄位的索引值。
示例:
<?php
$dsn="odbc:Driver={SQL Server};server=localhost;database=tmp";
try {
$pdo=new PDO($dsn, "sa","123456");
$query="select * from Student";
$result=$pdo->prepare($query);
$result->execute();
?>
<table>
<tr>
<th>學號</th>
<th>姓名</th>
<th>性別</th>
<th>年齡</th>
<th>所在省份</th>
<th>居住城市</th>
</tr>
<?php
$res=$result->fetchAll(pdo::FETCH_ASSOC);
for($index=0;$index<count($res);$index++){
?>
<tr>
<td><?php echo $res[$index]['no']?></td>
<td><?php echo $res[$index]['name']?></td>
<td><?php echo $res[$index]['sex']?></td>
<td><?php echo $res[$index]['age']?></td>
<td><?php echo $res[$index]['province']?></td>
<td><?php echo $res[$index]['city']?></td>
</tr>
<?php
}
?>
</table>
<?php
} catch (Exception $e) {
echo "連線失敗!".$e->getMessage();
}
- PDO中獲取結果集—fetchColumn()
fetchColumn()方法獲取結果集中下一行指定列的值,語法格式為:
string PDOStatement::fetchColumn([int column_number]);
引數column_number從0開始,如果省略該引數則從第1列開始取值。
示例:
<?php
$dsn="odbc:Driver={SQL Server};server=localhost;database=tmp";
try {
$pdo=new PDO($dsn, "sa","123456");
$query="select * from Student";
$result=$pdo->prepare($query);
$result->execute();
?>
<table>
<tr>
<th>姓名</th>
</tr>
<?php
while($res=$result->fetchColumn(1)){
?>
<tr>
<td><?php echo $res?></td>
</tr>
<?php
}
?>
</table>
<?php
} catch (Exception $e) {
echo "連線失敗!".$e->getMessage();
}
4、PDO中錯誤處理
PDO中捕獲SQL語句中的錯誤有以下三種模式:
PDO::ERRORMODE_SILIENT:設定PDStatement物件的errorCode屬性,但是不進行任何其它操作;
PDO::ERRORMODE_WARNING:會產生一個PHP警告,並設定errorCode屬性;
PDO::ERRORMODE_EXCEPTION:會建立一個PDOException,並設定errorCode屬性。
示例:當查詢一個不存在的資料庫表時,
如果為PDO::ERRORMODE_SILIENT模式則伍任何錯誤輸出;若為PDO::ERRORMODE_WARNING模式輸出錯誤如下:
若為PDO::ERRORMODE_EXCEPTION模式輸出錯誤如下:
errorCode()方法用於獲取在操作資料庫控制代碼時所發生的錯誤程式碼;
errorInfo()方法用於獲取操作資料庫控制代碼時所發生的錯誤資訊;
【示例1】
<?php
$dsn='mysql:host=localhost;dbname=students';
try {
$pdo=new PDO($dsn,"root","");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$query="select * from score1";
$result=$pdo->prepare($query);
$result->execute();
} catch (Exception $e) {
echo "連線失敗!".$e->getMessage();
echo "錯誤程式碼:".$pdo->errorCode();
print_r($pdo->errorInfo());
}
【示例2】資料庫表score1不存在
<?php
$dsn='mysql:host=localhost;dbname=students';
try {
$pdo=new PDO($dsn,"root","");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$query="select * from score1";
$result=$pdo->prepare($query);
$result->execute();
} catch (Exception $e) {
echo "<pre>";
echo "ErrorInfo:".$e->getMessage()."<br/>";
echo "ErrorCode:".$e->getCode()."<br/>";
echo "File:".$e->getFile()."<br/>";
echo "Line:".$e->getLine()."<br/>";
echo "Trace:".$e->getTraceAsString()."<br/>";
echo "</pre>";
}
輸出錯誤資訊如下:
5、PDO中事物處理
beginTransaction()開啟事務,commit()提交事務;rollBack()回滾事務。
示例:
資料庫表score有name和english兩個欄位,下面插入兩條記錄,第一條記錄是合法的,第二條記錄是不法的,會導致操作失敗。使用了事務後,兩條記錄都不會插入到資料庫,如果不使用事務,則第1條記錄會插入到資料庫。
<?php
$dsn='mysql:host=localhost;dbname=students;charset=gbk';//設定編碼格式
try {
$pdo=new PDO($dsn,"root","");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->beginTransaction();//開啟事務
$result=$pdo->query("insert into score values('張琴',88)");
$result=$pdo->query("insert into score values('鄭三',88,'asd’)");
$pdo->commit();//提交事務
} catch (Exception $e) {
echo "ErrorInfo:".$e->getMessage()."<br/>";
$pdo->rollBack();//事務回滾
}
?>
6、PDO中儲存過程
在mySql中建立儲存過程pro_reg,
mysql> drop procedure if exists pro_reg;
mysql> delimiter //
mysql> create procedure pro_reg(in name nvarchar(80),in age int,in address nvarc
har(200))
-> begin
-> insert into tb_reg(name,age,address) values(name,age,address);
-> end;
-> //
注:delimiter //作用是將結束符更改為//。資料庫tb_reg有三個欄位:name,age,address.
示例:
<?php
$dsn='mysql:host=localhost;dbname=students';
try {
$pdo=new PDO($dsn,"root","");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->query("set names gbk");
//$query="call pro_reg('張三',22,'廣東省廣州市')";
$name='李思';
$age=30;
$address='湖北省武漢市';
$query="call pro_reg('$name','$age','$address')";
$result=$pdo->prepare($query);
if($result->execute()){
echo "資料庫新增成功!";
}
else {
echo "資料庫新增失敗!";
}
} catch (Exception $e) {
echo "ErrorInfo:".$e->getMessage()."<br/>";
}
?>
執行後結果為: