PHP + MySQL簡易操作教學
前置作業:
- 先灌好PHP和MySQL
- 玩玩phpMyAdmin
- 確認你看得懂最基本的SQL語法
流程:
PHP的MySQL相關function操作其實不難,但是新手們一開始在使用時卻會很不習慣,以下僅以在下的認知做出簡易示範(應該不是最好的方法,事實上我自己目前已經不是這樣做,但我相信本文應該會是很好理解的流程)
- 連線到資料庫
連線到資料庫通常都很好解決(如果MySQL Server有設定好的話):
mysql_connect('localhost', 'username', 'password');
mysql_select_db('myDB');
這段程式碼通常會寫在一個給所有頁面引入的檔,假設上面兩行被我們存檔為"database.php",那麼遇到需要對資料庫連線的時候只要PHP呼叫:require_once 'database.php';
就可以了。這個方法也可以應用在其他想要在每個頁面上做的事情(像是紀錄IP、檢查是否已登入之類的)。不過只是這樣子有時會有點風險,比方說如果資料庫不是自己設定的,但我們又必須指定編碼(目前的趨勢是使用UTF-8)的話,就得加上一句"SET NAMES 'UTF8'"的SQL,以防止一些亂碼的狀況發生,當然這個前提是你的網頁也是用UTF-8編碼。連線的設定可能就會變成:
$db_server = 'db.mycom.com';
你可能會覺得先把帳號密碼寫在變數裡這件是有點多餘,不過實務面上我們很有可能還會把「帳號資料」和「連線」這兩個區塊分開--通常是做很大的站台的時候。比方說我可能某個頁面同時要跟Google、Yahoo!和FaceBook做連線,那麼我就會分開寫兩個檔:
$db_user = 'kong0107';
$db_password = '********';
$db_name = 'test';
mysql_connect($db_server, $db_user, $db_password);
mysql_select_db($db_name);
mysql_query("SET NAMES 'UTF8'");/* 這個檔叫做config.php */
$db_server = 'db.mycom.com';
$db_user = 'kong0107';
$db_password = '********';
$db_name = 'test';
$google_user = 'kong0107';
$google_password = 'hahaha';
$yahoo_user = 'kong_crazykid';
$yahoo_password = 'oh my god';
$fb_user = 'kong0107@gmail.com';
$fb_password = 'this is longer';/* 這個檔叫做service_connection.php */
看吧,只是連線而已就已經開始讓人頭昏眼花,而且我們根本還沒有開始真正操作什麼呢!所以還是把一些設定(諸如帳號、密碼)通通寫在同一區,這樣子之後要改才比較方便。(註:那些API的實際使用方法應該不是這樣子,我只是隨便舉個例子。但總之通常只會更複雜)
require 'config.php'; /*就會把上面那個檔案叫進來*/
mysql_connect($db_server, $db_user, $db_password);
mysql_select_db($db_name);
mysql_query("SET NAMES 'UTF8'");
require_once 'google_api.php'; /*把google的API(最重要的是連線function)叫進來*/
$google = new GoogleAPI();
$google->connect($google_user, $google_password);
require_once 'yahoo_api.php';
$yahoo = new yahooAPI();
$yahoo->connect($yahoo_user, $yahoo_password);
require_once 'facebook_api.php';
$fb = new facebookAPI();
$fb->connect($fb_user, $fb_password);- 執行SELECT SQL
- 希望你不會覺得光是連線就亂七八糟的,因為下面才要開始操作...orz
在這邊我們先考慮把資料從資料庫中取出來就好,寫入的方法之後會再介紹。
如果你還記得最簡單的SQL:SELECT id, name FROM student
這就是取出student資料表中的id和name兩個欄位。請注意資料庫的SELECT指令只會「取出資料」而不會「排序」--除非你要求他要排序:SELECT * FROM student
其中"ASC"是表示遞增排序(遞減排序則是DESC)
ORDER BY id ASC
在這邊要注意幾點事情:
- SQL指令可以換行,所以我建議你在寫比較長的指令時,擅用換行來讓指令比較好理解
- SQL的關鍵字不限大小寫,所以你也可以寫成"select * from student"。但是我個人覺得把關鍵字都大寫比較容易懂
- "select *"的星號是特殊用法,意思是「取得所有欄位」。通常我會建議這麼做,因為你不一定知道待會可能會想用到哪些欄位
- 通常資料庫名稱、資料表名稱、欄位名稱是不需要用引號框起來的,不過你可以為了區別他們和關鍵字而特別這麼做。但是要注意的是在MySQL中,把這類名稱框起來的引號並不是單引號或雙引號,而是鍵盤上左上角Esc鍵下面的那個「`」(請小心不要打成全型字),像是:
SELECT `id`, `name`
FROM `student`
WHERE `id` < 10
ORDER BY `id` DESC - 如果有字串的話,一定要用單引號(不能用雙引號)。舉例來說:
SELECT * FROM student WHERE name = '高睿甫'
如果字串之中有單引號的話,就要用跳脫字元「\」,像是如果要取出留言板中的特定留言:SELECT *
FROM message
WHERE content = '野村克也說\'要讓一個選手墮落很簡單啊,只要稱讚他就行了!\'他說的真是太忠肯了'
PHP執行SQL的指令是mysql_query()(注意:當然要先對資料庫連線,再執行mysql_query()才有意義),有時我們會把SQL直接寫在裡面:
$res = mysql_query("SELECT * FROM student");
不過如果是像上面有比較長的SQL,我倒是比較建議先另外丟進變數裡:$sql = "SELECT `id`, `name`
也別忘了PHP的字串裡面是可以直接換行的(題外話:如果你有在寫JavaScript的話,請注意JavaScript並不能直接這樣做喔)
FROM `student`
WHERE `id` < 10
ORDER BY `id` DESC";
$res = mysql_query($sql);有注意到我都把mysql_query()回傳的東西丟給$res變數嗎?那就是我們接下來要操作的東西囉
- 取出一列列的資料
- 好,這一個區塊其實才是我寫本文的主要目的....(不過上面講SQL好像花了太多篇幅)
mysql_query()回傳的$res變數是PHP的某種資料結構,沒辦法直接取得所有資料,不過可以「一筆一筆」的取出來(在這裡我是用mysql_fetch_assoc(),你也可以用mysql_fetch_row(),後面會再介紹他們的不同):$res = mysql_query("SELECT * FROM student");
注意我們其實是在執行同一個function,但是每次卻回傳不同的結果喔!當然你應該不會想這麼呆呆的把整張資料表取完,這種時候就得用上迴圈啦。但是面對不知道SQL回傳的結果有幾筆資料的時候,回圈應該要在什麼時候停止呢?
$row1 = mysql_fetch_assoc($res); /*第一列*/
$row2 = mysql_fetch_assoc($res); /*第二列*/
$row3 = mysql_fetch_assoc($res); /*第三列*/
其實mysql_fetch_assoc()(和mysql_fetch_row())都會在「已經沒有資料」的時候回傳false,所以我們只要把取出來的東西丟給while判斷就好啦:$res = mysql_query('SELECT * FROM student');
while($row = mysql_fetch_assoc($res)) {
/* 這裡就看你想對這一筆資料幹嘛*/
echo $row['id']; /*像這樣就可以印出該學生的學號*/
}
流程大概都清楚了,我們就來試試用HTML的表格來顯示出所有學生的學號和姓名吧:$res = mysql_query('SELECT `id`, `name` FROM `student`');
像是這樣,不過輸出的部份我自己比較喜歡另一個方式:
echo '<table>';
while($student = mysql_fetch_assoc($res)) {
echo '<tr>';
echo '<td>';
echo $student['id'];
echo '</td>';
echo '<td>';
echo $student['name'];
echo '</td>';
echo '</tr>';
}
echo '</table>';<table>
就是這樣囉,或是看你想怎麼顯示都可以。
<?php
while($student = mysql_fetch_assoc($res)) {
?>
<tr>
<td><?=$student['id']?></td>
<td><?=$student['name']?></td>
</tr>
<?php
}
?>
<table> - 其他注意事項和小撇步
-
- 如果你只想取得一筆資料(比方說想用學號來查名字),那就不需要用while回圈了,比方說:
$id = 9646515;
$res = mysql_query("SELECT * FROM student WHERE id = $id");
$kong = mysql_fetch_assoc($res);
$name = $kong['name'];
echo "學號$id 的學生,他的名字是$name"; - mysql_fetch_assoc()指令只是我自己慣用,如果資料表是你自己設計的,也可以使用mysql_fetch_row()。差別在於回傳回來的array結構:
$res = mysql_query("SELECT id FROM student");
$row1 = mysql_fetch_assoc($res);
echo $row1['id'];
$row2 = mysql_fetch_row($res);
echo $row2[0];
$row3 = mysql_fetch_array($res);
echo $row3['id'];
echo $row3[0];
mysql_fetch_assoc()的好處是你不用記得欄位順序,但缺點是你必須記得欄位名稱;mysql_fetch_row()則相反。當然你也可以用mysql_fetch_array(),這樣就兩種方式都可以取得想要的資料。
小提醒:上面的例子中,請注意$row1、$row2、$row3是會取得「不同筆」的資料喔。 - 實務面上我們常常需要藉由使用者表單來湊出SQL指令,比方說前面舉過的搜尋留言板:
$txt = $_GET['search'];
不過以這個例子來說,我們又必須小心使用者輸入的東西本身就有單引號。比方說使用者輸入了"我好傷心喔 T_T'",那麼整個SQL丟給MySQL的時候就會變成
$sql = "SELECT * FROM message WHERE content = '$txt'";
// 還記得字串要加上單引號吧..SELECT * FROM message WHERE content = '我好傷心喔 T_T''
然後就發生錯誤啦(因為MySQL看不懂那些引號是怎麼回事)
這種時候就必須另外用程式把那個單引號解決掉:$txt = str_replace("'", "\\'", $_GET['search']);
/* 如果你看不懂那個"\\'",就先照做吧....*/
$sql = "SELECT * FROM message WHERE content = '$txt'";
通常我只處理單引號,不過你可能也想把其他東西代換掉,就依樣畫葫蘆囉。 - 承上,如果是用留言的流水號(數字)來查的話,直覺上程式碼應該是:
$id = $_GET['id'];
可是,如果使用者在表單中,根本不是打數字的話(比方說使用者什麼都沒打),SQL就會變成
$sql = "SELECT * FROM message WHERE id = $id";SELECT * FROM message WHERE id =
於是就產生錯誤了(因為等號後面不是數字)。
要解決這個狀況有兩個方法,一個是無論該欄位是不是數字都加上引號:$id = str_replace("'", "\\'", $_GET['id']);
$sql = "SELECT * FROM message WHERE id = '$id'";
另一個就是使用sprintf()函數,這也是我比較偏好的方法:$sql = "SELECT * FROM message WHERE id = %d";
以上兩個方法都可以應付使用者亂打的狀況
$sql = sprintf($sql, $_GET['id']);
- 如果你只想取得一筆資料(比方說想用學號來查名字),那就不需要用while回圈了,比方說:
- 善用sprintf()
- 承上,我們有時會需要比較長的SQL,像是:
SELECT * FROM car
如果我們是使用sprintf()的話,就可以用比較容易懂得簡短程式碼來執行(簡潔易懂的程式碼可以幫助自己或他人後續的除錯和更新):
WHERE brand = 'BMW'
AND oilCart > 2000
AND price < 700000$sql = "
這只是個比較簡單的例子,但如果是遇到像是需要報表、統計這一類需要跨多的資料表的SQL,使用sprintf()的替代方式可以讓你快速的編輯和除錯。
SELECT * FROM car
WHERE brand = '%s'
AND oilCart > %d
AND price < %d
";
$sql = sprintf($sql, $_GET['brand'], $_GET['oilCart'], $_GET['price']);
先到此為止吧,我手痠了......
... read more