1、第13章 PHP 5與MySQL建立網頁資料庫,13-1 PHP與MySQL的基礎 13-2 開啟與關閉資料庫連結 13-3 執行資料表查詢 13-4 取得資料表和欄位資訊 13-5 取得資料表的記錄資料 13-6 使用表格分頁顯示記錄資料 13-7 物件導向介面的資料庫存取,13-1 PHP與MySQL的基礎-說明,通常PHP技術建立網頁資料庫都是搭配MySQL資料庫系統,從90年代中期開始,ext/mysql擴充程式一直擔任PHP與MySQL資料庫間的橋樑,提供相關函數讓我們在PHP程式存取MySQL資料庫。 但是,PHP 5和MySQL 4.1版之後,ext/mysql擴充程式的相容性問
2、題一一浮現,因為ext/mysql沒有辨法支援MySQL 4.1之後版本的新功能,所以Georg Richter建立一套全新支援PHP 5的MySQL擴充程式,稱為ext/mysqli,可以支援MySQL 4.1之後版本的新功能,13-1 PHP與MySQL的基礎-特點1,易維護與高相容性:在ext/mysql需要使用複雜方式來使用MySQL的新功能,而ext/mysqli可以很容易作到,ext/mysqli擁有與MySQL Client Library更佳的相容性,換句話說,未來MySQL的新版功能,ext/mysqli也可以輕易支援。 更快速和更佳的安全性:ext/mysqli不只執行速度
3、最高可比舊版ext/mysql快40倍,而且ext/mysqli支援新版MySQL的密碼雜湊(Password Hashes)和驗證程序,提供比舊版更佳的安全性。,13-1 PHP與MySQL的基礎-特點2,相同的程序式介面:使用和ext/mysql相似的函數呼叫,大部分ext/mysqli的函數都擁有舊版ext/mysql的對應版本,舊版函數名稱為mysql_?(),新版只多一個i字母的mysqli_?()。 物件導向使用介面:新版ext/mysqli提供物件導向使用介面,可以使用物件方式存取MySQL資料庫。 支援新版MySQL的通訊協定:MySQL 4.1之後的版本提供全新的通訊協定,這
4、是一種比舊版更有效率和提供更多功能的通訊協定,例如:Prepared Statement存取資料庫。,13-2-1 開啟與關閉MySQL資料庫連結 13-2-2 開啟指定的資料庫 13-2-3 取得MySQL伺服器資訊,13-2-1 開啟與關閉MySQL資料庫連結-開啟與建立資料庫連結,PHP的ext/mysqli擴充程式提供相關函數可以開啟與關閉資料庫連結,並且在開啟時檢查是否有錯誤產生。 在PHP程式可以呼叫mysqli_connect()函數開啟與建立MySQL資料庫連結,如下所示: $link = mysqli_connect( localhost, / MySQL主機名稱 root,
5、 / 使用者名稱 123456, / 密碼 school); / 預設使用的資料庫名稱,13-2-1 開啟與關閉MySQL資料庫連結-錯誤處理,if ( !$link ) echo “連結錯誤代碼: “.mysqli_connect_errno().“;echo “連結錯誤訊息: “.mysqli_connect_error().“;exit(); else / MySQL資料庫連結成功 ,13-2-1 開啟與關閉MySQL資料庫連結-錯誤處理函數,mysqli_connect_errno()和mysqli_connect_error()函數可以顯示錯誤訊息,各函數的說明如下表所示:,13-2
6、-1 開啟與關閉MySQL資料庫連結-關閉資料庫連結,當開啟資料庫連結後,如果不再需要存取MySQL資料庫,PHP程式可以呼叫mysqli_close()函數釋放資料庫連結資源佔用的記憶體,以便有效運用伺服器的記憶體資源,如下所示: mysqli_close($link); 上述函數的參數是mysqli_connect()函數傳回的物件變數,成功關閉傳回true,否則為false。,13-2-2 開啟指定的資料庫,PHP程式除了可以在mysqli_connect()函數的第4個參數指定預設存取的資料庫外,PHP提供mysqli_select_db()函數可以選擇或更改預設存取的資料庫,如下所示
7、: if ( !mysqli_select_db($link, $dbname) )die(“無法開啟 $dbname 資料庫!“); elseecho “資料庫: $dbname 開啟成功!“;,13-2-3 取得MySQL伺服器資訊,PHP的ext/mysqli擴充程式提供相關函數可以取得MySQL伺服器等資訊,其說明如下表所示:,13-3 執行資料表查詢,13-3-1 查詢資料表的記錄資料 13-3-2 MySQL操作的錯誤處理,13-3-1 查詢資料表的記錄資料-說明,在PHP程式是呼叫mysqli_query()函數來執行資料表查詢。不過,因為第14章筆者才會詳細說明SQL語法,為了
8、方便測試,在此之前的程式範例,筆者都是使用同一個SQL查詢指令,如下所示: $sql = “SELECT * FROM students”; 上述SQL指令字串可以取回students資料表所有欄位和記錄資料。,13-3-1 查詢資料表的記錄資料-執行SQL指令的資料表查詢,在PHP程式呼叫mysqli_query()函數,執行參數的SQL指令來查詢資料表,如下所示: if ( $result = mysqli_query($link, $sql) ) 函數的第1個參數是開啟的資料庫連結,第2個參數是SQL指令字串,舊版mysql_query()函數的參數順序相反。,13-3-1 查詢資料表的
9、記錄資料-MySQL結果物件,結果物件可以視為使用表格儲存的記錄資料,每一個表格欄對應記錄欄位,每一列是一筆記錄,以此例的查詢結果是students資料表的所有記錄和欄位,如下圖所示:,13-3-1 查詢資料表的記錄資料-設定中文編碼,在本書因為使用MySQL 4.1版之後的版本,所以預設支援多種字元編碼。當在資料表儲存中文欄位值時,PHP程式在執行SQL查詢前,需要設定使用中文內碼的字元集和校對,如下所示: mysqli_query($link,SET CHARACTER SET big5); mysqli_query($link, “SET collation_connection = b
10、ig5_chinese_ci“);,13-3-1 查詢資料表的記錄資料-取得結果物件的記錄和欄位值,PHP程式在取得結果物件後,就可以呼叫相關函數取出記錄資料或將記錄資料儲存成陣列。筆者準備呼叫mysqli_fetch_assoc()函數將查詢結果的每一筆記錄存入結合陣列,如下所示: while( $row = mysqli_fetch_assoc($result) ) echo $row“stdno“.“-“.$row“name“.“; ,13-3-1 查詢資料表的記錄資料-釋放佔用的記憶體空間,資料表查詢結果的結果物件會佔用伺服器的記憶體空間,當不再需要查詢結果時,在PHP程式請記得自行釋
11、放佔用的記憶體空間,以免浪費伺服器的寶貴資源。 在PHP程式是呼叫mysqli_free_result()函數釋放結果物件佔用的記憶體空間,如下所示: mysqli_free_result($result);,13-3-2 MySQL操作的錯誤處理,PHP的ext/mysqli擴充程式提供MySQL操作的錯誤函數,可以在執行資料庫存取時,取得進一步的錯誤資訊。相關函數的說明,如下表所示:,13-4 取得資料表和欄位資訊,13-4-1 取得欄位數和記錄數 13-4-2 取得欄位資訊,13-4-1 取得欄位數和記錄數,PHP的ext/mysqli擴充程式提供函數可以取得欄位數和記錄數,相關函數的說
12、明,如下表所示:,13-4-2 取得欄位資訊-說明,PHP程式可以呼叫mysqli_fetch_field()函數取得欄位相關資訊的物件,如下所示: while($meta=mysqli_fetch_field($result) echo “ . $meta-name .“;echo “ . $meta-table . “;echo “ . $meta-max_length . “;echo “ . $meta-type .“; ,13-4-2 取得欄位資訊-成員變數,mysqli_fetch_field()函數傳回值是物件,提供成員變數可以取得欄位資訊。常用成員變數說明,如下表所示:,13-
13、5 取得資料表的記錄資料,13-5-1 讀取單筆記錄的索引陣列 13-5-2 移動記錄指標 13-5-3 將記錄存入陣列,13-5-1 讀取單筆記錄的索引陣列,PHP的mysqli_fetch_row()函數可以如同一行一行讀取文字檔案一般,一次一筆記錄的讀取查詢結果物件的記錄資料,如下所示: while ($row = mysqli_fetch_row($result) echo “;for ( $i = 0; $i “ . $row$i . “;echo “; ,13-5-2 移動記錄指標,PHP的查詢結果物件預設擁有內部記錄指標(Internal Row Pointer)指向目前待讀取的
14、記錄位置,我們可以如同存取索引陣列一般,呼叫mysqli_data_seek()函數來更改指標位置,直接讀取指定位置的記錄資料,如下所示: mysqli_data_seek($result, 2); $row = mysqli_fetch_row($result);,13-5-3 將記錄存入陣列-說明,PHP的mysqli_fetch_array()函數不只可以讀取單筆記錄存入索引陣列,還可以將記錄存入以欄位名稱為鍵值的結合陣列。 在mysqli_fetch_array()函數的第2個參數可以指定儲存的陣列類型,如下所示: while ($rows=mysqli_fetch_array($re
15、sult,MYSQLI_NUM) ,13-5-3 將記錄存入陣列-儲存類型,MYSQLI_NUM:儲存成索引陣列,執行結果如同mysqli_fetch_row()函數。記錄使用索引值來取得欄位值,如下所示: echo “$rows0“; MYSQLI_ASSOC:儲存成以欄位名稱為鍵值的結合陣列,執行結果如同mysqli_fetch_assoc()函數。記錄是使用欄位名稱的鍵值存取欄位值,如下所示: echo “.$rows“stdno“.“; MYSQLI_BOTH:儲存成索引和結合陣列,換句話說,記錄可以任意選擇使用索引或欄位名稱的鍵值來取得欄位值。,13-6 使用表格分頁顯示記錄資料-說
16、明,當查詢結果的記錄資料很多時,我們並不希望在同一頁網頁就顯示所有記錄,此時可以使用表格分頁方式顯示記錄資料,提供超鏈結切換顯示指定頁碼、上一頁或下一頁的記錄資料。 在PHP程式是使用超連結的URL參數傳遞目前網頁顯示的頁碼,URL參數Pages是目前頁碼,瀏覽程式的URL網址,如下所示: http:/localhost/Ch13/Ch13-6.php?Pages=2 上述URL參數Pages為目前頁碼2。,13-6 使用表格分頁顯示記錄資料-URL參數取得目前頁碼,在PHP程式開頭就可以取得參數的頁碼和指定每頁顯示的記錄數,如下所示: $records_per_page = 2; / 取得U
17、RL參數的頁數 if (isset($_GET“Pages“)$pages = $_GET“Pages“; else $pages = 1;,13-6 使用表格分頁顯示記錄資料-計算總頁數和指標位置,我們就可以呼叫mysqli_num_fields()取得欄位數和mysqli_num_rows()函數取得記錄數,如下所示: $total_fields=mysqli_num_fields($result); $total_records=mysqli_num_rows($result); 接著計算出記錄資料的總頁數和此頁碼第1筆記錄的指標位置,如下所示: $total_pages = ceil(
18、$total_records/$records_per_page); $offset = ($pages - 1)*$records_per_page; mysqli_data_seek($result, $offset);,13-6 使用表格分頁顯示記錄資料-顯示分頁的記錄資料,$j = 1; while ($rows = mysqli_fetch_array($result, MYSQLI_NUM)and $j “;for ( $i = 0; $i“.$rows$i.“;echo “;$j+; ,13-6 使用表格分頁顯示記錄資料-顯示上一頁和下一頁的超連結,if ( $pages 1 )
19、 / 顯示上一頁echo“上一頁| “; if ( $pages 下一頁 “;,13-6 使用表格分頁顯示記錄資料-顯示頁碼超連結,頁碼超連結是使用for迴圈來顯示,如下所示: for ( $i = 1; $i “.$i.“ “;elseecho $i.“ “;,13-7 物件導向介面的資料庫存取-開啟資料庫連結,PHP的ext/mysqli擴充程式除了可以使用函數方式存取資料庫外(也就是本節之前使用的方法),我們還可以使用物件導向介面來存取資料庫,如下所示: $mysqli = new mysqli(“localhost“,“root“,“123456“); 上述程式碼使用new運算子建立$
20、mysqli物件,這是一個資料庫連結物件,其建構子參數和呼叫mysqli_connect()函數相同。,13-7 物件導向介面的資料庫存取-存取資料庫,在成功建立$mysqli物件後,我們就可以呼叫物件的相關方法來存取資料庫,如下所示: $mysqli-select_db(“school“); $result = $mysqli-query($sql); 程式碼呼叫select_db()方法選擇school資料庫,query()方法執行SQL查詢來取得結果物件$result。呼叫成員方法並不需要指明資料庫連結,因為資料庫連結資訊已經儲存在$mysqli物件之中。,13-7 物件導向介面的資料庫
21、存取-顯示記錄資料,在取得$result物件後,PHP程式取出記錄資料是呼叫$result結果物件的方法和存取成員變數,如下所示: $total_fields = $result-field_count; $total_records = $result-num_rows; while( $row = $result-fetch_assoc() ) echo $row“stdno“.“-“.$row“name“.“; $result-close();,13-7 物件導向介面的資料庫存取-關閉資料庫連結,最後只需呼叫$mysqli物件的close()方法就可以關閉資料庫連結,如下所示: $mysqli-close();,