[SQL與PHP] PHP教學


所需閱讀權限 1

[SQL與PHP] PHP教學

課1:PHP簡介與程式開發的工具。
摘要:  在這個課程中針對PHP作簡單的介紹,指導學員安裝開發PHP時所使用的工具,以及參考的文件。最後,教導學員使用EditPlus,來撰寫PHP,並將PHP程式上傳至網站。
PHP簡介 :
一、PHP的由來:
在古早古早的時候,也就是1994年。當時有個叫Rasmus Lerdorf的人,他用Perl寫了一些後端的程式,記錄有哪些人看過他的線上履歷表。慢慢地,一些網友對他所寫的程式碼產生興趣。於是,Rasmus Lerdorf就整理這些程式碼,包裝成一個叫作 ”Personal Home Page”的工具。基於個人的興趣,Rasmus Lerdorf又寫了一個腳本語言的核心引擎。然後,又加上了能處理HTML表單輸入的工具,稱作 “Form Interpreter”簡稱FI。在1995年完成的這個版本,當時稱作 “PHP FI”,也有人稱之為 ”PHP2”。

PHP/FI開發出來之後,受到網站開發者的極大的回響,使用PHP/FI來開發網站程式的人越來越多。在1997年中的時候,PHP從Rasmus Lerdorf個人維護的開發專案,轉變成一個重要的網站開發技術。PHP的開發與維護也轉由一個由Rasmus Lerdorf本人和Andi Gutmans、Zeev Suraski、Stig Bakken、Shane Cavaveo、以及Jim Winstead等人所組成的團隊來負責。在1998年6月的時候,Zeev Suraski和Andi Gutmans改寫了PHP語言的解析器,並公佈這新的版本,稱之為PHP3。

到目前為止,PHP已經變成Apache Software Foundation的一個專案計劃。穩定的版本為PHP 4.3.0


二、PHP是什麼東東:

PHP是開放源碼的通用腳本語言,特別適合用來開發網站程式,可以內嵌在HTML碼。PHP程式的原始碼是純文字,所以可以用任何可處理純文字檔的文字編輯器,如:記事本、vi、emac等,來撰寫PHP程式。


PHP程式開發的工具:
一、程式開發的工具

   1. 文字編輯器:用來撰寫程式碼。在這個課程中,我們使用EditPlus。
   2. 程式語言的參考文件:我們使用PHP的線上說明。
   3. 程式庫:別人開發出來的程式庫,可以簡化撰寫程式的工作。

二、EditPlus的下載及安裝

   1. 下載並安裝EditPlushttp://www.editplus.com/download.html
   2. 下載PHP的語法檔。ftp://ftp.editplus.com/files/phpcore412.zip
   3. 將下載完畢PHP的語法檔,解壓縮到EditPlus的安裝目錄底下。


三、EditPlus的PHP環境設定

   1. 啟動EditPlus。
   2. 執行功能表的Tools | Preferences,開啟Preferences的對話方塊。
   3. 設定PHP的語法檔:在Preferences對話方塊,點選左邊的FileseSettings Syntax。按Add按鈕,參考下圖,設定各欄位,設定完畢後,按Apply按鈕:

4.取消儲存時產生備份檔的設定:在Preferences對話方塊,點選左邊的Files,參考下圖,設定各欄位,設定完畢後,按OK按鈕:

5.產生PHP的樣本檔:執行功能表的File | New | Others,然後Select File Type選PHP,按OK按鈕。在EditPlus的文件編輯面版中輸入以下的文字,然後將檔案存在EditPlus的安裝目錄,檔名為 template.php。

<?php
^!
?>

6.設定PHP的樣本檔:執行功能表的File | New | Configure Templates,按Add按鈕,參考下圖,設定各欄位,設定完畢後,按OK按鈕:

使用EditPlus來開發 PHP程式:

   1. 在C磁碟機底下產生一個資料夾:C:\php。
   2. 啟動EditPlus。
   3. 執行功能表的 File | New | PHP
   4. 輸入以下的程式碼:

<?php
echo date("Y-m-d");
?>


   5. 存檔,檔名:C:\php\101_01.php。
   6. 使用EditPlus來上傳檔案:執行功能表的 File | FTP | FTP Upload。在Upload對話方塊中,按Setting按鈕,開啟FTP Settings的對話方塊。按Add按鈕,參考下圖,設定遠端主機的帳號、密碼、以及上傳的目錄。設定完畢後,按OK按鈕:
      回到Upload對話方塊後,按Upload按鈕。

7.啟動瀏覽器,輸入網址。如:http://fox.igt.com.tw/~lib13/101_01.php

PHP教學 第二回


上回說到PHP的簡單資訊,今次會教大家PHP程式設計基礎入門。
摘要:  在這個課程中簡單介紹PHP程式設計的基礎。
PHP程式語言基本注意事項:
一、Web Server 如何分辨PHP的檔案與HTML檔案:

    要讓Web Server 能執行文件中的PHP程式碼,文件的副檔名,必須是 .php或 .phtml。如果要使用其他檔名,請參考各Web Server的設定。

二、程式碼區域的開始與結束:

    PHP的優點之一,就是可以和HTML碼混合在一起。但是為了讓Web Server能區分出 PHP的程式碼與HTML碼,所以,在每段PHP程式碼的開頭必須加入<?php,在結尾的地方加 ?>。

三、命令句:

    在PHP中,每一個命令句必須以分號;作結束。

四、變數:

    變數是用來儲存程式執行時的暫存資料。在PHP中,變數之前必需加 $ 的符號。另外,PHP的大小寫是有差別的,所以在使用變數時,須注意大小寫是否一致。PHP是屬於 weakly typed的程式語言,對資料型態的規範較鬆,可以不先經宣告變數,就可以直接使用。好處是,程式寫起來比較方便,壞處是,程式出問題時,比較難找出錯誤。

五、程式註解:

    PHP的程式註解符號,與C++,Java一樣,單行的註解使用 //。// 之後同一行所有的文字,在執行時都會被乎略。若要使用多行的註解時,可以使用 /* 和 */的註解符號。自/*開始到*/之間的所有文字,在執行時都會被乎略。


PHP 的輸出:
一、echo 與 print的使用:

    要列印輸出程式的運算結果時,可以使用echo(PHP的語言結構)或 print(函數)。以下以實例分別示範echo和 print的用法。理論上,使用echo會比print略有效率。
二、echo.php:

使用 echo 輸出: <br>

這裡的文字, Web Server不會作任何處理, 直接輸出<hr>
<?
echo("有括弧的<br>");

echo "沒括弧的<hr>";

$today = date("Y年m月d日"); //把呼叫 date函數所得的值, 設定給 $today變數

echo <<<END
這鍋使用 "here document" 語法來輸出"一狗票"文字, <br>
所有用 here document的方式輸出的文字, <br>
都可以完整的保留下來, <br>
變數在這裡"也"可以被替換, <br>
今天: $today<br>
END;
?>
<hr>上面的文字, 是執行過PHP程式所得的輸出結果<br>
這裡的文字, Web Server不會作任何處理, 直接輸出<hr>
以下輸出的結果是 <?php echo $today ?> 的簡寫方式<br>
<?=$today?>
<hr>


三、print.php:

使用 print 輸出: <br>

這裡的文字, Web Server不會作任何處理, 直接輸出<hr>
<?
print("有括弧的<br>");

print "沒括弧的<hr>";

$today = date("Y年m月d日"); //把呼叫 date函數所得的值, 設定給 $today變數

print <<<END
這鍋使用 "here document" 語法來輸出"一狗票"文字, <br>
所有用 here document的方式輸出的文字, <br>
都可以完整的保留下來, <br>
變數在這裡"也"可以被替換, <br>
今天: $today<br>
END;
?>
<hr>上面的文字, 是執行過PHP程式所得的輸出結果<br>
這裡的文字, Web Server不會作任何處理, 直接輸出<hr>
以下輸出的結果是 <?php print $today ?> 的簡寫方式<br>
<?=$today?>
<hr>


Web的表單處理:
以上我們學到的是,使用PHP來輸出程式運算的結果。接下來我們要學習如何,處理表單所傳遞過來的資料。
一、102_form1.php:

<html>
<FORM METHOD=POST ACTION="">
帳號: <INPUT TYPE="text" NAME="account"><BR>
密碼: <INPUT TYPE="text" NAME="password"><BR>
<INPUT TYPE="submit" value="送出">
</FORM>
<HR>

你輸入的帳號: <?=$_POST[account]?> <BR>
你輸入的姓名: <?=$_POST[password]?>

<HR>

</html>

程式說明:
在102_form1.php中,我們使用簡寫的方式,把PHP碼內嵌到HTML碼中。
表單所傳遞過來的資料,會按照HTML表單物件的名稱,成為PHP可以讀取的變數。如 :<INPUT TYPE="text" NAME="account"> 這個文字欄位,NAME屬性的值是account。所以,要讀取這個欄位的值,只要使用$account這個變數即可。
練習題:

   1. 把 102_form1.php存成 102_form2.php,中的 Form Method=Post 改為 Form Method=Get,並觀察網址列的變化。
   2. 在瀏覽器中輸入http://www.igt.com.tw/~lib13/102 ... bcpassword=567,並觀察網頁輸出的結果。
   3. 在瀏覽器中輸入http://www.igt.com.tw/~lib13/102 ... fgpassword=987,並觀察網頁輸出的結果。

二、使用 if-elseif-else的結構:
1. 102_login.html

<html>
<FORM METHOD=POST ACTION="102_auth.php">
帳號: <INPUT TYPE="text" NAME="account"><BR>
密碼: <INPUT TYPE="text" NAME="password"><BR>
<INPUT TYPE="submit" value="送出">
</FORM>
</html>

2. 102_auth.php

<?php
if($account == "lord" & $password == "pass"){
       echo "歡迎 $_POST[account], 你的密碼是 $_POST[password]";
}elseif($_POST[account] == "god" & $_POST[password] == "dog"){
       $y = date("Y") - 1911;
       $m = date("m");
       $d = date("d");
       echo "歡迎 $_POST[account], 今天是民國".$y."年".$m."月".$d."日";
}else{
       echo "登入失敗:<hr> 輸入的資料:<br>帳號: $_POST[account] <br>密碼: $_POST[password]";
}
?>

三、簡單的數學運算:
1. 102_rect.html

<html>
<FORM METHOD=POST ACTION="102_rect.php">
高: <INPUT TYPE="text" NAME="h"><BR>
寬: <INPUT TYPE="text" NAME="w"><BR>
<INPUT TYPE="submit" value="送出">
</FORM>
</html>

2. 102_rect.php

<?php
$area = $_POST[w] * $_POST[h];
$para = 2 * ($_POST[w] + $_POST[h]);

echo <<<END
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" c>
</head>

<body>
<table width="61" border="0">
<tr>
<td width="36">高</td>
<td width="15">$_POST[h]</td>
</tr>
<tr>
<td>寬</td>
<td>$_POST[w]</td>
</tr>
<tr>
<td>面積</td>
<td>$area</td>
</tr>
<tr>
<td>周長</td>
<td>$para</td>
</tr>
</table>
</body>
</html>
END;
?>
四、簡單的比較運算:

1. 102_comp.html

<html>
<FORM METHOD=POST ACTION="102_comp.php">
n1: <INPUT TYPE="text" NAME="n1"><BR>
n2: <INPUT TYPE="text" NAME="n2"><BR>
<INPUT TYPE="submit" value="送出">
</FORM>
</html>

2. 102_comp.php


<?php
if($_POST[n1] > $_POST[n2]){
       $result = "$_POST[n1] 大於 $_POST[n2]";
}elseif($_POST[n1] < $_POST[n2]){
       $result = "$_POST[n1] 小於 $_POST[n2]";
}else{
       $result = "$_POST[n1] 等於 $_POST[n2]";
}

echo <<<END
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" c>
</head>

<body>
<table border="0">
<tr>
<td width="36">n1</td>
<td width="15">$_POST[n1]</td>
</tr>
<tr>
<td>n2</td>
<td>$_POST[n2]</td>
</tr>
<tr>
<td>結果</td>
<td>$result</td>
</tr>
</table>
</body>
</html>
END;
?>

小測驗:
1. 寫一個PHP程式, 讓網友輸入, 圓的半徑, 然後輸出周長及面積
Solution [post]
<?php
if(isset($_POST[submit])){
       $area = pi() * $_POST[radius] * $_POST[radius];
       $cir = 2 * pi() * $_POST[radius];
       $output = "<hr>解答:<br>周長: $cir<br>";
       $output .= "面積: $area<hr>";
}else{
       $output = "";
}
echo <<<EOF
<FORM METHOD=POST ACTION="">
"半徑": <INPUT TYPE="text" NAME="radius">
<INPUT TYPE="submit" name="submit">
</FORM>
$output
EOF;
?>
Click here to run this progamme[/post]
2. 寫一個PHP程式, 讓網友輸入, 三角形的三個邊, 然後輸出三角型的周長, 須判斷此三個值是否可構成三角形 Solution [post]
<?php
if(isset($_POST[submit])){
       $s1 = $_POST[s1];
       $s2 = $_POST[s2];
       $s3 = $_POST[s3];
       $output = "<hr> 邊1: $s1, 邊2: $s2, 邊3: $s3<br>";
       if($s1 + $s2 > $s3 & $s1 + $s3 > $s2 && $s2 + $s3 > $s1){
              $output .= "<hr>週長: ".($s1 + $s2 + $s3)."<br>";
       }else{
              $output .= "<hr>錯誤: 任兩邊和必需大於第三邊<br>";
       }
}else{
       $output = "";
}
echo <<<EOF
<FORM METHOD=POST ACTION="">
邊1: <INPUT TYPE="text" NAME="s1"><br>
邊2: <INPUT TYPE="text" NAME="s2"><br>
邊3: <INPUT TYPE="text" NAME="s3"><br>
<INPUT TYPE="submit" name="submit">
</FORM>
$output
EOF;
?>     
Click here to run this programme[/post]

PHP教學 第三回


呵呵,上一課學得怎樣,做到兩個小測試的要求嗎?這回要教大家程控結構。
摘要:  程式控制結構,分為條件式與迴圈兩種,提供程式設計決定判斷的基本能力。這個課程,探討PHP的程式控制結構,藉由實例演練,使學員能了解PHP程控結構的語法與使用方式。
條件式
一、if 命令句
實例一:
程式碼:103_01.php

<?php
echo "if 範例: <br/>";
if($fruit == "apple"){
       echo '<hr size=1>只有當 $fruit 等於是 apple 時, 這一行會才秀出來<hr size=1>';
}
echo '<p>這一行永遠會秀出來: $fruit = '.$fruit."</p>";
?>


實例二:
程式碼:103_02.php

<?php
echo "if-else 範例: <br/>";
if($fruit == "apple"){
       echo '<hr size=1>只有當 $fruit 等於是 apple 時, 這一行會才秀出來<hr size=1>';
}else{
       echo '<hr size=1>只要 $fruit 不是 apple 時, 就會秀出這行<hr size=1>';
}
echo '<p>我們的水果: $fruit = '.$fruit."</p>";
?>
實例三:
程式碼:103_03.php

<?php
echo "if-elseif-else 範例: <br/>";
if($fruit == "apple"){
       echo '<hr size=1>只有當 $fruit 等於是 apple 時, 這一行會才秀出來<hr size=1>';
}elseif($fruit=="orange"){
       echo '<hr size=1>只有當要 $fruit 是 orange 時, 才會秀出這行<hr size=1>';
}else{
       echo '<hr size=1>其他ㄉ, 都會秀出這行<hr size=1>';
}
echo '<p>我們的水果: $fruit = '.$fruit."</p>";
?>
實例四:if
程式碼:103_04.php

範例: if的另一種用法, 內嵌在其他文件中 <br/>

<?php if($fruit=="apple"): ?>
<hr size=1>只有當 $fruit 等於是 apple 時, 這一行會才秀出來<hr size=1>

<?php elseif($fruit=="orange"): ?>
<hr size=1>只有當要 $fruit 是 orange 時, 才會秀出這行<hr size=1>

<?php else: ?>
<hr size=1>其他ㄉ, 都會秀出這行<hr size=1>
<?php endif; ?>

<p>我們的水果: $fruit = <?=$fruit?></p>
二、switch 命令句
實例五:
程式碼:103_05.php

<?php
echo "switch 範例: case 的標籤值為常數<br/>";
switch($fruit){
       case "apple":
              $myfruit = "蘋果";
              break;
       case "banana":
              $myfruit = "香蕉";
              break;
       case "orange":
              $myfruit = "柳橙";
              break;
       case "guava":
              $myfruit = "拔辣";
              break;
       case "pear":
              $myfruit = "梨子";
              break;
       default:
              $myfruit = "西瓜";
}
echo "<hr size=1>你選的是 $myfruit <hr size=1>";
?>
實例六:
程式碼:103_06.php

<?php
echo "switch 範例: case 的標籤值為變數<br/>";
$a = "apple";
$b = "banana";
$c = "orange";
$d = "guava";
$e = "pear";
switch($fruit){
       case $a:
              $myfruit = "蘋果";
              break;
       case $b:
              $myfruit = "香蕉";
              break;
       case $c:
              $myfruit = "柳橙";
              break;
       case $d:
              $myfruit = "拔辣";
              break;
       case $e:
              $myfruit = "梨子";
              break;
       default:
              $myfruit = "西瓜";
}
echo "<hr size=1>你選的是 $myfruit <hr size=1>";
?>
迴圈:
一、while 迴圈
基本型態

while(condition){
    statement 1;
    statement 2;
    .
    .
    statement n;

}

當 condition 的值為真時,一直執行 { 和 }所包圍住的程式區段,直到 condition的值變成假的為止。所以,使用while迴圈時,要特別注意,程式區段裡面的命令句,或是condition這個運算式本身,必須要能隨時更新,讓condition能變成假的值。

實例七:
程式碼:103_07.php

<?php
echo "while 範例: { 和 }所包圍的程式區段, 改變 while 的 condition<br/>";
echo "<hr size=1>";
$i = 0;
while($i < 10){
       echo "$i 的平方: ".$i * $i."<br />";
       $i++;
}
?>
實例八:
程式碼:103_08.php

<?php
echo "while 範例: while condition 本身的運算結果, 改變 while 的 condition<br/>";
echo '使用 pre-increment: 變數 $i 的值先遞增, 再來檢查是否比 10 小<br />';
echo "<hr size=1>";
$i = 0;
while(++$i < 10){
       echo "$i 的平方: ".$i * $i."<br />";
}
?>
實例九:
程式碼:103_09.php

<?php
echo "while 範例: while condition 本身的運算結果, 改變 while 的 condition<br/>";
echo '使用 post-increment: 先檢查是否比 10 小, 再來遞增變數 $i 的值 <br />';
echo "<hr size=1>";
$i = 0;
while($i++ < 10){
       echo "$i 的平方: ".$i * $i."<br />";
}
?>
實例十:
程式碼:103_10.php

範例: while 的另一種用法, 內嵌在其他文件中 <br/><hr size=1>

