如果你從來沒有接觸過PHP,那麼還是先看看這個吧,當然即使是你已經對PHP有所瞭解,但一本PHP4的的使用手冊也還是需要的,:)。此外一本HTML文法手冊當然也是不可缺少的啦。
我們來開始做一個可以應用的PHP的投票程式。在這篇裡大家將學習到cookie技術的使用,PHP的數組操作及檔案的處理。如何?大家準備好了嗎?Let"s go!
在開始具體的程式設計之前,我們先學習一下幾個下面需要用到的重要概念和函數:
首先是cookie,我們需要用他來防止同一台機器進行重複投票。
那麼什麼是cookie?如果你的英文夠好,又想吃塊原味的cookie,那麼先到這裡來嘗嘗鮮;要不然你就只有吃地藏給你熱的啦。。。。。(不好吃別扁我喲,:))
cookie原義在美語中是小甜餅的意思,當然我們現在不是要吃餅,在這cookie指的是一個有許多限制的ASCII檔案。它是由伺服器發給使用者用於記錄著使用者在瀏覽過程中的一些資訊。Cookies的檔案大小被限制在4K以內。 cookie的用途是非常多的,比如你到過的一些網站有記錄你來過次數,那就多半是用了cookie。 在這裡我們用他來記錄訪問者是否已經投過票。
在PHP裡我們可以非常方便的用setcookie函數來使用cookie,cookie實際上是HTTP協議中header的一部分。因此setcookie函數必須在沒有任何其它資訊輸出到瀏覽器之前調用。說簡單點就是要在<html>標誌前用這個函數啦……。下面是setcookie的用法樣本,來自星空浪子大哥的PHP4中文手冊,大家等下還可以再參照一下我們在程式中的具體用法。
setcookie
送出 Cookie 資訊到瀏覽器。
文法: int setcookie(string name, string value, int expire, string path, string domain, int secure);
傳回值: 整數
函式種類: 網路系統
內容說明
本函式會跟著標題 Header 送出一段小資訊字串到瀏覽器。使用本函式要在送出 HTML 資料前,實際上 cookie 也算標題的一部份。本函式的參數除了第一個 name 之外,都是可以省略的。參數 name 表示 cookie 的名稱;value 表示這個 cookie 的值,這個參數為空白字串則表示取消瀏覽器中該 cookie 的資料;expire 表示該 cookie 的有效時間;path 為該 cookie 的相關路徑;domain 表示 cookie 的網站;secure 則需在 https 的安全傳輸時才有效。
expire時間的格式如下:
Wdy, DD-Mon-YYYY HH:MM:SS GMT
GMT表示格林尼治標準時間
使用範例
<?php
$status = 0;
if (isset($myTstCky) && ($myTstCky == "ChocChip")) $status = 1;
if (!isset($CCHK)) {
setcookie("myTstCky", "ChocChip");
header("Location: $PHP_SELF?CCHK=1");
exit;
}
?>
<html>
<head><title>Cookie Check</title></head>
<body bgcolor="#FFFFFF" text="#000000">
Cookie Check Status:
<?php
printf ("<font color="#%s">%s</font><br>;",
$status ? "00FF00" : "FF0000",
$status ? "PASSED!" : "FAILED!");
?>
</body>
</html>
怎麼樣?大家對cookie的用法是不是有所瞭解呢?地藏在這裡告訴大家一個關於expire日期的小技巧,如果你想讓cookie的expire日期為從當前算起的第三天。那麼你可以使用time()函數,這個函數將返回一個以秒為單位的目前時間(注意喲!這個時間是包括了年月日的,是不是很奇怪?:)),那麼如果你想把expire日期定為第三天,那麼就是 time()+60*60*24*3。
PHP的數組使用非常簡單,大家只要注意它預設的起始下標是象C語言一樣從零開始的,當然你也可以自己設定它的下標,如下面這樣:
$descArray=array(
1=>"英文:原始碼、程式下載",
2=>"英文:php動態",
3=>"英文:新聞群組、公告欄",
4=>"英文:教學類",
5=>"中文:原始碼、程式下載",
6=>"中文:新聞群組、公告欄",
7=>"中文:教學類" );
使用的時候 $descArray[1]= "英文:原始碼、程式下載"。更絕的是你還可以。
$MyArray2 = array( "
地支" => array("子", "醜", "寅", "卯"),
"生肖" => array("鼠", "牛", "虎", "兔"),
"數字" => array(1, 2, 3, 4) );
用的時候$MyArray2["地支"][0]="子"; 怎麼樣?是不是很有人情味啊,:)
最後我們來看看PHP的檔案處理,PHP中用於檔案處理的函數有大概幾十個,在我們這一節裡,使用了其中的五個函數fopen(); fclose(); flock();fexists();fwrite(); 其中我想重點說一下flock();其它的大家就去自己查手冊吧。
為什麼要重點說flock()?因為這是一個對於網路編程非常重要的功能,我舉個例子,兩個人同時投票,而且選的都是選項A,假設他們同時開啟資料檔案,這時A的選票是2,然後兩個進程都在原有的基礎上加1,接著一個寫入了資料,另外一個也跟著寫完了寫入,大家想這時會出現什麼情況?A的選票是多少?正確結果應該是4,但實際上卻會是3。為什麼會這樣?這就是因為網路的多人環境的特點啦,所以我們在投票前一定要先用flock()函數把檔案鎖住,投完後再開啟檔案讓其它的進程進行操作,這樣才能防止出現上面的那類錯誤。下面是flock函數的用法說明。
flock 鎖住檔案。
文法: boolean flock(int fp, int operation);
傳回值: 布林值
函式種類: 檔案存取
內容說明 本函式用來鎖住檔案,使別的行程無法存取。傳入的參數 fp 為檔案的指標。參數 operation 的值為下列的數字之一:
1 、表示設定鎖住檔案可以允許別的行程讀取;
2 、表示只有該行程可以寫入檔案;
3 、表示讀寫均鎖住;
4 、不鎖住區塊 (block)。
而本函式無論在 UNIX 或是 Windows 系列中的鎖住效果都相近。執行成功則傳回 true 值,否則傳回 false 值。
好了,基礎的東西已經學完,讓我們來進行實戰吧!大家先下這個範常式序。然後可以在自己的平台上先試試看。相信這樣會得到一點感性認識。
在這個應用中一共使用了三個檔案vote.php,config.php,http://www.webjx.com/htmldata/2007-06-09/1.gif以及一個儲存資料的檔案(該檔案的名字可以自由設定,在這裡我們設為sum.txt),其中vote.php是主程式檔案,config.php則用於設定一些經常需要修改的資訊。
//config.php檔案
<?
//title變數設定本html檔中的title標記,也就是在瀏覽器標題列裡出現的標題
$title=讀者類型調查表;
//設定調查內容。這裡用了一個數組,注意用""號把內容括起來
$option= array("學生","工人","農民","知識分子","資本家","流氓");
//設定調查結果儲存到哪個檔案中去
$countfile = "sum.txt";
//設定同一機器可以再次投票的時間
$limitdate = time()+60*60*24*365;
?>
// vote.php檔案
/*首先將配置資訊裝進來,這裡我簡單說明一下 require和include的區別,require通常放在PHP 程式的最前面,PHP 程式在執行前,就會先讀入 require 所指定引入的檔案,使它變成 PHP 程式網頁的一部份。常用的函式,亦可以這個方法將它引入網頁中。 include 則一般是放在流程式控制制的處理區段中。PHP 程式網頁在讀到 include 的檔案時,才將它讀進來。這種方式可以把程式執行時的流程簡單化。 */
<?
require "config.php";?>
/*下面這部分就是cookie了,它的expire時間在上面的config.php中設定,另外大家可能已經發現了,在這裡有兩個 if比較語句,第一個是檢測是否已經有cookie設定,第二個則是為了避免人家還沒有投票程式就把cookie發出去。*/
<?
if (isset($vote) && $vote=="Ready") $status = 1;
else $status=0;
if ($ready=="true")
{
setcookie("vote","Ready",$limitdate);
}
?>
<html>
<head>
<title><? echo $title ?> </title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body bgcolor="#FFFFFF">
//讀出原來的選票結果,賦給變數$result
<?
if (file_exists ($countfile)){
$result = file($countfile);
}
?>
/*下面是主程式 用switch做了三個分支,Case 1、查看結果;Case 2、提交選擇;Case 3、產生表單*/
<?
switch ($elect) {
/* 查看結果,實際就是把上面用file()函數讀出來的變數顯示出來*/
case "查看結果":
echo "<table border="0">";
for($i=0;$i<count($result);$i++){
echo "<tr>"."<td>".$option[$i]."</td>";
echo "<td>"."<img src="http://www.webjx.com/htmldata/2007-06-09/1.gif" width="";
echo "$result[$i]*10";
echo "" height="8"> </td>";
echo "<td>"." ".$result[$i]."</td></tr>";
}
echo "</table>";
break;
/*把選擇結果寫入到檔案中去,注意要用flock把檔案鎖住!雖然對投票程式來說這個問題不是特別突出*/
case "提交":
if ($status == 1){
echo "你已經投過票了";
}elseif($sugest == 0){
echo "you havn"t choice";
}else{
if($fp=fopen($countfile,"w")){
if(flock($fp,3)){
for ($i=0; $i< count ($option); $i++){
if ($sugest == $i+1){
$result[$i]=$result[$i]+1;
}else $result[$i]=$result[$i] + 0;
echo $option[$i]." ".$result[$i]."<br>";
fwrite($fp,$result[$i]."n");
}
}else "投票失敗";
}else echo "投票失敗";
fclose($fp);
}
break;
/*顯示投票的表單*/
default:
echo "<form action="vote.php" method="post" name="form1">";
$sum = count($option);
for ($i=0; $i<$sum; $i++){
echo "<input type="radio" name="sugest" value=";
echo $i+1;
if ($i==0) echo " CHECKED";
echo ">".$option[$i]."<br>";
}
echo "<input type="hidden" name="ready" value="true">";
echo "<br>";
echo "<input type="submit" name = "elect" value="提交">";
echo "<input type="submit" name="elect" value="查看結果">";
echo "</form>";
}
?>
</p>
</body>
</html>
這樣一個簡單的php的投票應用就完成了,說它簡單是因為這個程式只完成了投票應用的幾個最重要的功能,還有一些細節問題沒有去處理。比如檔案寫失敗之後的處理,使用者關閉cookie功能的應付辦法等等。具體的完善就留給讀者朋友來解決了。