PHP + MySQL簡易操作教學

前置作業:


流程:
  1. 連線到資料庫
  2. 執行SELECT SQL
  3. 取出一列列的資料
  4. 其他注意事項和小撇步

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';
$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'");
你可能會覺得先把帳號密碼寫在變數裡這件是有點多餘,不過實務面上我們很有可能還會把「帳號資料」和「連線」這兩個區塊分開--通常是做很大的站台的時候。比方說我可能某個頁面同時要跟Google、Yahoo!和FaceBook做連線,那麼我就會分開寫兩個檔:/* 這個檔叫做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 */
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);
看吧,只是連線而已就已經開始讓人頭昏眼花,而且我們根本還沒有開始真正操作什麼呢!所以還是把一些設定(諸如帳號、密碼)通通寫在同一區,這樣子之後要改才比較方便。(註:那些API的實際使用方法應該不是這樣子,我只是隨便舉個例子。但總之通常只會更複雜)

執行SELECT SQL
希望你不會覺得光是連線就亂七八糟的,因為下面才要開始操作...orz
在這邊我們先考慮把資料從資料庫中取出來就好,寫入的方法之後會再介紹。
如果你還記得最簡單的SQL:SELECT id, name FROM student
這就是取出student資料表中的id和name兩個欄位。請注意資料庫的SELECT指令只會「取出資料」而不會「排序」--除非你要求他要排序:SELECT * FROM student
ORDER BY id ASC
其中"ASC"是表示遞增排序(遞減排序則是DESC)

在這邊要注意幾點事情:

  • 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呢....

PHP執行SQL的指令是mysql_query()(注意:當然要先對資料庫連線,再執行mysql_query()才有意義),有時我們會把SQL直接寫在裡面:$res = mysql_query("SELECT * FROM student");
不過如果是像上面有比較長的SQL,我倒是比較建議先另外丟進變數裡:$sql = "SELECT `id`, `name`
FROM `student`
WHERE `id` < 10
ORDER BY `id` DESC";
$res = mysql_query($sql);
也別忘了PHP的字串裡面是可以直接換行的(題外話:如果你有在寫JavaScript的話,請注意JavaScript並不能直接這樣做喔)

有注意到我都把mysql_query()回傳的東西丟給$res變數嗎?那就是我們接下來要操作的東西囉

取出一列列的資料
好,這一個區塊其實才是我寫本文的主要目的....(不過上面講SQL好像花了太多篇幅)
mysql_query()回傳的$res變數是PHP的某種資料結構,沒辦法直接取得所有資料,不過可以「一筆一筆」的取出來(在這裡我是用mysql_fetch_assoc(),你也可以用mysql_fetch_row(),後面會再介紹他們的不同): $res = mysql_query("SELECT * FROM student");
$row1 = mysql_fetch_assoc($res); /*第一列*/
$row2 = mysql_fetch_assoc($res); /*第二列*/
$row3 = mysql_fetch_assoc($res); /*第三列*/
注意我們其實是在執行同一個function,但是每次卻回傳不同的結果喔!當然你應該不會想這麼呆呆的把整張資料表取完,這種時候就得用上迴圈啦。但是面對不知道SQL回傳的結果有幾筆資料的時候,回圈應該要在什麼時候停止呢?
其實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'];
    $sql = "SELECT * FROM message WHERE content = '$txt'";
    // 還記得字串要加上單引號吧..
    不過以這個例子來說,我們又必須小心使用者輸入的東西本身就有單引號。比方說使用者輸入了"我好傷心喔 T_T'",那麼整個SQL丟給MySQL的時候就會變成SELECT * FROM message WHERE content = '我好傷心喔 T_T''然後就發生錯誤啦(因為MySQL看不懂那些引號是怎麼回事)
    這種時候就必須另外用程式把那個單引號解決掉:$txt = str_replace("'", "\\'", $_GET['search']);
    /* 如果你看不懂那個"\\'",就先照做吧....*/
    $sql = "SELECT * FROM message WHERE content = '$txt'";

    通常我只處理單引號,不過你可能也想把其他東西代換掉,就依樣畫葫蘆囉。
  • 承上,如果是用留言的流水號(數字)來查的話,直覺上程式碼應該是:$id = $_GET['id'];
    $sql = "SELECT * FROM message WHERE id = $id";
    可是,如果使用者在表單中,根本不是打數字的話(比方說使用者什麼都沒打),SQL就會變成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']);
    以上兩個方法都可以應付使用者亂打的狀況