<?php $i = 0; ?>
<?php while($i++ < 10): ?>
<?=$i?> 的平方: <?=$i * $i?> <br />
<?php endwhile;?>
二、for 迴圈
實例十一:
程式碼:103_11.php

<?php
echo "範例: for 迴圈<br>";

echo "<TABLE border=1>";
echo "<TR><TD>數字</TD><TD>平方</TD></TR>";

for($i = 1; $i < 10; $i++){
echo "<TR><TD>$i</TD><TD>".$i * $i."</TD></TR>";
}
echo "</TABLE>";
?>
實例十二:
程式碼:103_12.php

範例: for 的另一種用法, 內嵌在其他文件中 <br/><hr size=1>

<TABLE border=1>
<TR><TD>數字</TD><TD>平方</TD></TR>
<?php for($i = 1; $i < 10; $i++): ?>
<TR><TD><?=$i?></TD><TD><?=$i * $i?></TD></TR>
<?php endfor;?>
</TABLE>
綜合實例:
寫一個程式模擬投擲一顆骰子6000次,並記錄每個點數,出現的次數。
程式碼:103_dice.php

<?php
define ("THROWS", 6000);
$p1 = 0;
$p2 = 0;
$p3 = 0;
$p4 = 0;
$p5 = 0;
$p6 = 0;
for($i = 0; $i < THROWS; $i++){
       $p = rand(1, 6);
       switch($p){
              case 1:
                     $p1++;
                     break;
              case 2:
                     $p2++;
                     break;
              case 3:
                     $p3++;
                     break;
              case 4:
                     $p4++;
                     break;
              case 5:
                     $p5++;
                     break;
              case 6:
                     $p6++;
                     break;
       }
}
echo <<<END
<div align=center>擲骰子<br></div>
<TABLE border=1 align=center>
<TR>
       <TD>點數</TD>
       <TD>次數</TD>
</TR>
<TR>
       <TD>1</TD>
       <TD>$p1</TD>
</TR>
<TR>
       <TD>2</TD>
       <TD>$p2</TD>
</TR>
<TR>
       <TD>3</TD>
       <TD>$p3</TD>
</TR>
<TR>
       <TD>4</TD>
       <TD>$p4</TD>
</TR>
<TR>
       <TD>5</TD>
       <TD>$p5</TD>
</TR>
<TR>
       <TD>6</TD>
       <TD>$p6</TD>
</TR>
</TABLE>
END;
?>
程式碼:103_diceArray.php 另一種作法

<?php
define ("THROWS", 6000);
$p = array(0,0,0,0,0,0,0);
for($i = 0; $i < THROWS; $i++){
       $points = rand(1, 6);
       $p[$points]++;
}
echo <<<END
<div align=center>"擲骰子: 使用陣列"<br></div>
<TABLE border=1 align=center>
<TR>
       <TD>點數</TD>
       <TD>次數</TD>
</TR>
<TR>
       <TD>1</TD>
       <TD>$p[1]</TD>
</TR>
<TR>
       <TD>2</TD>
       <TD>$p[2]</TD>
</TR>
<TR>
       <TD>3</TD>
       <TD>$p[3]</TD>
</TR>
<TR>
       <TD>4</TD>
       <TD>$p[4]</TD>
</TR>
<TR>
       <TD>5</TD>
       <TD>$p[5]</TD>
</TR>
<TR>
       <TD>6</TD>
       <TD>$p[6]</TD>