善用sprintf()
承上,我們有時會需要比較長的SQL,像是:SELECT * FROM car
WHERE brand = 'BMW'
AND oilCart > 2000
AND price < 700000
如果我們是使用sprintf()的話,就可以用比較容易懂得簡短程式碼來執行(簡潔易懂的程式碼可以幫助自己或他人後續的除錯和更新):$sql = "
SELECT * FROM car
WHERE brand = '%s'
AND oilCart > %d
AND price < %d
";
$sql = sprintf($sql, $_GET['brand'], $_GET['oilCart'], $_GET['price']);
這只是個比較簡單的例子,但如果是遇到像是需要報表、統計這一類需要跨多的資料表的SQL,使用sprintf()的替代方式可以讓你快速的編輯和除錯。

先到此為止吧,我手痠了
......
... read more

久違的台中

不知怎地,各個case在這兩週幾乎都有更新要求
於是最近總沒能成功讓自己好好放鬆
前天經前輩提醒才驚覺台中爵士音樂節已經開始了

是位最近在台中看房地產的前輩
聽他提到台中市的街道狀況和生活習慣
總覺得自己跟台中已經整個脫節了啊
該找時間回家了吧

說到爵士音樂節
去年拿亞軍的那隻可愛大熊學弟好像有說要教我鋼琴
原本還說我今年要參賽的勒

....似乎也不需要動用到「人事已非」來描述
雖然確實是名副其實啦
......
... read more

應該遵照本質嗎?

我從小時候就不喜歡龍應台,大概是因為她總堅持著要別人也接受她所認定的那些「應該」的事物。於是就連她所創立的清華思沙龍(其實我印象中剛創立時的名字是「思想沙龍」,如果我待會打成「廝殺龍」的話好像也很不錯)都不喜歡。
今天在交大看到了清華思沙龍的活動海報,主題是[共築社區夢想藍圖-從清大宵夜街談起],又讓我一整個反感。以下先節錄海報的部分內容:

天橋下的人潮
從湍急的車潮裡穿出
喧鬧的夜市
卻是被漠視的暗巷

清大一直在這裡
那,大學生在哪裡?

主持人:
王俊秀 清大通識中心教授

與談人:
曾光宗 中原大學建築系系主任
陳天佑 中華大學建築系系主任
劉俊秀 交大教授 新竹市長候選人

地點:清華大學 合勤演藝廳

姑且不論劉俊秀是不是來拉票,我看著海報時就一直在嘲笑龍應台長久以來一直想要灌輸社會大眾的本質問題。她好像總以「某某東西不該是某某樣子」之類的論點來引起注意,但是似乎她自己也只在自己在乎的地方實行這些想法而已....
合勤演藝廳-清大內唯一一個觀眾容納量是100~200人的有室內場地,但是由於合勤公司當初是將該廳的設備、燈光、裝潢、聲響設計成表演藝術的展演空間,使得許多想以之作為活動場地的小單位們一直被合勤的管理單位(我忘了是誰了)婉拒。而清華思沙龍也不知道是不是挾著龍應台的氣魄,從成立之初就常常使用該場地...(但我沒有要說合勤演藝廳不應該用做演講場地。)
回到活動的宣傳文字。清夜是不是跟大學生有關係,這我不予置評,不過海報上把官方網站打成nthuthinkers@blogspot.com,說實話讓我啼笑皆非,不像是一個自我要求的人創辦的自我要求的團體該發生的事件。
......
... read more

碩士論文主題

主題是性開放,但切入點和作品標題還沒想好。


當然是為了自己才選這個題目的。當初要不是有學弟把我拉去聚會,可能我現在還呆呆的異男忘,乖乖的寫程式吧(是說依我打混的個性再回去弄程式的話很可能連混畢業都有困難)。但說實話,進圈子的一年三個月來其實觀念沒有改變太多,還是一樣贊成開放式關係,還是一樣覺得戴套肛交比接吻安全,還是一樣覺得陳冠希沒有錯,還是想要靠身體賺錢(但不能在台灣)....


他們說你醜,這樣才會讓他們覺得自己很帥。
--海綿寶寶
我似乎在每個領域中,經歷過初學階段之後,都有著這樣目中無人的高傲,但其實自己並未有什麼真能經的起考驗的能力/事蹟。


當我覺得我什麼都知道時,他們給了我學士學位。
當我發現其實我什麼都不知道時,他們給了我碩士學位。
當我認清別人也什麼都不知道時時,我已經拿到博士學位。
但我們還是得做點什麼才能混口飯吃,或說,過著自己想要的生活。就像人類的所有認知/邏輯/思想的最基礎其實都是主觀而抽象的一樣,我(們)並不真的知道自己想要的東西,而是在生活經驗中去嘗試歸納,然後把自己明知也可能錯誤的歸納結果,當作唯一的圭臬來信仰。據說我曾經最喜歡的數學也是一樣:
歷來數學家總是擁有許許多多的技巧,以消解或避免邏輯矛盾所引起的問題,而使數學免於產生危機。


扯遠了。總之今天跟董老師聊過之後又再次體認到自己還有很多要努力的事情,長久以來都把這件事情看的太過簡單了,除了孟子那句「說大人則藐之」害人不淺之外,也許真的是太常被讚美讓沒經歷過挫折的我太過高傲了吧。

要讓一個選手墮落很簡單啊,只要稱讚他就行了!
--野村克也
不能在高傲下去了,還有很多事情要請教很多貴人的呢。


話說回來,作品的要求只有「與即時多媒體系統裝置相結合」,並沒有提到音樂性要如何....


目前想做的清單:

  • 開自己的整場音樂會(要先把論文要的那首解決)
  • 2009的日文檢定二級,2010的日本留學測驗
  • 大專盃健美比賽
  • 考軍樂預士,入伍前學Sax
  • 把屌練到19cm長(目前是16.5cm)
  • 跟阿賢打聽去日本拍G片

......
... read more

交大音樂所開放外系修習[音樂理論]

由於目前開放了[音樂學分學程],所以[音樂理論]課程確定可以開放給外系所修習。

課程內容大致沒有更動,請參考我在兩年半前回覆的同一討論串:

音樂所有個規定
除了科技組除外,入學考試的樂理如果不到70分,這堂音樂理論就會變成必修
然後,以今年為例,約有九成的人沒有到70分
簡言之,這門絕對不是給"完全沒有樂理基礎"的人上的課

之所以在選課系統上被加註「大學部課程」,因為這是屬於「補修課程」
可參考:http://www.imu.nctu.edu.tw/tw/commence.php?year=96 的"畢業學分"

我這學期去旁聽的第一節時
老師說:「每次都會有外系的以為這堂是基礎課程。」
老師講的蠻好的,跟音樂所的學長姐聊時
有不少人表示「跟大學時學的方式很不一樣」

雖然我期中之後就沒有再去旁聽了
可是我覺得如果你有一些樂理的基礎
比方說知道羅馬級數的和聲紀錄方式(含附屬和弦、和聲外音紀錄方式)
看五線譜不會像我還要一格格去數....
而且每週在課外有另外花兩個小時,那還蠻值得聽聽看(一)的

先聲名一下,我不是音樂所的學生,這學期也只是旁聽而已
所以有些地方可能不會寫的那麼中肯

這門課目前由兩位老師授課
其中洪老師講調性理論;吳老師講風格寫作
兩個老師的上課時間大約是二比一

調性理論的部分,課本是採用Harmony & Voice Leading 第三版,原文(英文)
這本書非常的貴,不到七百頁的黑白印刷(連灰階都沒有)
精裝本在柏克來的價格居然超過5000(而且不含CD)
(所以大家就不會在柏克來買..cc)
每週(只要洪老師會來)都會有一位同學負責報告其中一章
通常是從第六章(I-V-I進行)開始

前面幾章看似蠻容易的
但是這本課本會採用Voice Leading(可翻做"聲部進行")
從各個聲部的旋律進行去討論和聲的可能性
所以課本本身和習題就有一定的份量(不算"難",大概有看懂就ok)

課本報告完之後,洪老師會帶著大家分析曲子
這學期著重的部分是調性的建立,所以我們會需要去找譜例中的終止式
然後把曲子拆開來看,仔細看每個小節在幹麻

洪老師的拆法是由外而內的
以調性音樂來說,最基本的模式就是 主調區->對照調區->主調區
拆出了第一部份的主調區後,就會開始越來越細的拆解
通常第二個成分是拆成樂句(但不盡然)
然後再去分析這個樂句裡面用了什麼樣的技巧(最常見的是"模進")
當老師拆的越細,就越容易有「這作曲家真是變態」的感覺

兩個老師都會發非常多的譜例
大多數都是耳熟能詳的名家的曲子
不過由於音樂所的政策,非修課生(就是旁聽的啦)
所上不支援其講義的影印
所以我還蠻常沒拿到講義的..QQ
(只好事後找學姊搭訕..啊不是,是央求借印)

吳老師上的主題是風格寫作
會用一本名叫Classic Music的課本
副標是Expression, Form, and Style,聽說已經絕版了