</TR>
</TABLE>
END;
?>
課後練習:
1. 修改上面的擲骰子程式,將程式改為擲兩顆,擲12000次。並記錄每個點數,出現的次數。(解答:[post]Run this programme 原始碼[/post]
2. 修改 1. 的程式,作一個表單,讓使用者輸入骰子顆數,及投擲的次數,然後錄每個點數,出現的次數。(解答:[post]Run this programme 原始碼[/post]

PHP教學 第四回

課程104:MySQL:建立與刪除資料庫及資料表。
摘要:在之前的課程中,我們運用了表單來讀取使用者所輸入的資料,然後將運算完的結果,直接呈現在網頁上,沒有討論到如何儲存及管理資料。在網站後端,資料的儲存與管理,最有效率的方式,便是使用資料庫。PHP可以存取市面上許多的資料庫,但最常見的組合是,PHP+MySQL。所以在還沒介紹,存取資料庫的通用程式庫之前,我們會把重心集中在MySQL。在之後的課程,我們會討論,如何利用其他的通用程式庫,來連接各種資料庫,儘量使我們的程式碼與資料庫的種類脫節,避免更換資料庫時,需要大幅翻修程式碼。在這個課程中,我們介紹如何在MySQL建立與刪除資料庫及資料表。
工具:
一、putty
說明:
putty 是一個Windows平台上免費的Telnet及SSH的連線程式,可以讓我們透過Telnet及SSH連線到Un*x的平台,使用命令列來執行遠端 Un*x的指令。在我們的課程中,所使用的主機僅提供SSH的連線,透過加密的方式,以確保連線資料傳輸的安全性。putty程式,可在以下的網頁中,找到下載的連結:http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html

連線:

   1. 執行 Putty 程式。
   2. 在 Host Name 這個欄位中輸入主機名稱:
   3. 在 Protocol 點選 SSH 的圓鈕。
   4. 在 Saved Sessions 欄位中輸入連線名稱,然後按Save按鈕。儲存連線,日後,使用相同連線時,只需按Load按鈕,便可以載入之前的連線設定。
   5. 按 Open 按鈕,開啟連線。

   6. 在連線的視窗中,輸入你的帳號及密碼。

二、MySQL 用戶端連線工具 mysql
說明:
mysql 是與 MySQL 資料庫連線的用戶端工具,透過執行 mysql 指令,我們可以執行許多資料庫操作與管理的工作。

執行:

   1. 進入系統之後,輸入以下的指令:
      mysql -p
   2. 在 Enter Password: 提示,輸入你的 mysql 密碼。


建立與刪除資料庫及資料表:
一、建立資料庫

   1. 在 mysql 提示,輸入:
      create database lib13; 按 Enter

      醬子,就會在 MySQL建立一個名為 lib13 的資料庫。

說明:

   1. create database 資料庫名稱 是 MySQL 建立資料庫的命令,後面接資料庫的名稱。
   2. 切記:所有的 mysql 命令後面必須加分號 ; ,分號在 mysql 中代表 命令的結束點。必須要有分號才算完整的一個 mysql 命令。
   3. 在課程所使用的帳號中,已經設定好權限,每個人只能建立與自己帳號同名的資料庫。如果,你的帳號是 lib1。請輸入 create database lib1。


二、秀出所有資料庫
程式執行結果:

   1. 在 mysql 提示,輸入:
      show databases; 按 Enter

      醬子,就會秀出這台 MySQL 主機中,所有的資料庫名稱。

說明:

   1. show databases 是 MySQL 秀出資料庫的命令。
   2. 切記:databases 是複數,後面必須加 s ,否則便是語法錯誤。


三、選用資料庫:

   1. 在 mysql 提示,輸入:
      use lib13; 按 Enter


      醬子, MySQL 就知道你現在要使用的資料庫是 lib13。

說明:

   1. use 資料庫名稱; 是 MySQL 選取資料庫的命令。
   2. 請選用你剛剛所建立的資料庫,因為權限設定的關係,你只能使用你剛剛建立的資料庫。


四、建立資料表:

   1. 在 mysql 提示,輸入:
      create table Test ( 按 Enter
      id int primary key auto_increment, 按 Enter
      name varchar(16) 按 Enter
      ); 按 Enter

      醬子, MySQL 就會在現在所選用的資料庫,產生一個 Test 資料表。在這個資料表中,有兩個欄位:id 和 name 。id的資料型態是整數(INT),同時,也是 Test 資料表的主索引欄位 (primary key),並且再新增紀錄時,會自動遞增 (auto_increment)。name的資料型態是可變長度的字元,最多可放16個字元 (VARCHAR(16))。

說明:

   1. create table 資料表名稱(欄位名稱 欄位資料型態); 是 MySQL 建立資料表的命令。
   2. 括弧裡面,每個欄位之間以逗號區隔,最後一個欄位之後,千萬不要再加逗號。
   3. 每個欄位的定義,至少必須有欄位名稱及欄位資料型態。


五、秀出資料表的欄位資料:

   1. 在 mysql 提示,輸入:
      show columns from Test; 按 Enter
      或者
      describe Test; 按 Enter

      醬子, MySQL 就會顯示 Test 資料表中的所有欄位的定義資料。

說明:

   1. show columns from 資料表名稱; 或者 describe 資料表名稱; 是 MySQL 秀出資料表的命令。
   2. 切記:columns 是複數,後面必須加 s ,否則便是語法錯誤。


六、刪除資料表:

   1. 在 mysql 提示,輸入:
      drop table Test; 按 Enter

      醬子, MySQL 就會刪除 Test 資料表。

說明:

   1. drop table 資料表名稱; 是 MySQL 刪除資料表的命令。
   2. 切記:當資料表被刪除時,其中所有的紀錄也會被刪除掉。


七、刪除資料庫:

   1. 在 mysql 提示,輸入:
      drop database lib13; 按 Enter

      醬子, MySQL 就會刪除 lib13 資料庫。

說明:

   1. drop database 資料庫名稱; 是 MySQL 刪除資料庫的命令。


八、其他:

   1. 在 mysql 提示,按向上的箭頭鍵,和 linux shell一樣可以切換到之前的命令。
   2. 要離開 mysql 提示,可以輸入 exit 再按 Enter 鍵。

PHP教學 第五回

上一課學得怎樣呢?好了,廢話少說開開始第五回:
摘要:  在介紹MySQL查詢的基本語法之前,我們需要一些資料。所以,我們先討論如何將資料匯入到資料庫。接著我們學習如何使用 mysqldump 把資料庫中的資料匯出成 Script 檔。最後,我們學習把 dump 出來的 Script 檔還原回資料庫。
資料的匯入

說明:

用 Access 作了一個資料庫 mxdb(按這裡下載)。以下的實作,將轉換資料庫中的 Guestbook 資料表,到 MySQL 資料庫。


一、自 Access 檔案中,將 Guestbook 轉換成文字檔

說明:

我們會在 MySQL 中建立一個 Guestbook 資料表,然後匯入 Access 資料庫中Guestbook資料表的資料。
實作:

   1. 執行 Access,並開啟 mxdb.mdb檔。
   2. 選取 Guestbook 這個資料表,按滑鼠右鍵,在跳出式選單中,選取匯出,檔案類型:選擇文字檔案。然後,按儲存按鈕。
   3. 在輸出文字精靈中,按進階按鈕,把日期分隔符號改為 -,然後按確定按鈕,回到輸出文字精靈。
   4. 按下一步按鈕,檢查選擇欄位分隔字元為逗號,字串辨識符號為雙引號。按完成按鈕,完成輸出。
二、轉換文字檔案的類型

說明:

因為 Windows 的文字檔案,使用與 Unix/Linux 文字檔案不同的換行字元。所以,在 Linux的MySQL 匯入文字檔案的資料時,會發生問題。解決的方式是使用 EditPlus 中的檔案轉換功能,將文字檔轉換成 Unix的格式。
實作:

   1. 啟動 EditPlus。開啟之前自 Access 匯出的文字檔:GuestbookOut.txt。
   2. 執行選單中的 Document | File Format (CR/LF) | Unix。
   3. 存檔。

三、撰寫 MySQL 的 Script 檔

說明:

原則上,我們可以使用 mysql 的工具,進入到 mysql 提示下,以互動的方式,先建立資料庫,再建立資料表,然後再匯入文字檔中的資料。但是,這樣做有個缺點,就是在輸入命令時難免會打錯字。每次重打會很不方便。所以,我們使用另一種技巧,就是使用 Linux Shell 的重導輸入的方式,將 mysql 指令導入到 mysql 環境,作批次的執行。這種技巧在資料庫的備份與還原時,以及將資料庫移轉到其他機器上時,也很常用。不過,在撰寫 MySQL 的 Script 檔之前,我們先設定 EditPlus 的 MySQL 的語法檔。
實作:設定 EditPlus 的 MySQL 的語法檔

   1. 下載 EditPlus 的 MySQL 的語法檔 sql.txt (按這裡下載)。
   2. 將 sql.txt 放置在 EditPlus 的安裝資料夾中。如:C:\Program Files\EditPlus。
   3. 啟動 EditPlus。
   4. 執行選單中的 Tools | Preferences。按 Add 按鈕新增檔案類型。
   5. 參考下圖,設定各欄位,完成設定後,按 OK 按鈕。


實作:撰寫 MySQL 的Script檔

   1. 啟動 EditPlus。
   2. 執行選單中的 File | New | Others。
   3. Select File Type選擇 MySQL,然後按 OK按鈕。
   4. 輸入以下的 MySQL 命令碼:

QUOTE:
# 產生資料庫
Create Database lib13;

# 選用資料庫
use lib13;

# 產生 Guestbook 資料表
Create Table Guestbook(
  id int primary key auto_increment,
  name varchar(32) not null,
  email varchar(64),
  web varchar(128),
  content text,
  post_time datetime not null,
  fk_icon int not null
);

# 將 GuestbookOut.txt 中的內容載入到 Guestbook 資料表
LOAD DATA LOCAL INFILE "Guestbook.txt"
  INTO TABLE Guestbook
  FIELDS
  TERMINATED BY ','
  ENCLOSED BY '"'
  (name, email, web, content, post_time, fk_icon);

程式說明:

# 是 MySQL 的註解符號。

Load Data 的用法:
格式:
LOAD DATA LOCAL INFILE 資料文字檔
INTO TABLE 資料表名稱
FIELDS
TERMINATED BY <char A>
ENCLOSED BY <char A>
(欄1, 欄2, 欄3, ...欄n);

TERMINATED BY <char A> 表示以字元A, 作為輸入資料的欄位分隔字元, 字元前後以單引號框住.

ENCLOSED BY <char A> 表示以字元A, 作為輸入資料的文字欄位字串辨識符號, 字元前後以單引號框住.
*/


四、匯入資料

說明:

MySQL的Script檔完成後,我們就可以將Script檔和資料的文字檔,上傳到資料庫主機中。接著使用 Linux Shell 的重導輸入的方式,將資料匯入到 MySQL資料庫中。


實作:匯入資料

   1. 使用EditPlus的檔案上傳功能,將 db.sql 及 Guestbook.txt上傳到資料庫主機。
   2. 使用Putty連線到主機。
   3. 使用 cd 指令,切換到之前上傳的目錄中。
   4. 在 Linux Shell 執行以下的指令,將資料匯入到 MySQL 資料庫:
      mysql -p<db.sql
   5. 輸入你的MySQL密碼後,完成匯入。

實作:檢查資料是否已匯入成功

   1. 在 Linux Shell 執行以下的指令:
      mysql -p
   2. 輸入你的密碼後,進入 mysql 提示。
   3. 在mysql 提示下,輸入以下的命令,秀出所有資料庫。
      show databases;
   4. 在mysql 提示下,輸入以下的命令,選用匯入的資料庫。
      use lib13;
   5. 在mysql 提示下,輸入以下的命令,秀出資料庫中所有的資料表。
      show tables;
   6. 在mysql 提示下,輸入以下的命令,秀出 Guestbook 資料表各欄位的定義。
      describe Guestbook;

資料庫的備份、還原、與移轉

說明:

資料庫的備份、還原、與移轉,除了是資料庫管理者的日常重要工作之外,對程式開發者而言,也是一個非常重要的技能。在實務上,多數的小型專案,客戶通常並沒有設置資料庫管理師,來幫你處理這些事情;就算有,你要取得資料庫管理師的幫助時,你也必須要會一些基本的資料庫操作技能,才能讓你和對方在工作上的溝通與合作愉快。資料庫的備份,在這只教導 MySQL的 mysqldump指令的使用。使用 mysqldump 配合 Linux Shell的重導輸出,就可以把資料庫的資料匯出成 MySQL Script檔案。之後,你就可以使用這個檔案,用之前 mysql 配合Linux Shell 的重導輸入的方式,將資料庫還原;或者,將這個檔案,複製到其他的機器,匯入到其他機器的 MySQL資料庫中。


實作:資料庫的備份

   1. 使用Putty連線到主機。
   2. 執行以下的指令,將資料匯出到 Script檔:
      mysqldump -p lib13 > db_backup.sql
   3. 輸入你的密碼後,完成匯出。

實作:刪除 Guestbook 資料表

   1. 使用Putty連線到主機。
   2. 在 Linux Shell 執行以下的指令:
      mysql -p
   3. 輸入你的密碼後,進入 mysql 提示。
   4. 在mysql 提示下,輸入以下的命令,選用匯入的資料庫。
      use lib13;
   5. 在mysql 提示下,輸入以下的命令,刪除 Guestbook 資料表。
      drop table Guestbook;
   6. 在mysql 提示下,輸入以下的命令,秀出資料庫中所有的資料表。
      show tables;

實作:資料庫的還原

   1. 使用Putty連線到主機。
   2. 在 Linux Shell 執行以下的指令:
      mysql -p lib13 < db_backup.sql
   3. 輸入你的密碼後,完成還原。
哇,又一課了。下回會教大家<<MySQL:SQL 基本語法>>,密切留意。

PHP教學 第六回

摘要:  在這個課程中,將會介紹基本的 SQL 語法。這些 SQL 語法包含了:SELECT、INSERT、UPDATE、DELETE等。我們使用這些語法對資料庫執行:查詢、新增、更新、以及刪除等工作。這些工作幾乎含括了資料庫大部分的資料查詢作業,所以,身為網站應用程式開發者,學會這些基本語法,是必備的技能。在這個課程中,我們專注於學習這些基本的 SQL 語法,在 mysql 的環境中,使用這些語法。在之後的課程,我們會將所學習到的 SQL 技能,整合在 PHP 的程式之中。

SELECT

說明:

SELECT 句型,是用來對資料庫作查詢之用。資料庫在執行 SELECT 命令之後,會傳回查詢的結果。以下分別介紹各種 SELECT 句型的用法:

   1. 基本句型
   2. 使用萬用字元
   3. 使用 WHERE 子句,作為過濾查詢的條件。
   4. 使用 ORDER BY 子句,來定義排序的欄位,以及排序的方式。
   5. 使用 LIMIT 子句,設定查詢結果的範圍。
一、基本句型

句型:

QUOTE:
SELECT 欄位 1, 欄位 2, ...,欄位N FROM 資料表

說明:

   1. 上面的句型,表示選取資料表中所有紀錄,並按照:欄位 1, 欄位 2, ...,欄位N的方式,分欄位排列查詢的資料。
   2. 每個欄位以逗號區隔。
   3. 句型中的 SELECT 和 FROM 都是 SQL 的保留字。
   4. SQL 語法,除了資料表名稱及欄位名稱之外,並不區隔字母的大小寫。所以,你也可以寫成:Select 欄位 1, 欄位 2, ...,欄位N from 資料表。
實作:

   1. 使用 PUTTY 連線,進入資料庫伺服主機。
   2. 在主機系統的命令提示下,輸入:mysql -p。
   3. 輸入密碼。
   4. 在 mysql 提示下,輸入:use 你的資料庫名稱,如:use lib13; 再按 Enter 鍵。選用你的資料庫。
   5. 在 mysql 提示下,輸入:
      SELECT id, name, email, post_time FROM Guestbook;
   6. 按 Enter 鍵,執行 SQL 命令。觀察查詢所得的結果。
   7. 練習:試著更改 SELECT 命令句中欄位的部分,執行 SQL 命令,再觀察查詢所得的結果。如果,不知道 Guestbook 資料表中有哪些欄位的話,可以使用 describe Guestbook; 或 show columns from Guestbook; 的命令句,顯示 Guestbook資料表各欄位的定義。

二、萬用字元

句型:

QUOTE:
SELECT * FROM 資料表

說明:

   1. 星號 * ,代表所有欄位。
   2. 如果需要顯示所有欄位時,一一輸入欄位名稱的方式,不但麻煩,而且容易因為輸入錯誤,而產生問題。所以,使用星號可以簡化我們撰寫 SELECT 命令的工作。

實作:

   1. 在 mysql 提示下輸入:
      SELECT * FROM Guestbook;
   2. 按 Enter 鍵,執行 SQL 命令。

三、WHERE 子句

句型:

QUOTE:
SELECT 欄位 FROM 資料表 WHERE 條件

說明:

   1. WHERE子句,用來定義查詢所要過濾的條件。
   2. 只有符合 WHERE 子句條件的紀錄,才會被選取。
   3. 條件的內容,通常是以欄位來比對某特定的值。要特別注意的是,如果,被比對的值,其資料型態不是數值時,前後必須使用單引號框住。
   4. 以下是常用的比較運算子:
運算子                意義
=                   等於
!= 或 <>       不等於
>                  大於
>=                 大於等於
<                  小於
<=                 小於等於
LIKE                 字串的樣式比對。可用%萬用字元。

   5. WHERE子句中的條件,可以用 AND、OR、NOT等邏輯運算子,來組合成更複雜的查詢條件。
   6. 條件中的欄位,不一定要出現在 SELECT 的欄位中。

實作:

   1. 在 mysql 提示下輸入:
      SELECT id, name FROM Guestbook WHERE id=3;
   2. 按 Enter 鍵,執行 SQL 命令。
   3. 在 mysql 提示下輸入:
      SELECT id, name FROM Guestbook WHERE id!=3;
   4. 按 Enter 鍵,執行 SQL 命令。
   5. 在 mysql 提示下輸入:
      SELECT id, name FROM Guestbook WHERE id>3;
   6. 按 Enter 鍵,執行 SQL 命令。
   7. 在 mysql 提示下輸入:
      SELECT id, name FROM Guestbook WHERE id>=3;
   8. 按 Enter 鍵,執行 SQL 命令。
   9. 在 mysql 提示下輸入:
      SELECT id, name FROM Guestbook WHERE id<3;
  10. 按 Enter 鍵,執行 SQL 命令。
  11. 在 mysql 提示下輸入:
      SELECT id, name FROM Guestbook WHERE id<=3;
  12. 按 Enter 鍵,執行 SQL 命令。
  13. 在 mysql 提示下輸入:
      SELECT id, name FROM Guestbook WHERE id>2 AND fk_icon=2;
  14. 按 Enter 鍵,執行 SQL 命令。
  15. 在 mysql 提示下輸入:
      SELECT id, name FROM Guestbook WHERE id=1 OR id=4;
  16. 按 Enter 鍵,執行 SQL 命令。
  17. 在 mysql 提示下輸入:
      SELECT id, name FROM Guestbook WHERE email like 'au%';
  18. 按 Enter 鍵,執行 SQL 命令。
  19. 在 mysql 提示下輸入:
      SELECT id, name, email FROM Guestbook WHERE email like '%e%';
  20. 按 Enter 鍵,執行 SQL 命令。

四、ORDER BY 子句

句型:

QUOTE:
SELECT 欄位 FROM 資料表 [WHERE 子句] ORDER BY 欄位 [排序方式]

說明:

   1. 上面的句型中,[] 表示選用,不可以打入在 SQL 命令中,只是用來在這裡,說明句型的結構之用而已。
   2. ORDER BY 後面必須接欄位,表示使用這個欄位來排序。
   3. 排序方式有兩種:昇冪 (ASC),和降冪(DESC)。
   4. 如果未指定排序方式時,預設是昇冪的排序。
   5. 欄位可以用資料表的欄位名稱,使用欄位名稱時,這個欄位不一定要出現在 SELECT 所列出來的欄位中。
   6. 欄位也可以用數字來表示。這個數字是 SELECT 所列出來的欄位順序,起始值為 1。

實作:

   1. 在 mysql 提示下輸入:
      SELECT id, name, email FROM Guestbook ORDER BY fk_icon DESC;
   2. 按 Enter 鍵,執行 SQL 命令。
   3. 在 mysql 提示下輸入:
      SELECT id, name, email FROM Guestbook ORDER BY 2 DESC;
   4. 按 Enter 鍵,執行 SQL 命令。

五、LIMIT 子句

句型:

QUOTE:
SELECT 欄位 FROM 資料表 [WHERE 子句] [ORDER BY 子句] LIMIT [起始值, ] 紀錄筆數

說明:

   1. LIMIT 是用來限定傳回的紀錄筆數。
   2. 可以選用起始值,來指定從哪一筆記錄開始啟算。
   3. 查詢結果中第一筆紀錄的起始值為 0,以下依此類推。
   4. 這個功能在需要分頁顯示查詢資料時,特別有用。

實作:

   1. 在 mysql 提示下輸入:
      SELECT id, name, email FROM Guestbook LIMIT 3;
   2. 按 Enter 鍵,執行 SQL 命令。
   3. 在 mysql 提示下輸入:
      SELECT id, name, email FROM Guestbook LIMIT 1, 3;
   4. 按 Enter 鍵,執行 SQL 命令。

INSERT

說明:

INSERT 句型,是用來新增資料到資料表的命令。以下分別說明 INSERT的各種用法:

   1. 新增單筆資料(不指定欄位)。
   2. 新增單筆資料(指定欄位)。
   3. 新增多筆資料。

一、新增單筆資料(不指定欄位)

句型:

QUOTE:
INSERT INTO 資料表 VALUES(值1, 值2, ..., 值N)

說明:

   1. 執行這個句型的命令,會新增一筆資料到資料表。
   2. VALUES 括號中所列示的值的數目,必須與資料表中的欄位數相同。每個值以逗號分開。
   3. VALUES 括號中的值,其順序與資料型態,必須與資料表欄位的順序與資料型態相符。
   4. 非數值的欄位,其新增的值,前後必須以單引號框住。

實作:

   1. 在 mysql 提示下輸入:
      INSERT INTO Guestbook VALUES(10, 'george', 'george@igt.com.tw', 'www.test.com', 'hello there', NOW(), 2);
   2. 按 Enter 鍵,執行 SQL 命令。
   3. 在 mysql 提示下輸入:
      SELECT * FROM Guestbook;
   4. 按 Enter 鍵,執行 SQL 命令。並觀察新增資料的結果。

二、新增單筆資料(指定欄位)

句型:

QUOTE:
INSERT INTO 資料表(欄位1, 欄位2, ...,欄位N) VALUES(值1, 值2, ..., 值N)

說明:

   1. 資料表後面的括弧中的欄位列表,必須與 VALUES裡面的值列表,數目、順序、與資料型態配合。
   2. 資料表後面的括弧,不需要列示資料表中的所有欄位,順序也不需要和資料表本身的欄位相同。
   3. 資料表欄位的定義中,如果是 NOT NULL,非自動增量,又沒有設定預設值,同時又沒有定義 Default預設值的話,在新增時,一定要把這個欄位列示出來。

實作:

   1. 在 mysql 提示下輸入:
      INSERT INTO Guestbook (name, fk_icon)VALUES('mary', 3);
   2. 按 Enter 鍵,執行 SQL 命令。
   3. 在 mysql 提示下輸入:
      SELECT * FROM Guestbook;
   4. 按 Enter 鍵,執行 SQL 命令。並觀察新增資料的結果。

三、新增多筆資料

句型:

QUOTE:
INSERT INTO 資料表[欄位列表] VALUES(值列表), (值列表)...

說明:

   1. 要新增多筆欄位時,在VALUES之後,每筆資料的值列表,前後以括號框住,並以逗號作區隔。

實作:

   1. 在 mysql 提示下輸入:
      INSERT INTO Guestbook (name, fk_icon)VALUES('jay', 2), ('jolin', 1);
   2. 按 Enter 鍵,執行 SQL 命令。
   3. 在 mysql 提示下輸入:
      SELECT * FROM Guestbook;
   4. 按 Enter 鍵,執行 SQL 命令。並觀察新增資料的結果。

UPDATE

說明:

UPDATE 句型,是用來更新資料的命令。以下是 UPDATE的用法:

   1. 更新所有資料。
   2. 更新特定資料。

一、更新所有資料

句型:

QUOTE:
UPDATE 資料表 SET 欄位1= 值1, 欄位2=值2, 欄位3=值3

說明:

   1. 執行這個句型的命令,會更新資料表中所有的紀錄。
   2. 使用 UPDATE 更新資料時,一定要指定所要更新的欄位以及更新的值。
   3. 如果更新的欄位超過一個時,每組欄位=值,必須以逗號區隔。

實作:

   1. 在 mysql 提示下輸入:
      UPDATE Guestbook SET fk_icon=2, web='www.twisu.com.tw';
   2. 按 Enter 鍵,執行 SQL 命令。
   3. 在 mysql 提示下輸入:
      SELECT * FROM Guestbook;
   4. 按 Enter 鍵,執行 SQL 命令。並觀察新增資料的結果。

二、更新特定資料

句型:

QUOTE:
UPDATE 資料表 SET 欄位1= 值1, 欄位2=值2, 欄位3=值3 WHERE 條件

說明:

   1. 要更新特定資料時,可以在後面加上 WHERE條件子句,來限定要更改的紀錄。

實作:

   1. 在 mysql 提示下輸入:
      UPDATE Guestbook SET email=Concat(name, '@twisu.com.tw') WHERE id > 9;
   2. 按 Enter 鍵,執行 SQL 命令。
   3. 在 mysql 提示下輸入:
      SELECT * FROM Guestbook;
   4. 按 Enter 鍵,執行 SQL 命令。並觀察新增資料的結果。

DELETE

說明:

DELETE 句型,是用來刪除資料的命令。以下是 DELETE的用法:

   1. 刪除所有資料。
   2. 刪除特定資料。

一、刪除所有資料

句型:

QUOTE:
DELETE FROM 資料表

說明:

   1. 執行這個句型的命令,會刪除資料表中所有的紀錄。

實作:
我們的資料,以後還要用,所以,在這裡就不實作了。切記,除非你真的要刪除所有的紀錄,否則,除非有備份,不然要挽救這些資料,就很麻煩了。
二、刪除特定資料

句型:

QUOTE:
DELETE FROM 資料表 WHERE 條件

說明:

   1. 要刪除特定資料時,可以在後面加上 WHERE條件子句,來限定要刪除的紀錄。

實作:

   1. 在 mysql 提示下輸入:
      DELETE FROM Guestbook WHERE id = 2;
   2. 按 Enter 鍵,執行 SQL 命令。
這課到此為止,下一回會教大家MySQL 與 PHP 的結合,密切留意。

PHP教學 第七回

好!繼續課程! 撰寫資料庫網頁程式:
摘要:  在之前課程中,我們討論了使用 SQL 的語法,來管理資料庫裡面的資料。從這個單元開始,我們將實作留言版的專案,分別使用各種開發方式,來開發同樣的專案。讓學習者能學習各種不同的開發方式,藉由實地開發產生不同的體認。在這個單元中,我們將應用 SQL 語法,整合在 PHP網頁的程式之中。在這個課程中的每一頁 PHP 程式,都包含了完整的資料庫命令,專注在於每個資料庫作業的程式撰寫。等熟悉了資料庫網頁的撰寫方式之後,在以後單元中,將學習如何撰寫函式,將類似的功能分離出來,獨立成為個別的函式,並整合在函式庫中,供其他 PHP 程式使用。在之後的課程中,將介紹如何使用物件導向的方式,來重新改寫原本的程式。
留言版專案功能規範

說明:

為了教學上的目的,我們刻意忽略了一些實務上的功能需求,專注於學習資料庫程式的撰寫,以提高學習的效果。

留言版的功能規範如下:

   1. 簡單的權限控管:使用$PHP_AUTH_USER,$PHP_AUTH_PW全域變數
   2. 一個留言版列表的網頁:控管更新與刪除連結的呈現
   3. 一個新增留言的網頁
   4. 一個更新留言的網頁:存取控制
   5. 一個刪除留言的網頁:存取控制

在這個課程中,我們先專注於資料庫網頁的撰寫。在下一個課程中,再加入網頁存取控制的功能。

留言版的列表、新增、更新、以及刪除
一、準備工作

說明:

我們沿用之前的做法,把相關的網頁,放在同一個目錄之下。


實作:

   1. 使用putty連線到伺服主機。
   2. 輸入以下的命令,進入 public_html 目錄:
      cd public_html
   3. 輸入以下的命令,產生 guestbook 目錄:
      mkdir guestbook
   4. 輸入以下的命令,產生網頁程式的檔案:
      touch index.php add.php update.php delete.php

二、留言版列表

說明:

在這個部分,我們使用 SQL 的 SELECT 語法,取出 Guestbook 的所有資料,將每一筆記錄,以個別的表格呈現出來。
程式碼:

QUOTE:
<?php
/* 定義連接資料庫的有關參數 */
define('DB_USER', 'lib13');
define('DB_PASSWORD', 'mypassword');
define('DB_HOST', 'localhost');
define('DB_DATABASE', 'lib13');

/* 連接資料庫 */
$link = mysql_pconnect(DB_HOST, DB_USER, DB_PASSWORD)
       or die('無法連接到資料庫:'.mysql_error());

/* 選用資料庫 */
mysql_select_db(DB_DATABASE)
       or die('無法選擇資料庫['.DB_DATABASE.']:'.mysql_error());
      
/* 執行查詢 */

// 定義 SQL 命令的字串變數
$sql = 'SELECT * FROM Guestbook ORDER BY post_time DESC';

// 開始執行查詢
$result = mysql_query($sql);

/* 處理查詢結果 */
$output = '';
while($record = mysql_fetch_array($result)){
       $record[email] = strlen(trim($record[email])) > 0?'<a href=mailto:'.$record[email].'><img src=email.gif border=0></a>':' ';
       $record[web] = strlen(trim($record[web])) > 0?'<a href=http://'.$record[web].' target=_blank><img src=home.gif border=0></a>' :' ';
       $record[content] = nl2br($record[content]);
       $table=<<<EOF
<table width="600" border="1" cellpadding="0" cellspacing="0" bordercolor="#9999FF" align="center">
       <tr bgcolor="#9999FF">
               <td width="35%"><font color="#FFFFFF">$record[name]:</font></td>
                <td width="12%"><div align="center"><font color="#FFFFFF">$record[email]</font></div></td>
                <td width="11%"><div align="center"><font color="#FFFFFF">$record[web]</font></div></td>
                <td width="42%"><div align="right"><font color="#FFFFFF">$record[post_time]</font></div></td>
       </tr>
       <tr valign="top">
               <td height="120" colspan="4">$record[content]</td>
    </tr>
       <tr>
              <td colspan=2><div align="center"><a href="delete.php?id=$record[id]">刪除</a></div></td>
              <td colspan=2><div align="center"><a href="update.php?id=$record[id]">更新</a></div></td>
       </tr>
</table>
<hr width=600 size=1 />
EOF;
       $output .= $table;
}

/* 列印輸出 */
echo <<<EOF
<center>
<hr width=600 size=1 />留言版<hr width=600 size=1 />
<a href="add.php">我要留言<a><hr width=600 size=1 />
</center>
$output
EOF;
?>

三、新增留言

說明:

使用資料庫網頁,要新增一筆記錄時,使用 INSERT 語法,將使用者填入表單的資料,新增到資料庫中。

程式碼:

QUOTE:
<?php
/* 檢查使用者是否按下送出的按鈕
       如果是的話,執行以下的程式;
       否則,顯示以下的表單。 */

if(isset($_POST[Submit])){
       /* 定義連接資料庫的有關參數 */
       define('DB_USER', 'lib13');
       define('DB_PASSWORD', 'mypassword');
       define('DB_HOST', 'localhost');
       define('DB_DATABASE', 'lib13');

       /* 連接資料庫 */
       $link = mysql_pconnect(DB_HOST, DB_USER, DB_PASSWORD)
              or die('無法連接到資料庫:'.mysql_error());

       /* 選用資料庫 */
       mysql_select_db(DB_DATABASE)
              or die('無法選擇資料庫['.DB_DATABASE.']:'.mysql_error());
              
       /* 執行查詢 */

       // 定義 SQL 命令的字串變數
       $sql = "INSERT INTO Guestbook(name, email, web, content, post_time) VALUES('$_POST[name]', '$_POST[email]', '$_POST[web]', '$_POST[content]', NOW())";

       // 開始執行查詢
       mysql_query($sql) || die('無法執行查詢: '.$sql);

       // 查詢執行成功,重導網頁位址到 index.php
       header('Location: index.php');
       exit;
}
?>
<form name="form1" method="post" action="">
  <table width="600" border="1" align="center" cellpadding="5" cellspacing="0" bordercolor="#9999FF">
    <tr bgcolor="#9999FF">
      <td colspan="2"><font color="#FFFFFF">新增留言</font></td>
    </tr>
    <tr>
      <td width="23%"><div align="right">姓名:</div></td>
      <td width="77%"><input name="name" type="text" id="name"></td>
    </tr>
    <tr>
      <td><p align="right">電子郵件信箱:</p></td>
      <td><input name="email" type="text" id="email"></td>
    </tr>
    <tr>
      <td><div align="right">網站:</div></td>
      <td><input name="web" type="text" id="web"></td>
    </tr>
    <tr>
      <td valign="top"><div align="right">內容:</div></td>
      <td><textarea name="content" cols="48" rows="5" id="content"></textarea></td>
    </tr>
    <tr>
      <td colspan="2"><div align="center">
          <input type="submit" name="Submit" value="送    出">
        </div></td>
    </tr>
  </table>
</form>

四、更新留言

說明:

首先,必須先取得使用者所要更新資料的流水號。然後,使用 UPDATE 語法,將使用者填入表單的資料,更新到資料庫中。

程式碼:

QUOTE:
<?php

/* 定義連接資料庫的有關參數 */
define('DB_USER', 'lib13');
define('DB_PASSWORD', 'mypassword');
define('DB_HOST', 'localhost');
define('DB_DATABASE', 'lib13');

/* 連接資料庫 */
$link = mysql_pconnect(DB_HOST, DB_USER, DB_PASSWORD)
              or die('無法連接到資料庫:'.mysql_error());

/* 選用資料庫 */
mysql_select_db(DB_DATABASE)
              or die('無法選擇資料庫['.DB_DATABASE.']:'.mysql_error());              

/* 檢查使用者是否按下送出的按鈕
       如果是的話,執行更新查詢;
       否則,取出使用者所要更新的留言資料。 */

if(isset($_POST[Submit])){

       /* 執行查詢 */

       // 定義 SQL 命令的字串變數
       $sql = "UPDATE Guestbook SET name='$_POST[name]', email='$_POST[email]', web='$_POST[web]', content='$_POST[content]' WHERE id=$_GET[id]";

       // 開始執行查詢
       mysql_query($sql) || die('無法執行查詢: '.$sql);

       // 查詢執行成功,重導網頁位址到 index.php
       header('Location: index.php');
       exit;
}else{
       $sql = 'SELECT * FROM Guestbook WHERE id='.$_GET[id];
       $result = mysql_query($sql);
       $result || die('無法執行查詢: '.$sql);
       $record = mysql_fetch_array($result);
}
?>
<form name="form1" method="post" action="">
  <table width="600" border="1" align="center" cellpadding="5" cellspacing="0" bordercolor="#9999FF">
    <tr bgcolor="#9999FF">
      <td colspan="2"><font color="#FFFFFF">更新留言</font></td>
    </tr>
    <tr>
      <td width="23%"><div align="right">姓名:</div></td>
      <td width="77%"><input name="name" type="text" id="name" value=<?php echo $record[name];?>></td>
    </tr>
    <tr>
      <td><p align="right">電子郵件信箱:</p></td>
      <td><input name="email" type="text" id="email" value=<?php echo $record[email];?>></td>
    </tr>
    <tr>
      <td><div align="right">網站:</div></td>
      <td><input name="web" type="text" id="web" value=<?php echo $record[web];?>></td>
    </tr>
    <tr>
      <td valign="top"><div align="right">內容:</div></td>
      <td><textarea name="content" cols="48" rows="5" id="content"><?php echo $record[content];?></textarea></td>
    </tr>
    <tr>
      <td colspan="2"><div align="center">
          <input type="submit" name="Submit" value="送    出">
        </div></td>
    </tr>
  </table>
</form>

五、刪除留言

說明:

首先,必須先取得使用者所要更新資料的流水號。然後,使用 DELETE 語法,將使用者選取的留言,從資料庫中刪除。

程式碼:

QUOTE:
<?php

/* 定義連接資料庫的有關參數 */
define('DB_USER', 'lib13');
define('DB_PASSWORD', 'mypassword');
define('DB_HOST', 'localhost');
define('DB_DATABASE', 'lib13');

/* 連接資料庫 */
$link = mysql_pconnect(DB_HOST, DB_USER, DB_PASSWORD)
              or die('無法連接到資料庫:'.mysql_error());

/* 選用資料庫 */
mysql_select_db(DB_DATABASE)
              or die('無法選擇資料庫['.DB_DATABASE.']:'.mysql_error());              

/* 檢查使用者是否按下送出的按鈕
       如果是的話,執行更新查詢;
       否則,取出使用者所要更新的留言資料。 */

if(isset($_POST[Submit])){

       /* 執行查詢 */

       // 定義 SQL 命令的字串變數
       $sql = "DELETE FROM Guestbook WHERE id=$_GET[id]";

       // 開始執行查詢
       mysql_query($sql) || die('無法執行查詢: '.$sql);

       // 查詢執行成功,重導網頁位址到 index.php
       header('Location: index.php');
       exit;
}else{
       $sql = 'SELECT * FROM Guestbook WHERE id='.$_GET[id];
       $result = mysql_query($sql);
       $result || die('無法執行查詢: '.$sql);
       $record = mysql_fetch_array($result);
}
?>
<form name="form1" method="post" action="">
  <table width="600" border="1" align="center" cellpadding="5" cellspacing="0" bordercolor="#9999FF">
    <tr bgcolor="#9999FF">
      <td colspan="2"><font color="#FFFFFF">更新留言</font></td>
    </tr>
    <tr>
      <td width="23%"><div align="right">姓名:</div></td>
      <td width="77%"><?php echo $record[name];?></td>
    </tr>
    <tr>
      <td><p align="right">電子郵件信箱:</p></td>
      <td><?php echo $record[email];?></td>
    </tr>
    <tr>
      <td><div align="right">網站:</div></td>
      <td><?php echo $record[web];?></td>
    </tr>
    <tr>
      <td valign="top"><div align="right">內容:</div></td>
      <td><?php echo $record[content];?></td>
    </tr>
    <tr>
      <td colspan="2"><div align="center">
          <input type="submit" name="Submit" value="刪    除">
        </div></td>
    </tr>
  </table>
</form>

好,又一課了。快去第八課吧!  好!繼續課程! 撰寫資料庫網頁程式:
摘要:  在之前課程中,我們討論了使用 SQL 的語法,來管理資料庫裡面的資料。從這個單元開始,我們將實作留言版的專案,分別使用各種開發方式,來開發同樣的專案。讓學習者能學習各種不同的開發方式,藉由實地開發產生不同的體認。在這個單元中,我們將應用 SQL 語法,整合在 PHP網頁的程式之中。在這個課程中的每一頁 PHP 程式,都包含了完整的資料庫命令,專注在於每個資料庫作業的程式撰寫。等熟悉了資料庫網頁的撰寫方式之後,在以後單元中,將學習如何撰寫函式,將類似的功能分離出來,獨立成為個別的函式,並整合在函式庫中,供其他 PHP 程式使用。在之後的課程中,將介紹如何使用物件導向的方式,來重新改寫原本的程式。
留言版專案功能規範

說明:

為了教學上的目的,我們刻意忽略了一些實務上的功能需求,專注於學習資料庫程式的撰寫,以提高學習的效果。

留言版的功能規範如下:

   1. 簡單的權限控管:使用$PHP_AUTH_USER,$PHP_AUTH_PW全域變數
   2. 一個留言版列表的網頁:控管更新與刪除連結的呈現
   3. 一個新增留言的網頁
   4. 一個更新留言的網頁:存取控制
   5. 一個刪除留言的網頁:存取控制

在這個課程中,我們先專注於資料庫網頁的撰寫。在下一個課程中,再加入網頁存取控制的功能。

留言版的列表、新增、更新、以及刪除
一、準備工作

說明:

我們沿用之前的做法,把相關的網頁,放在同一個目錄之下。


實作:

   1. 使用putty連線到伺服主機。
   2. 輸入以下的命令,進入 public_html 目錄:
      cd public_html
   3. 輸入以下的命令,產生 guestbook 目錄:
      mkdir guestbook
   4. 輸入以下的命令,產生網頁程式的檔案:
      touch index.php add.php update.php delete.php

二、留言版列表

說明:

在這個部分,我們使用 SQL 的 SELECT 語法,取出 Guestbook 的所有資料,將每一筆記錄,以個別的表格呈現出來。
程式碼:

QUOTE:
<?php
/* 定義連接資料庫的有關參數 */
define('DB_USER', 'lib13');
define('DB_PASSWORD', 'mypassword');
define('DB_HOST', 'localhost');
define('DB_DATABASE', 'lib13');

/* 連接資料庫 */
$link = mysql_pconnect(DB_HOST, DB_USER, DB_PASSWORD)
       or die('無法連接到資料庫:'.mysql_error());

/* 選用資料庫 */
mysql_select_db(DB_DATABASE)
       or die('無法選擇資料庫['.DB_DATABASE.']:'.mysql_error());
      
/* 執行查詢 */

// 定義 SQL 命令的字串變數
$sql = 'SELECT * FROM Guestbook ORDER BY post_time DESC';

// 開始執行查詢
$result = mysql_query($sql);

/* 處理查詢結果 */
$output = '';
while($record = mysql_fetch_array($result)){
       $record[email] = strlen(trim($record[email])) > 0?'<a href=mailto:'.$record[email].'><img src=email.gif border=0></a>':' ';
       $record[web] = strlen(trim($record[web])) > 0?'<a href=http://'.$record[web].' target=_blank><img src=home.gif border=0></a>' :' ';
       $record[content] = nl2br($record[content]);
       $table=<<<EOF
<table width="600" border="1" cellpadding="0" cellspacing="0" bordercolor="#9999FF" align="center">
       <tr bgcolor="#9999FF">
               <td width="35%"><font color="#FFFFFF">$record[name]:</font></td>
                <td width="12%"><div align="center"><font color="#FFFFFF">$record[email]</font></div></td>
                <td width="11%"><div align="center"><font color="#FFFFFF">$record[web]</font></div></td>
                <td width="42%"><div align="right"><font color="#FFFFFF">$record[post_time]</font></div></td>
       </tr>
       <tr valign="top">
               <td height="120" colspan="4">$record[content]</td>
    </tr>
       <tr>
              <td colspan=2><div align="center"><a href="delete.php?id=$record[id]">刪除</a></div></td>
              <td colspan=2><div align="center"><a href="update.php?id=$record[id]">更新</a></div></td>
       </tr>
</table>
<hr width=600 size=1 />
EOF;
       $output .= $table;
}

/* 列印輸出 */
echo <<<EOF
<center>
<hr width=600 size=1 />留言版<hr width=600 size=1 />
<a href="add.php">我要留言<a><hr width=600 size=1 />
</center>
$output
EOF;
?>

三、新增留言

說明:

使用資料庫網頁,要新增一筆記錄時,使用 INSERT 語法,將使用者填入表單的資料,新增到資料庫中。

程式碼:

QUOTE:
<?php
/* 檢查使用者是否按下送出的按鈕
       如果是的話,執行以下的程式;
       否則,顯示以下的表單。 */

if(isset($_POST[Submit])){
       /* 定義連接資料庫的有關參數 */
       define('DB_USER', 'lib13');
       define('DB_PASSWORD', 'mypassword');
       define('DB_HOST', 'localhost');
       define('DB_DATABASE', 'lib13');

       /* 連接資料庫 */
       $link = mysql_pconnect(DB_HOST, DB_USER, DB_PASSWORD)
              or die('無法連接到資料庫:'.mysql_error());

       /* 選用資料庫 */
       mysql_select_db(DB_DATABASE)
              or die('無法選擇資料庫['.DB_DATABASE.']:'.mysql_error());
              
       /* 執行查詢 */

       // 定義 SQL 命令的字串變數
       $sql = "INSERT INTO Guestbook(name, email, web, content, post_time) VALUES('$_POST[name]', '$_POST[email]', '$_POST[web]', '$_POST[content]', NOW())";

       // 開始執行查詢
       mysql_query($sql) || die('無法執行查詢: '.$sql);

       // 查詢執行成功,重導網頁位址到 index.php
       header('Location: index.php');
       exit;
}
?>
<form name="form1" method="post" action="">
  <table width="600" border="1" align="center" cellpadding="5" cellspacing="0" bordercolor="#9999FF">
    <tr bgcolor="#9999FF">
      <td colspan="2"><font color="#FFFFFF">新增留言</font></td>
    </tr>
    <tr>
      <td width="23%"><div align="right">姓名:</div></td>
      <td width="77%"><input name="name" type="text" id="name"></td>
    </tr>
    <tr>
      <td><p align="right">電子郵件信箱:</p></td>
      <td><input name="email" type="text" id="email"></td>
    </tr>
    <tr>
      <td><div align="right">網站:</div></td>
      <td><input name="web" type="text" id="web"></td>
    </tr>
    <tr>
      <td valign="top"><div align="right">內容:</div></td>
      <td><textarea name="content" cols="48" rows="5" id="content"></textarea></td>
    </tr>
    <tr>
      <td colspan="2"><div align="center">
          <input type="submit" name="Submit" value="送    出">
        </div></td>
    </tr>
  </table>
</form>

四、更新留言

說明:

首先,必須先取得使用者所要更新資料的流水號。然後,使用 UPDATE 語法,將使用者填入表單的資料,更新到資料庫中。

程式碼:

QUOTE:
<?php

/* 定義連接資料庫的有關參數 */
define('DB_USER', 'lib13');
define('DB_PASSWORD', 'mypassword');
define('DB_HOST', 'localhost');
define('DB_DATABASE', 'lib13');

/* 連接資料庫 */
$link = mysql_pconnect(DB_HOST, DB_USER, DB_PASSWORD)
              or die('無法連接到資料庫:'.mysql_error());

/* 選用資料庫 */
mysql_select_db(DB_DATABASE)
              or die('無法選擇資料庫['.DB_DATABASE.']:'.mysql_error());              

/* 檢查使用者是否按下送出的按鈕
       如果是的話,執行更新查詢;
       否則,取出使用者所要更新的留言資料。 */

if(isset($_POST[Submit])){

       /* 執行查詢 */

       // 定義 SQL 命令的字串變數
       $sql = "UPDATE Guestbook SET name='$_POST[name]', email='$_POST[email]', web='$_POST[web]', content='$_POST[content]' WHERE id=$_GET[id]";

       // 開始執行查詢
       mysql_query($sql) || die('無法執行查詢: '.$sql);

       // 查詢執行成功,重導網頁位址到 index.php
       header('Location: index.php');
       exit;
}else{
       $sql = 'SELECT * FROM Guestbook WHERE id='.$_GET[id];
       $result = mysql_query($sql);
       $result || die('無法執行查詢: '.$sql);
       $record = mysql_fetch_array($result);
}
?>
<form name="form1" method="post" action="">
  <table width="600" border="1" align="center" cellpadding="5" cellspacing="0" bordercolor="#9999FF">
    <tr bgcolor="#9999FF">
      <td colspan="2"><font color="#FFFFFF">更新留言</font></td>
    </tr>
    <tr>
      <td width="23%"><div align="right">姓名:</div></td>
      <td width="77%"><input name="name" type="text" id="name" value=<?php echo $record[name];?>></td>
    </tr>
    <tr>
      <td><p align="right">電子郵件信箱:</p></td>
      <td><input name="email" type="text" id="email" value=<?php echo $record[email];?>></td>
    </tr>
    <tr>
      <td><div align="right">網站:</div></td>
      <td><input name="web" type="text" id="web" value=<?php echo $record[web];?>></td>
    </tr>
    <tr>
      <td valign="top"><div align="right">內容:</div></td>
      <td><textarea name="content" cols="48" rows="5" id="content"><?php echo $record[content];?></textarea></td>
    </tr>
    <tr>
      <td colspan="2"><div align="center">
          <input type="submit" name="Submit" value="送    出">
        </div></td>
    </tr>
  </table>
</form>

五、刪除留言

說明:

首先,必須先取得使用者所要更新資料的流水號。然後,使用 DELETE 語法,將使用者選取的留言,從資料庫中刪除。

程式碼:

QUOTE:
<?php

/* 定義連接資料庫的有關參數 */
define('DB_USER', 'lib13');
define('DB_PASSWORD', 'mypassword');
define('DB_HOST', 'localhost');
define('DB_DATABASE', 'lib13');

/* 連接資料庫 */
$link = mysql_pconnect(DB_HOST, DB_USER, DB_PASSWORD)
              or die('無法連接到資料庫:'.mysql_error());

/* 選用資料庫 */
mysql_select_db(DB_DATABASE)
              or die('無法選擇資料庫['.DB_DATABASE.']:'.mysql_error());              

/* 檢查使用者是否按下送出的按鈕
       如果是的話,執行更新查詢;
       否則,取出使用者所要更新的留言資料。 */

if(isset($_POST[Submit])){

       /* 執行查詢 */

       // 定義 SQL 命令的字串變數
       $sql = "DELETE FROM Guestbook WHERE id=$_GET[id]";

       // 開始執行查詢
       mysql_query($sql) || die('無法執行查詢: '.$sql);

       // 查詢執行成功,重導網頁位址到 index.php
       header('Location: index.php');
       exit;
}else{
       $sql = 'SELECT * FROM Guestbook WHERE id='.$_GET[id];
       $result = mysql_query($sql);
       $result || die('無法執行查詢: '.$sql);
       $record = mysql_fetch_array($result);
}
?>
<form name="form1" method="post" action="">
  <table width="600" border="1" align="center" cellpadding="5" cellspacing="0" bordercolor="#9999FF">
    <tr bgcolor="#9999FF">
      <td colspan="2"><font color="#FFFFFF">更新留言</font></td>
    </tr>
    <tr>
      <td width="23%"><div align="right">姓名:</div></td>
      <td width="77%"><?php echo $record[name];?></td>
    </tr>
    <tr>
      <td><p align="right">電子郵件信箱:</p></td>
      <td><?php echo $record[email];?></td>
    </tr>
    <tr>
      <td><div align="right">網站:</div></td>
      <td><?php echo $record[web];?></td>
    </tr>
    <tr>
      <td valign="top"><div align="right">內容:</div></td>
      <td><?php echo $record[content];?></td>
    </tr>
    <tr>
      <td colspan="2"><div align="center">
          <input type="submit" name="Submit" value="刪    除">
        </div></td>
    </tr>
  </table>
</form>

好,又一課了。快去第八課吧!

PHP教學 第八回

加入網頁存取控制:
摘要: 在這個課程中,我們使用 header的 WWW-Authenticate 驗證方式,取得使用者名稱與密碼。透過檢查使用者的$PHP_AUTH_USER,$PHP_AUTH_PW全域變數,我們可以知道使用者是否輸入正確的使用者名稱與密碼,再決定是否授權存取頁面。等我們學會了這個技巧之後,再把這個驗證的技巧,整合在之前的資料庫網頁。
驗證功能

說明:

使用 header 函式傳遞 WWW-Authenticate給瀏覽器時,瀏覽器會顯示一個要求輸入使用者名稱與密碼的對話方塊。當使用者輸入資料時,PHP 就會將使用者所輸入的使用者名稱,放到$PHP_AUTH_USER這個全域變數中,把密碼放到$PHP_AUTH_PW這個全域變數中。之後需要存取控制的網頁,只要檢查,這兩個全域變數,便可以得知,使用者是否輸入正確的使用者名稱與密碼。

程式碼:

QUOTE:
<?php

/*       檢查使用者是否有輸入,使用者名稱與密碼。
       如果使用者沒有輸入正確的使用者名稱和密碼,就顯示存取遭拒的訊息。
       否則,顯示使用者所輸入的使用者名稱與密碼。*/

if ($PHP_AUTH_USER!="hello" || $PHP_AUTH_PW!="world") {

    header( 'WWW-Authenticate: Basic realm="留言版系統管理"' );       // 送出驗證的檔頭資訊
    echo '存取遭拒.';                                                                                    // 顯示存取遭拒的文字訊息
    exit;

} else {
       echo "驗證成功!<BR>";
    echo "你輸入的使用者名稱是: $PHP_AUTH_USER<BR>";
    echo "你輸入的密碼是: $PHP_AUTH_PW<BR>";
}

?>

將驗證功能整合到留言版的網頁

說明:

留言版需要整合驗證功能的頁面如下:

   1. 留言版更新
   2. 留言版刪除
   3. 留言版列表

一、準備工作

說明:

將之前108課程所做好的PHP程式,放在另一個新的目錄 guestbook109 之下。然後,撰寫一個 authenticate.php 負責提示及驗證使用者的名稱,其他的程式則以 include()函式,將這個檔案含括在程式中即可。


複製檔案:

   1. 使用putty連線到伺服主機。
   2. 輸入以下的命令,進入 public_html 目錄:
      cd public_html
   3. 輸入以下的命令,產生新的目錄 guestbook109,並將 guestbook 中所有檔案,複製到guestbook109:
      cp -r guestbook guestbook109

撰寫 authenticate.php

將下面的PHP程式碼存成 authenticate.php:

QUOTE:
<?php
if ($PHP_AUTH_USER!="admin" || $PHP_AUTH_PW!="password") {

header( 'WWW-Authenticate: Basic realm="留言版系統管理"' );
echo '存取遭拒.';
exit;
}
?>

二、修改更新留言

說明:

在這裡我們只要使用 include()函式,將 authenticate.php 含括在程式中即可。

QUOTE:
<?php

/* 定義連接資料庫的有關參數 */
define('DB_USER', 'lib13');
define('DB_PASSWORD', 'mypassword');
define('DB_HOST', 'localhost');
define('DB_DATABASE', 'lib13');

/* 連接資料庫 */
$link = mysql_pconnect(DB_HOST, DB_USER, DB_PASSWORD)
              or die('無法連接到資料庫:'.mysql_error());

/* 選用資料庫 */
mysql_select_db(DB_DATABASE)
              or die('無法選擇資料庫['.DB_DATABASE.']:'.mysql_error());              

/* 檢查使用者是否按下送出的按鈕
       如果是的話,執行更新查詢;
       否則,取出使用者所要更新的留言資料。 */

if(isset($_POST[Submit])){

       /* 執行查詢 */

       // 定義 SQL 命令的字串變數
       $sql = "UPDATE Guestbook SET name='$_POST[name]', email='$_POST[email]', web='$_POST[web]', content='$_POST[content]' WHERE id=$_GET[id]";

       // 開始執行查詢
       mysql_query($sql) || die('無法執行查詢: '.$sql);

       // 查詢執行成功,重導網頁位址到 index.php
       header('Location: index.php');
       exit;
}else{
       $sql = 'SELECT * FROM Guestbook WHERE id='.$_GET[id];
       $result = mysql_query($sql);
       $result || die('無法執行查詢: '.$sql);
       $record = mysql_fetch_array($result);
}
?>
<form name="form1" method="post" action="">
  <table width="600" border="1" align="center" cellpadding="5" cellspacing="0" bordercolor="#9999FF">
    <tr bgcolor="#9999FF">
      <td colspan="2"><font color="#FFFFFF">更新留言</font></td>
    </tr>
    <tr>
      <td width="23%"><div align="right">姓名:</div></td>
      <td width="77%"><input name="name" type="text" id="name" value=<?php echo $record[name];?>></td>
    </tr>
    <tr>
      <td><p align="right">電子郵件信箱:</p></td>
      <td><input name="email" type="text" id="email" value=<?php echo $record[email];?>></td>
    </tr>
    <tr>
      <td><div align="right">網站:</div></td>
      <td><input name="web" type="text" id="web" value=<?php echo $record[web];?>></td>
    </tr>
    <tr>
      <td valign="top"><div align="right">內容:</div></td>
      <td><textarea name="content" cols="48" rows="5" id="content"><?php echo $record[content];?></textarea></td>
    </tr>
    <tr>
      <td colspan="2"><div align="center">
          <input type="submit" name="Submit" value="送    出">
        </div></td>
    </tr>
  </table>
</form>

三、修改刪除留言

說明:

在這裡我們只要使用 include()函式,將 authenticate.php 含括在程式中即可。

程式碼:

QUOTE:
<?php

/* 定義連接資料庫的有關參數 */
define('DB_USER', 'lib13');
define('DB_PASSWORD', 'mypassword');
define('DB_HOST', 'localhost');
define('DB_DATABASE', 'lib13');

/* 連接資料庫 */
$link = mysql_pconnect(DB_HOST, DB_USER, DB_PASSWORD)
              or die('無法連接到資料庫:'.mysql_error());

/* 選用資料庫 */
mysql_select_db(DB_DATABASE)
              or die('無法選擇資料庫['.DB_DATABASE.']:'.mysql_error());              

/* 檢查使用者是否按下送出的按鈕
       如果是的話,執行更新查詢;
       否則,取出使用者所要更新的留言資料。 */

if(isset($_POST[Submit])){

       /* 執行查詢 */

       // 定義 SQL 命令的字串變數
       $sql = "DELETE FROM Guestbook WHERE id=$_GET[id]";

       // 開始執行查詢
       mysql_query($sql) || die('無法執行查詢: '.$sql);

       // 查詢執行成功,重導網頁位址到 index.php
       header('Location: index.php');
       exit;
}else{
       $sql = 'SELECT * FROM Guestbook WHERE id='.$_GET[id];
       $result = mysql_query($sql);
       $result || die('無法執行查詢: '.$sql);
       $record = mysql_fetch_array($result);
}
?>
<form name="form1" method="post" action="">
  <table width="600" border="1" align="center" cellpadding="5" cellspacing="0" bordercolor="#9999FF">
    <tr bgcolor="#9999FF">
      <td colspan="2"><font color="#FFFFFF">更新留言</font></td>
    </tr>
    <tr>
      <td width="23%"><div align="right">姓名:</div></td>
      <td width="77%"><?php echo $record[name];?></td>
    </tr>
    <tr>
      <td><p align="right">電子郵件信箱:</p></td>
      <td><?php echo $record[email];?></td>
    </tr>
    <tr>
      <td><div align="right">網站:</div></td>
      <td><?php echo $record[web];?></td>
    </tr>
    <tr>
      <td valign="top"><div align="right">內容:</div></td>
      <td><?php echo $record[content];?></td>
    </tr>
    <tr>
      <td colspan="2"><div align="center">
          <input type="submit" name="Submit" value="刪    除">
        </div></td>
    </tr>
  </table>
</form>

四、修改留言列表

說明:

留言列表的要求,不同於更新與刪除留言。一般使用者可以直接存取這個網頁,但是,網頁中的更新與刪除的文字連結,必須在輸入正確使用者名稱和密碼才可以顯示。我們可以使用檢查$PHP_AUTH_USER,以及$PHP_AUTH_PW全域變數的方式,來判斷是否要顯示更新與刪除的連結。

程式碼:

QUOTE:
<?php
/* 定義連接資料庫的有關參數 */
define('DB_USER', 'lib13');
define('DB_PASSWORD', 'mypassword');
define('DB_HOST', 'localhost');
define('DB_DATABASE', 'lib13');

/* 連接資料庫 */
$link = mysql_pconnect(DB_HOST, DB_USER, DB_PASSWORD)
       or die('無法連接到資料庫:'.mysql_error());

/* 選用資料庫 */
mysql_select_db(DB_DATABASE)
       or die('無法選擇資料庫['.DB_DATABASE.']:'.mysql_error());
      
/* 執行查詢 */

// 定義 SQL 命令的字串變數
$sql = 'SELECT * FROM Guestbook ORDER BY post_time DESC';

// 開始執行查詢
$result = mysql_query($sql);

/* 處理查詢結果 */
$output = '';
while($record = mysql_fetch_array($result)){
       $record[email] = strlen(trim($record[email])) > 0?'<a href=mailto:'.$record[email].'><img src=email.gif border=0></a>':' ';
       $record[web] = strlen(trim($record[web])) > 0?'<a href=http://'.$record[web].' target=_blank><img src=home.gif border=0></a>' :' ';
       $record[content] = nl2br($record[content]);

       /*** 加入以下的程式碼 ***/
       if ($PHP_AUTH_USER=="admin" & $PHP_AUTH_PW=="password") {
              $admin=<<<ADMIN
       <tr>
              <td colspan=2><div align="center"><a href="delete.php?id=$record[id]">刪除</a></div></td>
              <td colspan=2><div align="center"><a href="update.php?id=$record[id]">更新</a></div></td>
       </tr>
ADMIN;
       }else{
              $admin = "";
       }
       /*** 然後在下面把原來的 tr 改成 $admin變數 ***/

       $table=<<<EOF
<table width="600" border="1" cellpadding="0" cellspacing="0" bordercolor="#9999FF" align="center">
       <tr bgcolor="#9999FF">
               <td width="35%"><font color="#FFFFFF">$record[name]:</font></td>
                <td width="12%"><div align="center"><font color="#FFFFFF">$record[email]</font></div></td>
                <td width="11%"><div align="center"><font color="#FFFFFF">$record[web]</font></div></td>
                <td width="42%"><div align="right"><font color="#FFFFFF">$record[post_time]</font></div></td>
       </tr>
       <tr valign="top">
               <td height="120" colspan="4">$record[content]</td>
    </tr>
       $admin
</table>
<hr width=600 size=1 />
EOF;
       $output .= $table;
}

/* 列印輸出 */
echo <<<EOF
<center>
<hr width=600 size=1 />留言版<hr width=600 size=1 />
<a href="add.php">我要留言<a><hr width=600 size=1 />
</center>
$output
EOF;
?>

五、加入登入的網頁

說明:

之前的留言列表更改之後,輸入正確使用者名稱及密碼後,可以看到更新與刪除的連結,沒輸入時,則隱藏更新與刪除的連結。

但是,反而造成了另一個問題。就是沒有登入的入口點。所以我們要另作一個 PHP 程式(login.php),作為我們登入的入口。

程式碼:

QUOTE:
<?php
include("authenticate.php");
header("Location: index.php");
?>

第九課會提及Function的應用,請留意啦!

PHP教學 第九回

函式的應用
在第七課撰寫資料庫網頁程式中,在各個網頁程式裡使用了大量相同的程式碼。程式開發者,在開發應用程式的過程當中,如果有碰到《似曾相識》的感覺時,就必須要有重新調整程式結構的警覺。將類似的程式碼,從原本的程式碼中抽離出來,按照功能,獨立成為一個功能模組,避免重複撰寫相同功能的程式碼。模組化的方式有兩種:一、自訂函式;二、物件導向。在這個課程我們先討論如何撰寫自訂的函式,讓程式模組化。然後,改寫原先的資料庫網頁程式。在下個課程中,我們將討論物件導向程式設計。
函式

說明:

函式,是一個獨立的程式碼區段,只需撰寫一次,就可以讓程式的其他部分,藉由呼叫函式的方式,重複使用。通常,函式會接受參數,執行特定的功能,傳回程式執行的結果。藉由使用函式,可以節省你的程式開發時間,以及減少程式的臭蟲,提高程式的可維護性。

但是,光是把程式碼,寫成函式,並不會讓你的程式變得更好,或是讓你的工作變得更輕鬆。你必須學習養成如何撰寫好的函式。好的函式,通常有以下的特質:

   1. 最好不超過一頁:太長的函式,通常不好維護,而且容易發生錯誤。
   2. 函式只執行一個特定的功能:如果,在一個函式裡面,執行多個功能時,通常必須把各功能,再切割成獨立的函式。這樣,才可以更模組化,在主程式組合這些功能時,能更有彈性。
   3. 好的函式,會有好名字:如果,你無法替你的函式,找出一個好名字的話,通常代表,你對函式的功能,沒有具體的認知。自然無法寫出好的函式。

在這一節中,我們使用範例,來學習如何撰寫函式:

   1. 函式的語法。
   2. 參數傳遞。
   3. 預設參數。
   4. 函式內變數的範圍。
   5. 使用 include()函式,來建立自己的函式庫。

一、函式的語法

function 函式名稱([參數1, 參數2, ...參數n]){

    程式碼

}

說明:

   1. 撰寫函式時,在 function保留字之後,接著是使用者自己命名的函式名稱。函式名稱之後,是由括弧所包含的是要交給函式處理的參數。視情況需要,函式可以接受任何數目的參數,包括不接受任何參數。之後,是由 { 和 }所包含的程式區段。
   2. 函式的執行:在主程式呼叫函式之後,自 { 開始由上而下的順序,一直執行到 }為止或碰到 return 的命令句時結束。
   3. return 可以用來結束函式的執行,return 後面如果有接任何運算式,則會將運算式所得的結果,傳回給主程式。

範例:無參數,無回傳值

程式碼:

QUOTE:
<?php

function today(){      
     $ty = date("Y") - 1911;
     echo '民國 '.$ty.'年'.date("m月d日");
}


today();

?>

範例:無參數,有回傳值

程式碼:

QUOTE:
<?php

function today(){
     $ty = date("Y") - 1911;
     return'民國 '.$ty.'年'.date("m月d日");
}

echo today();

?>

範例:有參數,有回傳值

程式碼:

QUOTE:
<?php

function numberOptions($start, $end, $selected){
     $option = "";
     for($i = $start; $i <= $end; $i++){
          $list .= "<option value='$i'";
          if($i==$selected){
          $list .= " SELECTED";
          }
          $list .=">$i</option>";
     }
     return $list;
}
$yr = date('Y') - 1911;
$yr_start = $yr - 5;
$yr_end = $yr + 5;
$mn = date('m');
$dy = date('d');
$yr_option = numberOptions($yr_start, $yr_end, $yr);
$mn_option = numberOptions(1, 12, $mn);
$dy_option = numberOptions(1, 31, $dy);
?>
民國 <select name=year><?php echo $yr_option; ?></select>年
<select name=month><?php echo $mn_option; ?></select>月
<select name=day><?php echo $dy_option; ?></select>日[/qoute]

二、參數傳遞

說明:

當其他部分的程式碼,呼叫函式,以變數當作參數,傳遞給函式時,實際上函式所接受到的是這個變數的值,所以,在函式中的程式碼,如果更改這個變數時,並不會影響到原本程式中的變數。這種參數的傳遞方式,稱之為值的傳遞。

另一種參數傳遞的方式,稱之為參照的傳遞。使用這種方式傳遞參數給函式處理時,當函式更改參數的值,原本程式的變數值也會跟著改變。使用參照傳遞方式,在函式的定義中,參數之前必須加上 符號。其他程式,呼叫這個函式時,必須在這個參數使用變數,不可以是其他的運算式(如:常數、定數)。
範例:參照傳遞

程式碼:

[qoute]<?php

function add_by_value($value, $increment){
     $value += $increment;
}

function add_by_reference($value, $increment){
     $value += $increment;
}

$n = 100;
$i = 50;

echo '原本 n 的值: '.$n.'<br />';

add_by_value($n, $i);
echo '值傳遞之後 n 的值: '.$n.'<br />';

add_by_reference($n, $i);
echo '參照傳遞之後 n 的值: '.$n.'<br />';

?>

三、預設參數

說明:

函式使用預設參數時,呼叫函式的程式,可以不需要提供這個參數,而使用函式中所定義的參數預設值。

使用預設參數時,預設參數必須放在非預設參數的後面(右邊)。
範例:預設參數

程式碼:

QUOTE:
<?php

function numberOptions($start, $end, $selected=3){
     $option = "";
     for($i = $start; $i <= $end; $i++){
          $list .= "<option value='$i'";
          if($i==$selected){
               $list .= " SELECTED";
          }
          $list .=">$i</option>";
     }
     return $list;
}

$number_options = numberOptions(1, 10);
?>
<select name=number><?php echo $number_options; ?></select>

四、函式內變數的範圍

說明:

函式內所使用的變數,除非特別指定,均為區域變數。區域變數的範圍,只限定在定義這個變數的函式內。函式外即使有同名的變數,因為範圍不同,所以是另一個變數。兩者不會互相影響。

如果,在函式之內有特別指定變數範圍(在變數名稱之前,加上 global 保留字)。變數變成全域變數。
範例:區域變數及全域變數

程式碼:

QUOTE:
<?php
function local_scope(){
     $x = 5;
}

function global_scope(){
     global $x;
     $x = 10;
}

$x = 0;
echo '原本 x 的值: '.$x.'<br />';

local_scope();
echo '呼叫 local_scope()函式之後, x 的值: '.$x.'<br />';

global_scope();
echo '呼叫 global_scope()函式之後, x 的值: '.$x.'<br />';
?>

五、使用 include()函式,來建立自己的函式庫

說明:

到目前為止,所有的函式,都是寫在和主程式同一個網頁中,所以,只有這個主程式的網頁可以呼叫這些函式。

更好的做法,是把所有函式按照功能的類別,寫在同一個檔案。然後,在主程式中,使用 include() 或 include_once() 函式,將函式的檔案,含括在主程式中。透過含括檔案的方式,就可以把函式的功能,提供給其他的PHP網頁程式使用。
範例:使用含括檔案的方式

程式碼:

QUOTE:
<?php
// 檔名: 110_07.php
function numberOptions($start, $end, $selected){
     $option = "";
     for($i = $start; $i <= $end; $i++){
          $list .= "<option value='$i'";
          if($i==$selected){
               $list .= " SELECTED";
          }
               $list .=">$i</option>";
     }
     return $list;
}
?>

<?php
// 檔名: 110_08.php
include("110_07.php");
$yr = date('Y') - 1911;
$yr_start = $yr - 5;
$yr_end = $yr + 5;
$mn = date('m');
$dy = date('d');
$yr_option = numberOptions($yr_start, $yr_end, $yr);
$mn_option = numberOptions(1, 12, $mn);
?>
民國 <select name=year><?php echo $yr_option; ?></select>年
<select name=month><?php echo $mn_option; ?></select>月
<select name=day><?php echo $dy_option; ?></select>日

將函式應用在留言版的資料庫網頁

說明:

在這一節當中,我們將原本資料庫中的程式碼,按照功能,將程式碼自原本的程式中抽離,獨立成為個別的函式。

我們按照以下的步驟,來修改留言版的程式:

   1. 準備工作
   2. 產生設定檔:config.php
   3. 產生資料庫函式檔:db.php
   4. 產生留言版函式檔:guestbook.php
   5. 修改原本的程式: index.php, add.php, update.php, delete.php

一、準備工作

說明:

將之前一課程所做好的PHP程式,放在另一個新的目錄 guestbook110 之下。
複製檔案:

   1. 使用putty連線到伺服主機。
   2. 輸入以下的命令,進入 public_html 目錄:
      cd public_html
   3. 輸入以下的命令,產生新的目錄 guestbook110,並將 guestbook109 中所有檔案,
      複製到guestbook110:
      cp -r guestbook109 guestbook110

二、產生設定檔:config.php

說明:

在 config.php 中,我們定義一些有關網站設定的一些變數的資料,方便網站的管理者,修改程式的設定。

程式碼:

QUOTE:
<?php
/*
檔名: config.php
*/

/* 定義連接資料庫的有關參數 */
$DB_USER = 'lib13';
$DB_PASSWORD = 'mypassword';
$DB_HOST = 'localhost';
$DB_DATABASE = 'lib13';
?>[/qoute]

三、產生資料庫函式檔:db.php

說明:

在 db.php 檔案中,我們定義資料庫的初始化函式 db_init() ,供網站中所有需要存取資料庫的 PHP 程式使用。任何有關存取這個資料庫的相關功能的函式,都可以在這個檔案中定義。

程式碼:

[quote]<?php
/*
檔名: db.php
目的: 存放跟整個資料庫操作有關的各函式
*/

include_once("config.php");

function db_init(){
     //使用全域變數
     global $DB_HOST;
     global $DB_USER;
     global $DB_PASSWORD;
     global $DB_DATABASE;

     /* 連接資料庫 */
     $link = mysql_pconnect($DB_HOST, $DB_USER, $DB_PASSWORD)
          or die('無法連接到資料庫:'.mysql_error());

     /* 選用資料庫 */
     mysql_select_db($DB_DATABASE)
          or die('無法選擇資料庫['.$DB_DATABASE.']:'.mysql_error());
}
?>

四、產生留言版函式檔:guestbook.php

說明:

guestbook.php 這個檔案,定義了所有跟留言版有關的資料庫操作功能的函式。其他程式要存取有關留言版的資料,只要呼叫這個檔案中的函式即可。

程式碼:

QUOTE:
<?php
/*
檔名: guestbook.php
目的: 存放跟操作留言版各類功能有關的函式
*/

include_once("db.php");

// 呼叫 db.php 檔案中的 db_init()函式來初始化資料庫
db_init();

function getRecordset(){
     // 宣告一個陣列變數 $recordset, 存放查詢所得的紀錄集
     $recordset = array();

     // 定義 SQL 命令的字串變數
     $sql = 'SELECT * FROM Guestbook ORDER BY post_time DESC';

     // 傳回查詢結果
     $result = mysql_query($sql);
     if(!$result) die ('無法執行查詢: '.$sql);
     while($record = mysql_fetch_assoc($result)){
          array_push($recordset, $record);
     }
     return $recordset;
}

function Add(){
     // 定義 SQL 命令的字串變數
     $sql = "INSERT INTO Guestbook(name, email, web, content, post_time)";
     $sql .= " VALUES('$_POST[name]', '$_POST[email]', '$_POST[web]', ";
     $sql .= "'$_POST[content]', NOW())";

     // 執行查詢
     return mysql_query($sql);
}

function Retrieve(){

     // 定義 SQL 命令的字串變數
     $sql = 'SELECT * FROM Guestbook WHERE id='.$_GET[id];


     // 執行查詢
     $result = mysql_query($sql);
     if(!$result) die('執行查詢錯誤: '.$sql);
     return mysql_fetch_assoc($result);
}

function Update(){
     // 定義 SQL 命令的字串變數
     $sql = "UPDATE Guestbook SET name='$_POST[name]', email='$_POST[email]', ";
     $sql.= "web='$_POST[web]', content='$_POST[content]' WHERE id=$_GET[id]";
     // 執行查詢
     return mysql_query($sql);
}

function Delete(){
     // 定義 SQL 命令的字串變數
     $sql = "DELETE FROM Guestbook WHERE id=".$_GET[id];
     // 執行查詢
     return mysql_query($sql);
}
?>

五、修改原本的程式: index.php, add.php, update.php, delete.php

說明:

在這裡,我們使用含括 guestbook.php檔案,並拿掉所有跟資料庫有關的程式碼。藉由呼叫 guestbook.php 當中所定義的函式,執行各網頁程式所需要的功能。

PHP教學 第十回

物件導向程式設計
摘要: 在這個課程中,我們將討論物件導向程式設計。首先,我們討論物件導向程式設計的觀念。接著,我們以實例來示範 PHP 物件導向程式設計的撰寫。然後,再把物件導向程式設計的方法,應用在留言版的程式中。
物件導向程式設計觀念

PHP 支援物件導向程式設計,雖然就純粹的物件導向程式設計的觀點來看,它的支援並不是很完整,但是,只要我們遵循良好的程式設計習慣,我們還是可以善用 PHP ,來開發物件導向的程式。

為什麼要使用物件導向的程式設計?

在物件導向程式設計的觀念提出之前,軟體開發者,大多是使用結構化的程式設計。所謂結構化的程式設計,就是把問題切割成各個比較小的問題,比較小的問題,如果還是複雜到無法以一個函式來解決時,就在切割成為更小的問題。直到可以用一個單一的函式來解決為止。每個函式處理個別的功能,主程式藉由呼叫各個函式,來完成他的工作。

在前一個課程函式的應用,我們應用了結構化的程式設計,將留言版的功能分割成各個函式,各網頁藉由呼叫各函式的方式,完成存取留言版資料的工作。使用結構化的程式設計,的確簡化了我們撰寫程式的工作,也提高了程式的可維護性。但是,結構化程式設計在開發大型專案時,還是無可避免的碰到了他的瓶頸。因為,結構化的程式設計,專注於功能面(函式)的開發,而往往忽略了功能所要處理的資料。被處理的資料與功能在結構化的程式設計是分離的關係。在大型專案的開發上,由於要處理的問題,相對的要複雜許多,如果,資料與函式之間沒有關聯性,很容易發生錯誤,維護起來也很不方便。後來,物件導向程式設計的興起,就是為了解決,結構化程式設計所面臨的資料與功能分離的問題。

物件導向程式設計的常用名詞:

   1. 屬性(Property):即物件裡的資料(變數)。
   2. 方法(Method):即物件裡的功能(函式)。
   3. 成員(Member):即類別裡所定義的變數或函式。
   4. 物件:類別的實例。
   5. 類別:物件的定義。由使用者所定義的資料型態。
物件導向程式設計的支柱

物件導向程式設計的三大支柱,稱之為 PIE(Polymorphism多變, Inheritance繼承, Encapulation封裝)。由於,PHP目前的版本只支援繼承及封裝,所以,我們在此,僅討論繼承與封裝。

所謂封裝,就是把功能與資料包裝起來成為一個物件,並定義物件的介面。讓外界的程式,透過物件所提供的介面,來與這個物件溝通。外界的使用者,無須知道,物件內部如何執行他的作業。只需要知道,如何使用物件的介面,來完成自己的工作即可。所以,設計物件的開發者,日後要更新物件的程式時,只要維持物件的介面不變,便可以確保,使用這物件的外部程式,不需要改寫,一樣可以執行。而外界程式的開發者,只要遵循不直接存取物件內部的功能及資料,僅透過介面來使用物件的規則,便可以確保程式執行無誤。

所謂繼承,就是子類別藉由繼承父類別的方式,取得父類別所定義的屬性及方法。通常,父類別會定義通用的屬性及方法,而子類別則延伸父類別定義特定的屬性及方法,以解決特定的問題。

如何使用物件導向程式設計來開發程式

使用物件導向的方式來開發程式,最主要的關鍵,在於程式設計觀念的改變。之前,我們使用函式來開發留言版的時候,我們著重在於找出留言版應該具有的功能,然後,按照功能來撰寫對應的函式。外界的網頁程式,把資料餵給這些功能,來完成它的工作。使用物件導向程式設計時,我們必須把程式所企圖解決的問題,看做是一個獨立的個體。在這個個體中,包含了它應該處理的資料,以及處理這些資料的功能。這些功能是為了處理這些資料所產生的。所以,在撰寫留言版的程式時,我們要把留言版當作是一個自給自足的個體。把程式所要解決的問題,定義成為個別的個體,這個過程稱之為抽象化(Abstraction)。

當我們的腦子裡,有了這個個體所需要的資料以及功能後,我們就可以專注於定義這個個體的類別。把個體的資料,定義成類別的屬性;把個體的功能,定義成類別的方法。在定義類別時,先別管外界的程式如何運作,全心全力專注於如何按照這個個體的需求,寫好這個類別。類別定義完之後,外界的程式,便可藉由物件變數,來使用這個我們定義的類別(使用者定義的資料型態)。物件導向程式設計,名稱上雖然是物件,但是,實際上,程式設計師大部分的心力,在於找出問題中的個體,定義這個個體的類別。使用這類別的程式部分,反而花的時間不多。

在下一節中,我們將使用實際的例子,來實作 PHP的物件導向程式設計。


PHP 物件導向程式設計實例演練

說明:

在這一節中,我們使用範例,來學習如何撰寫類別:

   1. 類別的語法結構。
   2. 封裝:定義屬性及方法。
   3. 使用物件:類別的實例化。
   4. 繼承。
一、類別的語法結構

class 類別名稱 [extends][父類別名稱]{

    類別的定義

}

說明:

   1. 定義類別時,在 class 保留字之後,是使用者所定義的類別名稱。
   2. 如果,所定義的類別要繼承其他類別時,需加上 extends 保留字,然後,加上父類別的名稱。否則,省略 extends和父類別名稱。
   3. 之後是由 { 和 }所包圍的類別定義。在這裡,類別的定義,包括了屬性及方法。

二、封裝:定義屬性及方法。

class 類別名稱 [extends][父類別名稱]{

    // 屬性的定義

    var $變數名稱;

    // 方法的定義

    function 方法名稱([參數列]){

    }

}

說明:

   1. 定義類別的個別屬性時,前面必須加 var 保留字。代表這變數是這個類別的屬性。
   2. 定義屬性時,可以給初始值。
   3. 定義方法時,規則同函式。
   4. 在方法中,如果要存取類別的屬性時,必須用 $this->變數名稱 這個格式。變數名稱在這裡,不可以加 $符號。
   5. 如果,類別中的方法名稱與類別名稱相同時,這個方法稱之為這個類別的建構方法。建構方法在類別被實例化時執行。類別實例化,說白一點,就是在外界的程式中,產生這個類別的物件變數。

範例:定義類別

<?php
/* 檔名:111_01.php
定義 Dog 類別
*/

class Dog{
     var $food = '骨頭';
     var $name;

     function Dog(){
          echo '產生 Dog 類別的物件時,便會呼叫這個方法(建構方法)';
     }

     function Eat(){
          echo $this->name.'吃'.$this->food;
     }
}
?>

三、使用物件:類別的實例化。

// 產生物件時
     $物件變數名稱 = new 類別名稱;

// 呼叫物件方法或存取屬性時
     $物件變數名稱->物件的方法或屬性;
            

說明:

   1. 要產生物件時,必須以一個變數來存放物件。
   2. 必須使用 new 保留字來產生物件。產生物件時,會執行這個物件的建構方法。
   3. 存取物件的屬性或呼叫物件方法時,物件與其成員之間,必須加 ->。
   4. 物件的屬性之前,不可加 $ 符號。

範例:使用物件

程式碼:

<?php
/* 檔名:111_02.php
       使用 Dog 類別
*/
// 含括 111_01.php 定義 Dog 類別的PHP檔
include_once('111_01.php');

// 產生 Dog 類別的物件
$mydog = new Dog;
$mydog->name = '來福';
echo '<br>';
$mydog->Eat();
?>

執行程式
四、繼承

說明:

   1. 當子類別繼承父類別時,子類別取得父類別所有的成員(屬性及方法)。
   2. 在子類別的方法,要呼叫父類別的方法時,使用 $this->父類別的方法名稱。
   3. 父類別通常只定義通用的成員。
   4. 子類別延伸父類別原有的功能,可另行定義專屬於子類別的功能。
   5. 當父類別的成員改變時,子類別的成員跟著改變。所以,藉著繼承的關係,可以讓我們的程式維護性大為提高。

範例:繼承

程式碼:

QUOTE:
<?php
/* 檔名:111_03.php
       定義 Pet, Dog, Cat 類別
*/

class Pet{
     var $food;
     var $name;
     var $language;

     function Pet(){
          echo '產生 Pet 類別的物件時,便會呼叫這個方法(建構方法)';
     }

     function Eat(){
          echo $this->name.'吃'.$this->food;
     }

     function Speak(){
          echo $this->name.'說'.$this->language;
     }
}

class Dog extends Pet{
     function Dog(){
          $this->food = '骨頭';
          $this->language = '汪汪';
          echo '產生 Dog 類別的物件時,便會呼叫這個方法(建構方法)';
     }
}

class Cat extends Pet{
     function Cat(){
          $this->food = '魚';
          $this->language = '喵喵';
          echo '產生 Cat 類別的物件時,便會呼叫這個方法(建構方法)<br>';
          $this->Pet();
     }

     function showFear(){
          echo $this->name.'怕水';
     }
}
?>



QUOTE:
<?php
/* 檔名:111_04.php
   使用 Dog, Cat 類別
*/
// 含括 111_03.php 定義 Pet, Dog, Cat 類別的PHP檔
include_once('111_03.php');

// 產生 Dog 類別的物件
$mydog = new Dog;
$mydog->name = '來福';
echo '<br>';
$mydog->Eat();
echo '<br>';
$mydog->Speak();
echo '<hr>';
$mycat = new Cat;
echo '<br>';
$mycat->Eat();
echo '<br>';
$mycat->Speak();
echo '<br>';
$mycat->showFear();
?>

將物件導向程式設計應用在留言版的資料庫網頁

說明:

在這一節當中,我們將把物件導向程式設計,應用在留言版的網頁程式中。

我們按照以下的步驟,來修改留言版的程式:

   1. 準備工作
   2. 產生網站設定檔:web_config.php
   3. 產生資料庫類別檔:db.php
   4. 產生應用程式設定檔:app_config.php
   5. 產生留言版類別檔:Guestbook.php
   6. 修改原本的程式: index.php, add.php, update.php, delete.php

一、準備工作

說明:

將第九課程所做好的PHP程式,放在另一個新的目錄 guestbook111 之下。然後,在網站的根目錄底下,建立一個 inc 的目錄。存放網站整體各項設定的檔案,以及存取資料庫物件的父類別檔案。
複製檔案:

   1. 使用putty連線到伺服主機。
   2. 輸入以下的命令,進入 public_html 目錄:
      cd public_html
   3. 輸入以下的命令,產生新的目錄 guestbook111,並將 guestbook110 中所有檔案,
      複製到guestbook111:
      cp -r guestbook110 guestbook111
   4. 輸入以下命令,產生新的目錄 inc。用來存放整體網站的設定檔及父類別檔。
      mkdir inc
   5. 輸入以下命令,產生 web_config.php 和 db.php 這兩個檔案。
      touch inc/web_config.php inc/db.php

二、產生網站設定檔:web_config.php

說明:

在 web_config.php 中,我們定義一些有關整體網站各含括目錄所需的參數,以及存取資料庫的設定,方便網站的管理者,日後修改網站的設定。

程式碼:

QUOTE:
<?php
/* 檔名:web_config.php
       定義各目錄及資料庫參數的常數
*/

// 定義網站目錄的設定
define(WEB_DIR, '/home/lib13/public_html/');
define(INCLUDE_DIR, WEB_DIR.'inc/');

// 定義資料庫的設定
define(DB_HOST, 'localhost');
define(DB_USER, 'lib13');
define(DB_PASSWORD, 'mypassword');
define(DB_DATABASE, 'lib13');
?>

三、產生資料庫類別檔:db.php

說明:

在 db.php 檔案中,我們定義存取資料庫的父類別,供網站中所有需要存取資料庫的類別繼承之用。在這個類別中,我們定義了資料庫連線及選用資料庫的方法 init()。同時,我們也擷取出存取資料庫的通用功能,分別依照功能定義成各種方法。透過繼承這個父類別,其他子類別就可繼承父類別的方法,無須再個別定義存取資料庫的方法。子類別隻需定義,個別類別所需的特定功能。這樣子的做法,一來,減輕修改程式的負擔,提高整個網站程式的維護便利性。二來,要新增其他類似的資料庫網頁時,可以透過繼承父類別的方式,減少程式碼的撰寫,提高程式開發的效率。

程式碼:

QUOTE:
<?php
/* 檔名:db.php
定義資料庫父類別,供其他需要存取資料庫的類別繼承之用。
*/

class DB{
     var $add_sql;
     var $update_sql;
     var $delete_sql;
     var $select_sql;
     var $retrieve_sql;

     function DB(){
          $this->init();
     }

     function init(){
          mysql_pconnect(DB_HOST, DB_USER, DB_PASSWORD)
                 || die('無法與資料庫建立連結');
          mysql_select_db(DB_DATABASE)
                 || die('無法選擇資料庫:'.DB_DATABASE);
     }

     function Add(){
          $this->setSQL();
          return mysql_query($this->add_sql);
     }

     function Update(){
          $this->setSQL();
          return mysql_query($this->update_sql);
     }

     function Delete(){
          $this->setSQL();
          return mysql_query($this->delete_sql);
     }

     function Select(){
          $this->setSQL();
          return $this->recordset($this->select_sql);
     }
               
     function recordset($sql){
          $rs = array();
          $result = mysql_query($sql);
          if($result){
               while($record = mysql_fetch_assoc($result)){
               array_push($rs, $record);
               }
               return $rs;
          }else{
               return false;
          }
     }

     function Retrieve(){
          $this->setSQL();
          $result = mysql_query($this->retrieve_sql);
          if($result and mysql_num_rows($result) == 1){
               return mysql_fetch_assoc($result);
          }else{
               return false;
          }
     }
}
?>

四、產生應用程式設定檔:app_config.php

說明:

app_config.php 這個檔案,定義了有關留言版所有網頁程式的設定。其他留言版的網頁,只需含括這個檔案,便可以使用定義好的各種設定。

藉由使用目錄來存放各相關子系統的方式,可以讓我們網站的功能模組化,日後需要增減功能時,只要新增或刪除目錄即可。在各目錄中,放置個別的 app_config.php 檔,來負責個別子系統的環境設定。這樣可以提昇各模組的可攜性,方便網站程式開發的管理。

程式碼:

[quote]<?php
/* 檔名:app_config.php
       定義這個目錄所需的各項設定
*/

// 含括網站設定檔 web_config.php
include_once('../inc/web_config.php');
?>[quote]

五、產生留言版類別檔:Guestbook.php

說明:

Guestbook.php,定義了留言版所需要使用的類別 Guestbook。Guestbook類別藉由繼承父類別 DB,取得了存取資料庫的通用功能。所以,在這個類別,只要定義專屬於留言版的各種屬性及功能即可。

程式碼:

[quote]<?php
/* 檔名:Guestbook.php
       定義 Guestbook 類別
*/

// 藉由含括子系統的設定檔,取得網站及子系統的各種設定
include_once('app_config.php');

// 含括父類別 db.php
include_once(INCLUDE_DIR.'db.php');

class Guestbook extends DB{
// 定義屬性
/ 通常可以用所要存取的資料表的各個欄位,作為這個類別的屬性
     var $id;
     var $name;
     var $email;
     var $web;
     var $content;
     var $post_time;
     var $fk_icon;

// 類別的建構方法
     function Guestbook(){
          $this->DB();
     }
               
// setProperties 方法用來連接表單的欄位以及類別的屬性
     function setProperties(){
          $this->id = $_POST[id];
          $this->name = $_POST[name];
          $this->email = $_POST[email];
          $this->web = $_POST[web];
          $this->content = $_POST[content];
     }

// setSQL 方法定義存取資料表所需的各個 SQL 命令
     function setSQL(){
          $this->add_sql = 'INSERT INTO Guestbook ";
          $this->add_sql .= "(name, email, web, content, post_time) ';
          $this->add_sql .= "VALUES('$this->name','$this->email','$this->web',";
          $this->add_sql .= "'$this->content',NOW())";
          $this->update_sql = "UPDATE Guestbook SET name='$this->name', ";
          $this->update_sql .= "email='$this->email', web='$this->web', ";
          $this->update_sql .= "content='$this->content' WHERE id=$this->id";
          $this->delete_sql = "DELETE FROM Guestbook WHERE id=$this->id";
          $this->select_sql = "SELECT * FROM Guestbook ORDER BY post_time DESC";
          $this->retrieve_sql = "SELECT * FROM Guestbook WHERE id=$this->id";
     }
}
?>[quote]

六、修改原本的程式: index.php, add.php, update.php, delete.php

說明:

在這裡,我們含括 Guestbook.php檔案。藉由產生 Guestbook的物件 $obj,按照各網頁程式所需要的功能, 透過 $obj物件,呼叫Guestbook所定義及繼承的各個方法。

下一課的題目為表單驗證。

PHP教學 第十一回

很久不沒有Post了,對不起,因為小弟要考試。好廢話少說,現在立刻開始第十一節課。
摘要:在這個課程中,將介紹表單欄位資料的驗證。我們在之前的課程中,一直沒有提到表單欄位驗證的問題。原因是因為,一方面是為了簡化程式的複雜性,讓學員能夠專注在學習新的技巧;另一方面,是因為表單驗證,跟物件導向程式設計,以及我們的程式開發觀念,能夠整合的更好,所以,個人認為在教完物件導向程式設計後,再回頭來教表單驗證,學習上的效果會比較好。

如何在伺服器端驗證表單欄位的資料

為什麼需要表單驗證?

一,使用者可能無意或蓄意填入不正確的資料,輸入的資料如果其資料型態與資料庫欄位定義不同,或者在不允許空值(NOT NULL)的欄位中,不填入任何資料。都會造成資料無法更新或新增的錯誤。二,有時,在使用者填寫表單時,我們希望所填入的資料,必須是某特定類型的資料,或是填入的值,必須再某特定的範圍內時,在正式寫入資料庫之前,都必須檢查,這些值是否有效。

如何把表單驗證整合在我們的程式中?

表單驗證的運算邏輯應該放在哪裡?按照我們的程式開發方式,表單驗證,應該放在哪個部分?通常需要表單驗證的地方,是在新增以及更新資料時,才需要使用表單驗證。以留言版的程式而言,我們可以放在 add.php 或 update.php。但是,這樣一來,就犯了一個大忌。因為我們嘗試將程式,分為三個層面來處理,使用者介面層、運算邏輯層、資料介面層。我們可以考慮一個問題,當驗證的規則改變時,他會影響到哪個層面。比如說,在留言版中,我們硬性規定,使用者的姓名,不可以超過12個字元。請問,這個改變,會影響到畫面的呈現(使用者介面層),或者影響到資料存取的通用功能(資料介面層),還是影響到運算邏輯的處理。在這裡,表單驗證,屬於資料驗證的工作,任何跟應用程式運算規則改變有關的事情,應該都歸屬於運算邏輯層來處理。所以,比較好的方式,應該是放在運算邏輯層裡面。所以,我們應該將表單驗證,放在 Guestbook.php裡面。以下,我們就將表單驗證整合在留言版的程式中。


將表單欄位驗證整合在留言版的程式

說明:

在這一節當中,我們將把表單驗證的功能整合在留言版的程式。

我們按照以下的步驟,來修改留言版的程式:

   1. 準備工作
   2. 修改資料庫類別檔:db.php
   3. 修改留言版類別檔:Guestbook.php
   4. 修改新增資料的程式: add.php
   5. 修改更新資料的程式: update.php
一、準備工作

說明:

將之前課程所做好的PHP程式,放在另一個新的目錄 guestbook112 之下。
複製檔案:

   1. 使用putty連線到伺服主機。
   2. 輸入以下的命令,進入 public_html 目錄:
      cd public_html
   3. 輸入以下的命令,產生新的目錄 guestbook112,並將 guestbook111 中所有檔案,
      複製到guestbook112:
      cp -r guestbook111 guestbook112

二、產生資料庫函式檔:db.php

說明:

因為 db.php 是需存取資料庫的所有類別的父類別。我們在這裡定義一個屬性,$error,並更改Add() 和 Update()這兩個方法的功能。這樣所有繼承這個類別的子類別,自然就繼承了這個屬性,就無須自行訂定義這個屬性;同時也更新了 Add() 和 Update()這兩個方法的功能。這就是使用繼承,所帶給我們的好處。修改一個地方,其他地方的程式,跟著會作改變。

注意:因為 db.php 這個程式所定義的父類別 DB,是供網站內其他程式繼承之用。所以,我們把它放在 inc 的資料夾之內,而不是 guestbook1xx的資料夾內。

程式碼:

QUOTE:
<?php
/* 檔名:db.php
定義資料庫父類別,供其他需要存取資料庫的類別繼承之用。
*/

class DB{
     var $add_sql;
     var $update_sql;
     var $delete_sql;
     var $select_sql;
     var $retrieve_sql;
     // 請在這個地方加入新的屬性 $error
     var $error;

     function DB(){
          $this->init();
     }

     function init(){
          mysql_pconnect(DB_HOST, DB_USER, DB_PASSWORD)
                 || die('無法與資料庫建立連結');
          mysql_select_db(DB_DATABASE)
                 || die('無法選擇資料庫:'.DB_DATABASE);
     }

     function Add(){

          // 在新增資料之前,先檢查資料是否有效。如果含有無效的資料時,直接傳回 false 值。
                    if(!$this->isDataValid()) return false;
          $this->setSQL();
          return mysql_query($this->add_sql);
     }

     function Update(){
   
          // 在更新資料之前,先檢查資料是否有效。如果含有無效的資料時,直接傳回 false 值。
                  if(!$this->isDataValid()) return false;
          $this->setSQL();
          return mysql_query($this->update_sql);
     }

     function Delete(){
          $this->setSQL();
          return mysql_query($this->delete_sql);
     }

     function Select(){
          $this->setSQL();
          return $this->recordset($this->select_sql);
     }
               
     function recordset($sql){
          $rs = array();
          $result = mysql_query($sql);
          if($result){
               while($record = mysql_fetch_assoc($result)){
               array_push($rs, $record);
               }
               return $rs;
          }else{
               return false;
          }
     }

     function Retrieve(){
          $this->setSQL();
          $result = mysql_query($this->retrieve_sql);
          if($result and mysql_num_rows($result) == 1){
               return mysql_fetch_assoc($result);
          }else{
               return false;
          }
     }
}
?>

三、修改留言版類別檔:Guestbook.php

說明:

之前在父類別 DB修改了Add() 和 Update()這兩個方法,在實際新增以及更新資料之前,我們呼叫了 isDataValid()這個方法。然而,父類別 DB本身並沒有定義這個方法 (Why?),所以我們必須在子類別中定義 isDataValid() 這個方法。

除此之外,我們定義了另一個方法 ,getProperties()。這個方法,將物件中的屬性轉換成為一個關連式陣列。方便,Update()方法更新資料失敗時,能取回原來表單的資料。讓使用者不必重新填寫所有資料。

程式碼:

QUOTE:
<?php
/* 檔名:Guestbook.php
       定義 Guestbook 類別
*/

// 藉由含括子系統的設定檔,取得網站及子系統的各種設定
include_once('app_config.php');

// 含括父類別 db.php
include_once(INCLUDE_DIR.'db.php');

class Guestbook extends DB{
// 定義屬性
/ 通常可以用所要存取的資料表的各個欄位,作為這個類別的屬性
     var $id;
     var $name;
     var $email;
     var $web;
     var $content;
     var $post_time;
     var $fk_icon;

// 類別的建構方法
     function Guestbook(){
          $this->DB();
     }
               
// setProperties 方法用來連接表單的欄位以及類別的屬性
     function setProperties(){
          $this->id = $_POST[id];
          $this->name = $_POST[name];
          $this->email = $_POST[email];
          $this->web = $_POST[web];
          $this->content = $_POST[content];
     }

// setSQL 方法定義存取資料表所需的各個 SQL 命令
     function setSQL(){
          $this->add_sql = 'INSERT INTO Guestbook ";
          $this->add_sql .= "(name, email, web, content, post_time) ';
          $this->add_sql .= "VALUES('$this->name','$this->email','$this->web',";
          $this->add_sql .= "'$this->content',NOW())";
          $this->update_sql = "UPDATE Guestbook SET name='$this->name', ";
          $this->update_sql .= "email='$this->email', web='$this->web', ";
          $this->update_sql .= "content='$this->content' WHERE id=$this->id";
          $this->delete_sql = "DELETE FROM Guestbook WHERE id=$this->id";
          $this->select_sql = "SELECT * FROM Guestbook ORDER BY post_time DESC";
          $this->retrieve_sql = "SELECT * FROM Guestbook WHERE id=$this->id";
     }
// isDataValid 方法驗證表單的資料是否有效
         function isDataValid(){
                  if(strlen(trim($this->name)) == 0){
                         $this->error.= '姓名欄位不可以是空白<br/>';
                  }
                 if(strlen($this->name) > 12){
                         $this->error .= '姓名不可以超過 12 個字元 <br/>';
                  }
                     if(strlen(trim($this->content)) == 0){
                         $this->error.= '留言內容欄位不可以是空白<br/>';
                  }
                  if(strlen($this->content) > 2048){
                      $this->error .= '留言內容不可以超過 2048 個字元 <br/>';
                  }
                  return strlen($this->error) == 0;
          }

// 將物件的屬性轉換成一個關連式陣列。
      function getProperties(){
          return array(
               "name" => $this->name,
               "email" => $this->email,
               "web" => $this->web,
               "content" => $this->content
               );
     }
}
?>

四、修改新增資料的程式: add.php

說明:

在之前我們已經修改了 DB類別的 Add()方法,在實際新增資料之前會先呼叫子類別的 isDataValid()方法。如果,資料有問題時,會傳回 false 值。同時,將錯誤的訊息,寫入 $error 這個屬性。所以,在 add.php 中,我們可以藉由 Add() 這個方法所傳回來的值,決定是否表單的資料有誤。如果有錯誤的話,顯示錯誤訊息。錯誤的訊息會放在 $error 這個變數,然後,在 HTML碼裡面,會使用 <?php echo $error?>的方式,顯示錯誤的訊息。

同時為了避免資料錯誤時,使用者必須重新填寫每個欄位的麻煩。我們修改了每個表單欄位標籤裡面的 value屬性。
請點選 add.php 看修改過後的原始碼
五、修改更新資料的程式: update.php

說明:

在之前我們已經修改了 DB類別的 Update()方法,在實際新增資料之前會先呼叫子類別的 isDataValid()方法。如果,資料有問題時,會傳回 false 值。同時,將錯誤的訊息,寫入 $error 這個屬性。所以,在 add.php 中,我們可以藉由 Update() 這個方法所傳回來的值,決定是否表單的資料有誤。如果有錯誤的話,顯示錯誤訊息。錯誤的訊息會放在 $error 這個變數,然後,在 HTML碼裡面,會使用 <?php echo $error?>的方式,顯示錯誤的訊息。

因為,在更新的表單中各個欄位的初始值,是使用 $record 這個關連式陣列的變數。為了表單欄位值初始化的一致性,不論是從資料庫取得這個資料,或是送出表單,資料發生錯誤時,都使用 $record 這個關連式陣列的變數,來初始化欄位的值。所以,我們呼叫了 Guestbook這個類別的 getProperties() 方法。取得物件的屬性值。
請點選 update.php 看修改過後的原始碼
小組專案作業

說明:

為了讓同學有實際演練的機會,同時也驗收目前的學習成果。我們會由同學們親手實作一個專案。在撰寫程式之前,必須先了解專案的內容。要詳細了解專案的內容,就必須與使用者訪談。訪談的重點擺在聽和問。

聽啥東西呢?在使用者敘述他的問題時,重點放在他所使用的名詞和動詞。記下他所敘述的每個名詞,用箭頭來表示動詞,並連接每個名詞。名詞可能代表程式中所要設計的物件。動詞則可能是流程,或者是物件之間的互動關係。注意,在訪談過程,重點在找出每個物件他所需要具備的屬性,之後,在藉由了解各物件之間的互動關係,來定義物件的方法。

問可能比聽更重要,使用者在敘述他的問題時,通常會用比較概觀的說法。你必須透過問問題的方式,找出影響你開發程式中的細節。如果,使用者一時無法回答比較細節的問題時,告訴他你需要什麼樣的資料,請他準備好,或者與他商量如何來定義這些資料。如果,你無法開始著手開發程式時,表示你所收集的資料還不夠,直到資料收集足夠時,才可以停止問問題。

切記,訪談的重點,不在你是否有能力解決使用者的問題。而在於你能否確切了解使用者的問題。別讓你的心思沉迷在解決問題的陷阱中。別使用程式設計者的觀點來思考,要站在使用者的角度,來看這些問題。解決問題是後面的事情,不是現在你關心的重點。了解比解決更重要。

PHP教學 第十二回

Smarty 樣版引擎:版面配置
摘要: 在這個課程中,我們將以另一種角度來觀察網頁,分析網頁是由哪些部分所組成的。了解了網頁組成的成分之後,我們就可以這些部分給抽離出來,讓它成為一個獨立的檔案。再透過 Smarty樣版引擎,把各部分組合成為一個網頁。
網頁的組成:區塊

說明:

如果我們仔細觀察每個網頁,至少都可以分成以下幾個區塊:

   1. 頁首:網頁標題,主題等。
   2. 導覽:連接到網站各部分的連結。
   3. 內容:這頁網頁的內容。
   4. 頁尾:版權宣告,或其他連結與網站聯繫資料等。

要達到能夠在各個網頁中,能重複使用這些區塊,就必須將每個區塊獨立成為一個檔案。如果,要把這些區塊的檔案,組成一個網頁,我們就必須作一個檔案,作為整個網頁配置的主檔,負責指定每個區塊檔案在網頁呈現的位置。

這樣做,一開始會覺得很繁瑣,因為,一個網頁居然要使用五個檔案(四個區塊檔,加上一個網頁配置檔)來組成。的確,如果只是作一個網頁的話,使用樣版引擎,有點殺雞焉用牛刀的感覺。但是,在實務上,大部分的情況,一個網站中通常會有數十個,甚至上百個網頁配置相同的網頁。在這種情況之下,使用樣版引擎,來配置網頁的效益,就能夠突顯出來。

以下,我們就以實際的例子,來作說明。


準備工作:使用Dreamweaver MX 定義網站

   1. 使用Dreamweaver MX 定義一個 Site(名稱自定)。
   2. 在這個 Site 底下產生兩個資料夾,一個名稱為 114,一個名稱為 tpl。
   3. 在 tpl 資料夾之下,再產生一個 114 的資料夾。

產生區塊檔案:header.htm、menu.htm、content.htm、footer.htm

   1. 使用 Dreamweaver MX在 tpl/114 資料夾底下,產生這四個檔案。
   2. 去掉 <Body>(含)之前的所有標籤,以及</Body>(含)之後所有的標籤。

header.htm

<h1>國立嘉義大學圖書館</h1>
           

menu.htm

<table width="160" border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td bgcolor="#9966FF"> <div align="center">
        <font color="#FFFFFF">主選單:</font></div></td>
  </tr>
  <tr>
    <td bgcolor="#FFFFCC"> <div align="center">選單一</div></td>
  </tr>
  <tr>
    <td bgcolor="#FFFFCC"> <div align="center">選單二</div></td>
  </tr>
  <tr>
    <td bgcolor="#FFFFCC"> <div align="center">選單 N</div></td>
  </tr>
  <tr>
    <td bgcolor="#FFFFCC"><div align="center">回首頁</div></td>
  </tr>
</table>

content.htm

<p>這裡是內容區塊:</p>
<p>應該會有很多字 </p>

footer.htm

<p>版權所有:國立嘉義大學圖書館<br />
  來信請寄:<a href="mailto:webmaster@lib.ncyu.edu.tw">webmaster@lib.ncyu.edu.tw</a></p>

產生網頁配置檔:layout.htm
使用 Dreamweaver MX 在 tpl/114 資料夾底下,產生網頁配置檔。先以文字標明區塊,之後,我們會改用Smarty的語法來取代。
layout.htm

<html>
<head>
<title>{$pageTitle}</title>
<meta http-equiv="Content-Type" c />
</head>

<body>
<div align="center">header
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr valign="top">
<td width="15%">menu</td>
<td width="85%">content</td>
</tr>
</table>
footer </div>
</body>
</html>


修改網頁配置檔:layout.htm

說明:

到目前為止,我們只以文字來標明網頁配置檔中的區塊,並沒有使用 Smarty 的語法。在使用之前,我們先看一下哪些區塊,是會變動的,哪些是不會變動的。

為了使頁面風格以及瀏覽方式一致,通常在頁首、頁尾、以及導覽的部分通常是固定不變的,只有在內容區塊才會變動。

所以,在 header、footer、menu這三個文字所標明的區塊,含括的檔案,其檔名是不變的。而 content 所標明的區塊,應該隨著使用者點選而作改變;所以,這裡所含括的檔名,應該是變數。

Smarty 提供了 include 函式,讓我們可以把檔案含括進來。其格式如下:

{include file="檔案名稱"}

檔案名稱可以放絕對路徑,即實體檔案系統的絕對路徑。如,/home/lib13/public_html/tpl/114/header.htm。

也可以放相對路徑,即相對於 Smarty 物件 template_dir 屬性所定義的路徑。如,114/header.htm。

知道了哪些區塊是可變動的,哪些是固定不變的;以及知道 Smarty 的含括語法後,我們就可以修改網頁配置檔:layout.htm。

P.S. 使用 Dreamweaver MX來撰寫樣版時,注意要使用 Code View,不要在 Design View中寫 Smarty 的語法。不然,一些專屬的符號,如 { 和 }會被替代掉。


修改後的 layout.htm

<html>
<head>
<title>{$pageTitle}</title>
<meta http-equiv="Content-Type" c />
</head>

<body>
<div align="center">{include file="114/header.htm"}
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr valign="top">
<td width="15%">{include file="114/menu.htm"}</td>
<td width="85%">{include file=$contentBlock}</td>
</tr>
</table>
{include file="114/footer.htm"} </div>
</body>
</html>


使用 Smarty 物件來呈現我們的網頁

說明:

樣版做好之後,我們就可以使用 Smarty 來呈現頁面。之前在課程 113 裡面,我們已經做好了一個 Page 的類別檔。在這裡我們就直接繼承這個類別,撰寫程式來呈現我們的頁面。



在你所定義的 Site 目錄底下,114 資料夾下,產生一個新檔,檔名:index.php。你可以使用 EditPlus 或 Dreamweaver MX 來編寫這個程式。


114/index.php

程式碼:

QUOTE:
<?php
/*** 含括 Page 父類別 Page.class.php 檔案。 ***/
include_once('/home/lib13/public_html/Page.class.php');

/*** 產生 Smarty 物件。 ***/
$page = new Page;

/*** 設定樣版中的變數。 ***/
$page->assign('pageTitle', 'Smarty 網頁配置');
$page->assign('contentBlock', '114/content.htm');

/*** 呈現樣版。 ***/
$page->display('114/layout.htm');
?>

上傳檔案

你可以用 EditPlus 將 114/ 和 tpl/這兩個資料夾上傳到你的 publilc_html/目錄。或者,使用 Dreamweaver MX來上傳檔案。

使用 Dreamweaver MX 上傳 Site 的檔案時,必須先定義 Site 的 Remote Info。請參考下圖:

在 Site 中按 Connect To Remote Host按鈕之後,直接用拖拉的方式,把 114/和 tpl/ 這兩個資料夾,上傳在 public_html 目錄之下。
使用相同的樣版,產生其他的網頁

說明:

做好一個頁面之後,我們就可以使用同樣的樣版,產生其他的頁面。只要產生新的內容區塊檔,然後,產生新的 PHP 檔,將 contenbBlock變數指定給新的內容區塊檔即可。
產生新的內容區塊檔:content1.htm

使用 Dreamweaver MX 在 tpl/114 資料夾底下,產生 content1.htm 內容檔。同樣刪掉<body>這類不必要的標籤。原始檔如下:

<p>內容區塊:</p>
<p>點選選單一的內容</p>
<p>應該也要有很多字</p>

產生 php 檔:select1.php
在你所定義的 Site 目錄底下,114 資料夾下,產生一個新檔,檔名:select1.php。做完後,上傳檔案。

程式碼:

QUOTE:
<?php
/*** 含括 Page 父類別 Page.class.php 檔案。 ***/
include_once('/home/lib13/public_html/Page.class.php');

/*** 產生 Smarty 物件。 ***/
$page = new Page;

/*** 設定樣版中的變數。 ***/
$page->assign('pageTitle', 'Smarty 網頁配置');
$page->assign('contentBlock', '114/content1.htm');

/*** 呈現樣版。 ***/
$page->display('114/layout.htm');
?>

練習:修改導覽區塊

請自行練習,修改 menu.htm。讓回首頁的文字連結,點選後,回到 114/index.php。點選單一,跳到 select1.php。並檢查,是否修改過 menu.htm之後,select1.php 和 index.php 的選單內容也跟著改變。


練習:增加新的 php 檔

使用之前產生 select1.php 的方式,再撰寫兩個新的 php 程式:select2.php 和 select3.php。然後,修改 menu.htm。
下一課是: 使用 SESSION 來記錄 Web 應用程式的狀態,快快看

PHP教學 第十三回

使用 SESSION 來記錄 Web 應用程式的狀態
摘要:

HTTP 使用無連線狀態的連線(Stateless Connection)方式,然而,我們在開發應用程式時,常會需要在多個網頁,存取同一位使用者連線資料。PHP解決這個問題的方式,有以下幾種:

   1. Cookie
   2. Session
   3. Hidden Field 隱藏欄位。
   4. URL Rewriting 網址改寫。

在這個課程中,我們著重在討論 Session的使用,並把 Session 應用在系統登入的實例中。

Session 變數的使用:

PHP 的全域變數 Session 提供給我們一個可以在多個頁面存取個別使用者連線資料的機制。對於針對個別使用者,需要在多個頁面存取共用的資料時,特別有用。如果,非由程式特別清除 Session 的話,個別使用者的 Session 資料會在特定時間(由 php.ini 設定)內,被系統清除掉。

以下,我們分別按照寫入Session、讀取Session、清除Session等方式,探討如何使用 Session 變數。

Session 的寫入:

   1. 啟動 Session。
   2. 登記 Session 變數名稱。
   3. 使用$_SESSION 全域變數,將值寫入已登記的 Session 變數。

範例碼:

QUOTE:
<?php
       // 1. 啟動 Session
       session_start();


       // 2. 登記 Session 變數名稱
       session_register('foo');


       // 3. 寫入 Session 變數
       $_SESSION[foo] = 66;

?>

Session 的讀取:

   1. 啟動 Session。
   2. 使用$_SESSION 全域變數,讀取 Session 變數。

範例碼:

QUOTE:
<?php
       // 1. 啟動 Session
       session_start();


       // 2. 使用$_SESSION 全域變數,讀取 Session 變數。
       echo $_SESSION[foo];

?>

Session 的清除:

   1. 啟動 Session。
   2. 清除所有已登記的 Session 變數。
   3. 銷毀現有的 Session連線紀錄。

範例碼:

QUOTE:
<?php
       // 1. 啟動 Session
       session_start();


       // 2. 清除所有已登記的 Session 變數
       session_unset();

       // 3. 銷毀現有的 Session連線紀錄
       session_destroy();
?>

實例演練:

以下使用簡單的帳號登入,來示範 Session 的使用。在這個簡化的演練中,不使用資料庫,僅著重在於 Session 的應用,以加深學習的效果。在這個範例中,有以下幾個網頁:

   1. index.htm 主頁:包含系統登入,以及權限控管頁面的連結。
   2. login.php 登入頁:負責檢查帳號密碼是否正確,登入成功的話,將變數寫入 Session,供其他權限控管頁面存取;並按照使用者在主頁所點選的連結,決定重導的網址。登入失敗時,則重導到登入失敗的頁面。
   3. access_denied.htm 登入失敗頁:顯示登入失敗的訊息。
   4. login_success.php 登入成功頁:如果,使用者在主頁所點選的連結為系統登入,且登入成功時,則傳回這個網頁,並讀取 Session 中的變數值,顯示在這個頁面。
   5. protected.php 權限控管頁:如果,使用者在主頁所點選的連結為權限控管頁面,且登入成功時,則傳回這個網頁,並讀取 Session 中的變數值,顯示在這個頁面。
   6. logout.php 登出頁:清除所有 Session 變數,銷毀現有連線資料,並重導回主頁。


實作:

※ 網頁製作完成後,請將資料夾上傳至網站的目錄※

一、靜態網頁:index.htm, access_denied.htm

   1. 在你的電腦上,作一個資料夾 115 。
   2. 用 Dreamweaver MX 或其他任何網頁編輯工具,製作這兩個檔案。
   3. 請點選以下兩個連結,參考這兩個網頁的畫面:
index.htm
access_denied.htm
二、login.php:

原始碼:

QUOTE:
<?php
       if(isset($_POST[Submit])){
              // 如果帳號和密碼正確的話,寫入Session變數,並視情況重導到相關的頁面
              if($_POST[account] == "admin" & $_POST[password] == "pass"){
                     // 啟動 Session
                     session_start();

                     // 登記 Session 變數名稱
                     session_register('authenticated');
                     session_register('fruits');
                     session_register('login_time');

                     // 寫入 Session 變數值
                     $_SESSION['authenticated'] = true;
                     $_SESSION['fruits'] = array("orange", "banana", "apple");
                     $_SESSION['login_time'] = date('Y-m-d h:i:s');
                     // 檢查在 $_SESSION 全域變數中,是否有之前設定好的網址重導 Session 變數
                     if(isset($_SESSION[UrlRedirect])){
                            $redir = $_SESSION[UrlRedirect]
                     }else{
                            $redir = 'login_success.php';
                     }
                     
                     // 重導到相關頁面
                     header("Location: $redir");
                     exit;
              }else{
                     header('Location: access_denied.htm');
                     exit;
              }
       }
?>

<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" c />
</head>

<body>
<form name="form1" id="form1" method="post" action="">
<p align="center">帳號:
<input name="account" type="text" id="account" />
</p>
<p align="center">密碼:
<input name="password" type="password" id="password" />
</p>
<p align="center">
<input type="submit" name="Submit" value="登 入" />
</p>
</form>
</body>
</html>

三、login_success.php:

原始碼:

QUOTE:
<?php
       session_start();
       if($_SESSION[authenticated] == true){
              $result = '登入時間: '.$_SESSION[login_time];
              foreach($_SESSION[fruits] as $fruit){
                     $result .= "<br>$fruit";
              }
       }else{
              header('Location: login.php');
              exit;
       }

?>

<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" c />
</head>

<body>
<div align="center">
<p><font color="#0000FF"><strong>登入成功!</strong></font></p>
<p>Session 變數如下:</p>
<p><?php echo $result?></p>
<p><a href="logout.php">[ 登 出 ]</a></p>
</div>
</body>
</html>

四、protected.php:
原始碼:

QUOTE:
<?php
       session_start();
       session_register('UrlRedirect');
       $_SESSION[UrlRedirect] = $PHP_SELF;
       if($_SESSION[authenticated] == true){
              $result = '登入時間: '.$_SESSION[login_time];
              foreach($_SESSION[fruits] as $fruit){
                     $result .= "<br>$fruit";
              }
       }else{
              header('Location: login.php');
              exit;
       }

?>

<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" c />
</head>

<body>
<div align="center">
<p><font color="#0000FF"><strong>權限控管頁面!</strong></font></p>
<p>Session 變數如下:</p>
<p><?php echo $result?></p>
<p><a href="logout.php">[ 登 出 ]</a></p>
</div>
</body>
</html>

五、logout.php:

原始碼:

QUOTE:
<?php
session_start();
session_unset();
session_destroy();
header('Location: index.htm');
exit;

?>

PHP教學 第十四回

Ant 的使用
摘要:

在這個課程當中,我們簡單的介紹 Ant 的使用方法。有關 Ant 的取得、安裝、以及設定,請參考附錄 B:ANT 取得、安裝、及設定。]我們使用 Ant ,將上個課程所寫的程式上傳到伺服器。

Ant 的概念:

Ant 語法採用 XML 的格式。XML非常適合用來表達多階層的樹狀資料結構。Ant 的語法也承襲了這個優點。

要讓 Ant 來自動化我們的工作,我們就必須在專案的目錄中,撰寫 build.xml。

當然你可以使用其他的檔案名稱,如果使用其他檔名,就必須在命令列指定這個檔名。
假設檔名為abc.xml,命令列就必須改成:

ant -buildfile abc.xml。

build.xml 基本的結構,包含了一個文件的根節點:project;至少一個 target 節點;target節點裡再包含 task 節點來指定 Ant 所要執行的任務。視情況需要,還可以使用 property 節點,來定義 Ant 的變數。以下,分別介紹每個節點的功用。

project 節點:

project 節點是 build.xml 的文件根節點。一個文件之中,只能有一個根節點。project 節點有以下三個屬性。

屬性                   說明                                                                              是否必要
name                專案名稱                                                                              No
default        假設命令列未指定 target 時,預設執行的 target 節點              Yes
                                                                                                
basedir        用來指定專案的根目錄,這個屬性可以使用"basedir"
                   property 節點來改                 
                  變,如果定義 basedir的 property 節點,在 project 標籤中,
                  就不可以定義           
                  這個屬性。假使未使用這個屬性或 property 節點來定義 basedir
                  的話,則 Ant 會使用這個專案 build.xml 的目錄,作為 basedir。                                                               
                                                                                                          No

target 節點:

target 節點是 Ant 執行的目標,我們可以把各種命令(在 Ant 中的術語,叫任務 task),放在 target 的節點中。所以,你可以把他想成是一組命令的結合,以程式設計來說,接近副程式或不傳回值的函式。

target 和 target 之間,可以使用 depends屬性來定義彼此間的依存關係。藉由定義這些依存的關係,我們可以改變 target 的執行順序。也可以定義 if 以及 unless 屬性,來決定是否執行這個 target 節點的工作。沒有定義 if 和 unless 屬性的 target 節點,一定會按照順序執行。


屬性                          說明                                                                是否必要
name                     target 的名稱                                                        Yes
depends        在執行這個 target 節點之前,先要執行其他節點的名稱。
                     如果是多個節點時,以逗號區隔各個節點。                      No
----------------------------------------------------------------------------------------------------------------              
if                     指定 property 名稱。必須定義這個 property ,               No
                     才會執行這個 target的工作。
----------------------------------------------------------------------------------------------------------------                                             
unless                  指定 property 名稱。必須不定義這個 property ,
                    才會執行這個 target的工作。                                              No
description        文字說明                                                                         No

task 節點:

task 節點,是 Ant 執行工作最基本的單位,類似程式設計中的命令句。可分為 core tasks 和 optional tasks 兩類,你也可以使用 java 來撰寫自定的 task。

task 的範圍很廣,各個屬性也不相同,要運用 task時,可參考 Ant 的線上說明。

property 節點:

property 節點,定義專案的屬性值,類似程式設計中的變數。最常用的屬性有 name 和 value。name 定義這個 property 的名稱,value 定義這個property 的值。要讀取 property 的值時,必須使用 ${property名稱}的格式。

範例:

QUOTE:
<project name="ex" default="hello">

<property name="who" value="Bush"/>

<task name="hello">

<echo message="Hello, ${who} "/>

</task>

</project>

實例演練:使用 Ant 上傳檔案

我們在開發應用程式時,常常面臨需要處理很多繁瑣的工作。使用 Ant 可以幫助我們簡化這個過程。在使用 Ant 之前,你必須要先知道,你所要處理的工作有哪些。

以上個課程為例,我們要把寫完的 PHP 網頁程式,上傳到伺服器。上傳檔案這種瑣事,就可以交給 Ant 來處理。一般來說,應該是以FTP工具來執行上傳的工作,Ant 裡面所使用的 FTP task 功能不夠強大,在初次上傳的情況還好,但是,在開發過程當中,常常需要不時的更新上傳,Ant 的 FTP task 就容易因為目錄權限的問題,發生無法執行的錯誤。為了避免這個困擾,我們可以在開發測試的主機中,安裝 Samba,然後,在你的 windows 機器上,建立連線磁碟機,使用 Ant 的 copy task ,就可以解決這個問題。

準備工作:

在桌面上的網路上的芳鄰,按右滑鼠鍵,在選單中選擇連線網路磁碟機。指定磁碟機的名稱為 F:,路徑欄輸入\\主機名稱或 IP\帳號,如:\\libdns.lib.ncyu.edu.tw\lib13。然後,輸入帳號和密碼。這樣,在你的機器上,就有一台網路磁碟機了。

撰寫 build.xml:

進入到你的 115 資料夾之內,使用 editplus,產生一個 build.xml 檔案。

內容如下:

QUOTE:
<project name="115" default="upload">      
       <property name="dest_drive" value="F:\" />
       <property name="dest_dir" value="${dest_drive}\public_html\115" />

       <target name="create_dir">
              <mkdir dir="${dest_dir}" />
       </target>

       <target name="upload" depends="create_dir">
              <copy todir="${dest_dir}">
                     <fileset dir=".">
                            <exclude name="**\build.xml"/>
                     </fileset>
              </copy>
       </target>

</project>

執行 Ant 程式:

進入 DOS 命令列,cd 到 115資料夾,然後,在命令提示下,打 ant 按 enter 鍵。

實例演練:使用 Ant 存取資料庫

QUOTE:
<project name="main" default="getdata">      
       <property name="host" value="libdns.lib.ncyu.edu.tw" />
       <property name="database" value="lib13" />
       <property name="userid" value="lib13" />
       <property name="password" value="password" />
       <property name="driver" value="com.mysql.jdbc.Driver" />
       <property name="url" value="jdbc:mysql://${host}/${database}" />

       <target name="create_database">
              <sql
                     driver="${driver}"
                     url="${url}"
                     userid="${userid}"  
                     password="${password}"
                     src="lib13.sql"
                     encoding="iso-8859-1"
              />
       </target>

         <target name="getdata" depends="create_database">
              <sql  
                     driver="${driver}"
                     url="${url}"  
                     userid="${userid}"  
                     password="${password}"  
                     showheaders="true"
                     print="true"
                     encoding="iso-8859-1">
                             select id, name from Guestbook
              </sql>
       </target>

</project>

PHP教學 第十五回

【專案實作】一、網站開發的基礎架構(Framework)
摘要:

在這個課程當中,我們著重在建立網站的基礎架構。這個架構包含了:開發規範,核心模組,共用檔案等。在課程最後,會練習以這個架構,製作出網站的首頁。下一個課程中,我們將開發帳號管理的子系統,更詳細介紹如何使用這個架構。

檔案下載
專案開發規範:

由於這個專案是由多人共同開發出來,為了日後能順利整合各開發者所開發出來的子系統,以及確保日後程式更新與維護的便利性,所以,訂定以下的規範,請各位開發者務必遵守:

   1. 所有子系統,以及頁面一律使用這個課程所開發的核心模組。
   2. 各子系統應將所有頁面及程式模組安置在同一個資料夾(project/www/資料夾之下)。
   3. 各子系統都必須含括網站根目錄中的 config.php 檔案,以確保含括檔的路徑不至於混淆。
   4. 各子系統必須定義自己的樣版設定檔。
   5. 各子系統均應有一個類別檔,繼承 DB 父類別。
   6. 公共存取頁面,請產生一個 PublicPage 的物件。
   7. 系統管理頁面,請產生一個 SysPage 的物件。
   8. 所有圖片檔,一律放在同一個資料夾(project/www/images/資料夾之下)。
   9. 使用 Smarty 樣版引擎,製作所有頁面的樣版。
  10. 頁面中所有的連結,均需使用網站絕對網址。
  11. 使用統一的 CSS 定義文件的樣式(project/www/css/style.css)。
  12. 使用 Ant 配置檔案及設定資料庫。
  13. 使用相同的資料夾結構。
  14. 撰寫註解。方便其他開發者,了解你的程式。

決定核心模組:

在開發網站的初期,一般說來,未經過詳細的系統分析的過程,很難一次就決定核心模組有哪些。但是,如果,要經過漫長的系統分析的過程,再來開始決定核心模組,往往無法達到時間上的要求。所以,比較好的方式是,先就目前所知的部分,先行決定要開發哪些模組。等日後,對系統有更清楚的認識,以及在日後開發其他子系統時,發覺需要修正核心的部分時,再來修改核心。

不過,也不能隨便亂寫。最好要有個可以參考的基準。我們採用的基準就是將所有程式,分為以下三個層:

   1. 資料層(Data Layer):負責處理有關存取資料庫的工作。
   2. 邏輯層(Logic Layer):負責處理各子系統模組特定功能需求的工作。
   3. 呈現層(Presentation Layer):負責處理有關頁面呈現的工作。

決定以這三個層作為開發基準之後,我們就容易決定要有哪些作為我們核心的模組。下表是目前所決定的模組。

類別名稱                            說明                                    檔名                      層
DB        負責存取資料庫的類別                               DB.php                 Data
Page        繼承 Smarty 類別,呈現頁面的類別,
           定義頁面的共同屬性及方法                    Page.php         Presentation
-------------------------------------------------------------------------------------------------------------------
PublicPage        繼承 Page 類別,負責呈現公共頁面        PublicPage.php        Presentation
SysPage        繼承 Page 類別,負責呈現系統管理頁面        SysPage.php        Presentation

上面的表格中,並沒有在核心模組中,定義有關邏輯層的類別。這是因為各子系統除了在存取資料庫時,具有共同的功能需求之外,其他部分,到目前為止,還沒有發現需要在核心中,另行撰寫一個父類別來定義共同的屬性及功能。何況,因為所有子系統的類別均需繼承 DB 這個父類別。如果,真有需要的話,可以視情況需要,在 DB 父類別中,再來定義額外的屬性及方法。

設定檔:

設定檔共有兩類,以下表說明:
種類                                                              說明
網站 PHP 的設定檔        在 www/網站根目錄底下有一個 config.php ,負責設定路徑以及            
                               資料庫等參數。
----------------------------------------------------------------------------------------------------------------
樣版的設定檔        在 config/底下的各設定檔,每一子系統擁有一個設定檔,負責設定樣版

                    所使用的變數。

Ant Build.xml:

一個專案主檔,負責配置檔案到遠端伺服器。另一個資料庫檔,負責設定資料庫。

開發流程:

子系統開發流程
      



網頁開發流程