其實吳老師用課本的時間不多,大多是另外發講義
講義中完整曲子的比例偏少,大部分是文章或是一些音型的範例
這學期有講到很多種風格,比方說土耳其進行曲的土耳其風格(廢話~"~)
然後會試著看管旋樂總譜,分析哪幾個小節是用怎樣的風格
並且跟曲式稍做結合(其實好像並不是「曲式」這個專有名詞)
分析這一段跟前一段有什麼異同

文章的部份則有點進入心理學的層面
會討論到怎麼樣的曲子容易被理解和記住
是看荀白克的教學筆記

從這學期中開始就是講各種擴展方式
包括音型的擴展(最常見的是重複跟模進,當然還有逆行、反向....)
樂句的延長、段落的收尾(很多樂段的收尾甚至比其主題還長)
過門、轉調(不是移調唷)....等等(我後來就沒去聽了..愧)

作業的部份
洪老幾乎師每週都會出一題當週講的章節後面的習題
通常是四聲部寫作(高音、低音題都有)
可能會有要分析曲子,而且要用"寫"的(說實話,很難)
因為她蠻注重「你要分析的讓別人看的懂」這個能力的

吳老師的作業則是教什麼就做什麼
比方說第一週交Period和Sentence的差異
那作業就是把同樣的動機,用period和sentence方式分別擴展
從期中開始就算是開始寫曲子了
一開始只是要你用do, re, fa, mi四個音寫一個樂句
下一週就要你擴展,再下一週就變奏成別的風格
然後是收尾、收尾的擴展.....
然後寫出下一個對照區.....到期末就成了一首曲子

上課時很可能把大家的作業都輪流聽過
所以可以很明顯的感覺到大家的...."活力"
至於怎麼"聽"....大多數人是彈鋼琴
也可以凹鋼琴組的幫你視奏(如果你坳的到..XD)
也可以輸入成MIDI然後再過帶成CD

我旁聽的那學期,期末作業是變奏曲
印象中下學期的是奏鳴曲式


不過現在制度不太一樣了,雖然選課系統上有分班,但仍是兩位老師輪流上
分班的部分則會在第一周舉辦分班考試:
第一堂課(9.14.星期一)4:30-6:30pm將舉行測驗考試,依據測驗結果,將會分成
  1. 免修 (非音樂所的應該不會有這個狀況...)
  2. A組:只需修98-1學期
  3. B組:需修98-1及98-2的課程
未參加考試的同學一律為B組


考試的部分可以參考去年的考題:
http://www.imu.nctu.edu.tw/download/2009/MusicTheoryTest97.pdf
剛剛問了一下學弟妹,三個小時是絕對寫不完的
而且這並不是想要寫快點就真能寫的快的題目

再次強調,本課程不是給沒有基礎的人修的
而且作業量即使是音樂系本科的人也不敢小覷
想找通識課的請參考李子聲老師3AB的音樂理論導論







以上都是真的,但也只是嚇人的
以下簡述一些個人意見。

我還在唸清大資工的時候就來聽課了,說實話如果是那時看到分班考試題目的話,應該也是一題都不會寫吧。那時只知道級數和終止式,連數字低音都不知道,更遑論什麼Neapolitan Chord、附屬和絃、三段體、Period/Sentence...

不過憑著對音樂的喜好就硬著頭皮繼續聽課了。
一開始關於級數、數字低音的部分其實就只是了解定義就好了,上課前多google一下和看一下WikiPedia都很方便,課堂間問一下學長姊一些關鍵性的問題也很快可以釐清。

不用把音樂系畢業的人的樂理能力想的太高,很多時候非本科系的對於樂理死板的部分反應反而快,有修過李子聲老師的課的應該偶爾會聽到他感嘆類似的事情。但相對的,非本科系-特別是理工科-就變得容易不小心太過堅持/鑽研死板的樂理,我自己考上音樂所,唸到碩三了也常會有類似的感覺。

而單就「學院派的樂理」這個角度來說,我非常推薦這門課。修過之後,你就大概可窺知學院派的美學觀是怎麼回事。樂理只是大家「溝通」的基礎、「能聽」的保障,好好去享受音樂中的每一條節奏和旋律,還有彼此交織起來的感覺才是重點。(知道「複音音樂」是什麼的應該能聽懂我在說什麼)

而就實用性來說,你也會更清楚西方古典樂理不是唯一的圭臬。頑皮豹、馬力歐、小叮噹、龍貓的主題曲帶給我們的感覺,絕對不是用樂理解析之後就可以複製的。我曾經小看並試著複製帕爾海貝的「卡農」,但嘗試之後才發現他的厲害之處。

有膽子挑戰的,就請全力以赴吧。
......
... read more