什麼是 PHP?
PHP 是一種伺服端描述語言,用來製作動態網頁。當一個網客開啟網頁時,伺服端便會處理 PHP 指令,然後把其處理結果送到網客的網頁瀏覽器上面。就好像 ASP 或者是 ColdFusion 一樣。然而,PHP 跟 ASP 或者是 ColdFusion 不一樣的地方在於,它是開放原始碼 (Open Source) 而且是跨平台的。PHP 可以在 Windows NT 以及很多不同的 Unix 版本執行,它也可以被建成一個 Apache 模組,或者是一個 CGI 的二元檔案(binary)。當被建成一個 Apache 模組時,PHP 是特別的輕巧而快速。在這種情況下,它沒有繁瑣的程序產生的負擔,因此可以很快的把結果跑出來,而且你也不需要特別為了保持伺服器不會佔太大的記憶體空間,而去調整 mod_perl。
除了能夠用來產生你的網頁的內容之外,PHP 也可以用來傳送 HTTP 表頭(header)。你可以設定 cookies,做授權管理,以及將使用者重新導向至新的頁面(redirect users)。它也提供了優良的資料庫連結功能(還有 ODBC 的連結功能),另外還有提供與各式各樣的外部檔案庫(library),可以讓你用來做幾乎所有的事情,上至產生 PDF 文件,下至解析 XML。
PHP 程式碼就在你的網頁中,因此你不必為它建立一個開發環境或整合性開發環境(IDE)。你用 <?php 開始一段 PHP 程式,然後以 ?> 做結束。(你也可以將 PHP 設定成使用 ASP 形式的 <% %> tag 甚至是用 <SCRIPT LANGUAGE="php"></SCRIPT>。) PHP 引擎會處理 tag 之間的任何東西。
PHP 語言的語法跟 C 還有 Perl 很像。在使用變數前,你不必先宣告他們。要建立陣列(array)以及雜湊(hash)或關聯性陣列也很快。 PHP 甚至還有一些基本的物件導向功能,幫助你組織以及封裝(encapsulate)你的程式。
雖然當嵌入 Apache 裡面時,PHP 跑得最快,但是在 PHP 網站上還是有些操作指南教你如何讓它能夠天衣無縫的與 Microsoft IIS 以及 Netscape Enterprise Server 結合。如果你手邊還沒有 PHP,你可以在它的官方網站下載取得。 你也會在那裡找到一份紀錄所有 PHP 功能以及特色的手冊。
PHP 語法
PHP 的基本語法看起來很熟悉。
<?php
echo "Hello, World!";
?>
產生如下結果
Hello, World!
變數則以 $ 為開端。你可以將上面的 "Hello, World!" 寫成這樣:
<?php
$message = "Hello, World!";
echo $message;
?>
字串的串聯(concatenation)則是用 .(一個英文句點)標示出來;其他有關數字的運算符號就如同你所預期的一樣:
<?php
$greeting = "Hello ";
$num = 3 + 2;
$num++;
echo "$greeting $num people!";
?>
會產生如下結果
Hello 6 people!
PHP 有全套的運算元(operator),它們的運作方式就如同你所預期的一樣 -- 特別是當你有 C 或者 C++ 的知識背景時。使用 PHP 的最高指導原則:「有疑問時,先試看看;你可能會成功。」
正如 Perl 一樣,一個字串用雙引號括起來,會使得其中的變數被置換(interpolate),而如果以單引號括起來,則變數不會被置換。因此,
<?php
$name = 'Susannah';
$greeting_1 = "Hello, $name!";
$greeting_2 = 'Hello, $name!';
echo "$greeting_1\n";
echo "$greeting_2\n";
?>
產生如下結果
Hello, Susannah!
Hello, $name!
注意一下,字串中 \n 字元是換行符號,就跟 Perl 或 C 一樣。不過這只在以雙引號括起來的字串內才有效。
變數
PHP 可以讓你把環境變數當作一般變數使用。這包括伺服器為了一個 CGI 程式所設定的環境變數(即使當你以模組的方式執行 PHP,也是如此)。因此, 如果這個網頁 "http://www.domain.com/farm/cattle/cow-cow.cow.html" 包含以下程式碼
<?php
echo "[$REQUEST_URI]";
?>
它會印出 [/farm/cattle/cow-cow-cow.html]
陣列(array)
你用方形括弧([ and ]), 指定陣列(一般或關聯性)的索引:
$fruit[0] = 'banana';
$fruit[1] = 'papaya';
$favorites['animal'] = 'turtle';
$favorites['monster'] = 'cookie';
如果你授與陣列一些值,但是索引是空白的,PHP 會把這個值所代表的物件設定到陣列的尾端。上面所列有關 $fruit 這個變數,以下面的方式授與變數值,其結果是一樣的:
$fruit[] = 'banana';
$fruit[] = 'papaya';
你也可以用多維陣列:
$people['David']['shirt'] = 'blue';
$people['David']['car'] = 'minivan';
$people['Adam']['shirt'] = 'white';
$people['Adam']['car'] = 'sedan';
一個建立陣列的捷徑為
array()
函數:
$fruit = array('banana','papaya');
$favorites = array('animal' => 'turtle',
'monster' => 'cookie);
你也可以
$people = array ('David' => array('shirt' => 'blue',
'car' => 'minivan'),
'Adam' => array('shirt' => 'white',
'car' => 'sedan'));
count() 內建函數是用來告訴你一個陣列裡面有多少元素:
$fruit = array('banana','papaya');
print count($fruit);
得到如下結果
控制結構
你可以利用迴圈結構例如 for 還有 while:
for ($i = 4; $i < 8; $i++) {
print "I have eaten $i bagels today.\n"; }
產生如下結果
I have eaten 4 bagels today.
I have eaten 5 bagels today.
I have eaten 6 bagels today.
I have eaten 7 bagels today.
還有以下程式碼也會產生同樣結果
$i = 4; while ($i < 8) {
print "I have eaten $i bagels today.\n";
$i++;
}
你可以利用控制結構 if 以及 elseif:
if ($user_count > 200)
{
print "The site is busy right now!";
}
elseif ($user_count > 100)
{
print "The site is sort of active right now!";
}
else
{
print "The site is lonely - only $user_count user logged on.";
}
運算元(operator)利用的最高指導原則同樣也可以運用在控制結構上面. 你還可以使用 switch, do...while,甚至是 ?: 程式結構。
一個簡單的表單
PHP 最方便的功能之一是,它能夠自動將表單(form)裡面的值塞到 PHP 的變數裡面。使得表單處理變得非常迅速。
因此,如果你送出一個內含輸入欄位值的表單如下:
<INPUT TYPE=TEXT NAME="name" VALUE="Glen Morris">
當你以 PHP 處理這個網頁,$name 這個變數的值就會是 Glen Morris。
因此,你可以用如下的方式把值印出來:
echo "Hi $name!";
或者像這樣測試它的值:
if ($name == "Glen Morris") { echo "Please check your email."; }
在這裡提供一個以 PHP 來處理基本表單的好方法。讓我們以範例來做說明,假設我們必須做一個簡單的問卷調查,填卷者必須填入他們的姓名,電子郵件住址, 以及回答一些我們感興趣而想調查的問題。
首先,我們會將網頁拆成兩個函數。因此,我們只要有一個 PHP 網頁,然後用程式邏輯去控制要給網客看的是什麼,就可以了。我們不用去寫兩個分開的網頁 (一個是表單部分,另外一個是用來處理表單的 CGI 程式)。
顯示表單
第一個函數用來顯示表單:
<?php
function display_form() {
global $PHP_SELF;
?>
<FORM TARGET="<?php echo $PHP_SELF; ?>" METHOD=GET>
Name:
<INPUT TYPE=TEXT NAME="name"><BR>
Favorite Cheese:
<INPUT TYPE=RADIO NAME="cheese" VALUE="brie">Very soft French Brie
<INPUT TYPE=RADIO NAME="cheese" VALUE="cheddar">Farmhouse English Cheddar
<INPUT TYPE=RADIO NAME="cheese" VALUE="mozzarella">Italian Buffalo Mozzarella Favorite Times to Eat Cheese:
<INPUT TYPE=CHECKBOX NAME="times[]" VALUE="m">Morning
<INPUT TYPE=CHECKBOX NAME="times[]" VALUE="n">Noon
<INPUT TYPE=CHECKBOX NAME="times[]" VALUE="d">Dinner
<INPUT TYPE=CHECKBOX NAME="times[]" VALUE="l">Late night
<INPUT TYPE=HIDDEN NAME="stage" VALUE="results">
<INPUT TYPE=SUBMIT VALUE="Thanks!">
</FORM>
<?php
}
?>
以上程式雖然大部分都只是產生表單所需的 HTML 程式,然而,還是有一些複雜的地方是我們必須加以說明的。
首先是 $PHP_SELF 變數。$PHP_SELF 變數是一個很方便的參考變數 -- 它的值就是目前網頁的 URL。我們把這個表單的 TARGET 設為 $PHP_SELF,因為我們要讓該網頁處理這個表單。藉由使用 $PHP_SELF 變數而非該網頁實際的固定路徑,我們可以任意將這個程式改名或更動位置, 而不必擔心每次用到這段程式碼時,都要特別去設定網頁的位置。
順帶一提,以下這一行
global $PHP_SELF;
的意思是說,我們要拿到 $PHP_SELF 這個全域變數。 在函數裡面所宣告的變數的範圍是區域性的(local scope),或者說,它能夠與在函數外面宣告的同名變數有不同的值。如果我們沒有明白的告知 PHP, 我們要的是全域變數 $PHP_SELF,我們會發現,$PHP_SELF 的值是空白的。
再來,你注意到,我們甚至在函數裡面轉進轉出 PHP 模式。這絕對是合法的語法。PHP 聰明到它會自動忽略所有在中間的 HTML 程式碼,只找下一段 PHP 程式碼的開端。這比起一直保留在 PHP 模式,然後用 echo 印出 HTML 碼還要快。
現在看到單選圓鈕(radio button)以及勾選方塊(check box) 的 NAME 屬性,你注意到 times[] 在後面跟著一對括弧,而 cheese 卻沒有。這是因為 radio button 只讓你選擇一個(正確的)答案,因此,cheese 的值只會有一個字串。相對而言,check box,讓你選擇數個答案。為了要讓 PHP 儲存這些答案,它必須將這些答案放到一個陣列裡面。而在 times 變數名稱後面加上 [],PHP 就知道它是一個陣列, 而非純量變數(scalar)。
最後,我們還有一個隱藏變數叫做 stage。我們用 $stage 來辨別是否要將表單顯示出來或者是要計算處理結果。
表單處理
下面接著是處理表單的函數,process_form()。
<?php
function process_form()
{
global $name;
global $cheese;
global $times;
if ($cheese == 'brie')
{
$cheese_message = 'I love brie.';
}
elseif ($cheese == 'cheddar')
{
$cheese_message = 'Cheddar is awesome!';
}
else
{
$cheese_message = 'Fresh mozzarella is divine.';
}
$favorite_times = count($times);
if ($favorite_times <= 1)
{
$times_message = 'You should eat cheese more often.';
}
elseif ($favorite_times > 1 && $favorite_times < 4)
{
$times_message = 'Those are good times to eat cheese.';
}
else
{
$times_message = 'You are eating too much cheese.';
}
echo "Hello $name.";
echo "$cheese_message $times_message";
}
?>
首先,就如同我們先前處理 $PHP_SELF 的方式一樣,我們擷取表單裡面的全域變數。然後我們檢查 cheese 選項裡面,哪一個被點選,以便按照選項編撰我們的回應。
下面,我們使用 count() 函數,以便計算有幾個時段是被選為偏好的時段。 在過去,我們必須檢查吃 $cheese 時段的每一個可能的值, 現在我們只要利用「大於」,「小於 」來比較 $favorite_times 的大小,就可以了。如果你不知道,在比較 "$favorite_times > 1 && $favorite_times < 4" 中,&& 所代表的涵義,它其實是表示 "and"。因此,$favorite_times 必須大於一而且小於四,這個條件才能成立。
在程式最後面,我們印出網路用戶的名字。當然,你也可以做各式各樣有趣的變化,例如,將這個資訊存在資料庫裡面,或者是你也可以查詢某種資料庫, 然後將查詢結果以整齊的方式表達出來。
將表單組合起來
現在既然我們有這兩個函數了,接著我們只要再放入一小段程式,就可以把它們湊在一起,並且建立我們的程式需要的邏輯走向。好啦,現在就在 display_form() 以及 process_form() 下面加入以下這段程式碼:
<?php
if (empty($stage)) { display_form(); }
else { process_form(); }
?>
首先,我們看看 $stage 變數值是否為空白。在 PHP 的規則裡,一個變數如果未曾給值(也就是未曾有授與該變數某值),或者它的值是 nothing(也就是它的值是 "nothing", 即空白字串或者是零),那麼,該變數就被視為空白。當網客第一次造訪我們的網頁時,$stage 變數值是空白的。因此我們要做的是顯示表單;否則的話,我們做表單內容處理。
以上就是如何使用 PHP 處理表單。
一個多頁表單
當然,我們還沒全部講完。畢竟,如果你可以在一個頁面上建立多個表單,為什麼你不能建立跨頁面的多個表單呢?
不幸的是,想用 HTTP 程式碼來從一個頁面傳送資料到另一個頁面並不容易。那是因為在 HTTP 的通訊協定裡面並沒有內建的功能規範所謂的一連串的頁面。 不過,還好,只要透過一點小小的聰明技巧,再加上 PHP 某些便利的函數,我們就可以比較不用花太多力氣,而能突破這個限制。在這一個章節裡面,我們使用的主要的概念是,我們會把所有從上一個頁面的輸入的資料,放在下一個頁面的表單的隱藏變數裡面。因為在當我們的螢幕頁面一頁一頁的更換時,程式碼也跟著在頁面之間傳送資訊, 所以每一個表單都會內含上一個表單的資料。這個方法有點笨拙,不過目前為止這是最簡單的方法 -- 而且它不必用到資料庫或 cookies。
你應該猜得到,我們將延伸使用 $state 變數,來執行這種功能。 其實,這就是為什麼我們剛剛帶你走過與此相關的技巧,而沒有用比較簡單的方式處理在單一頁面的表單。
為了方便起見,讓我們重複使用先前的表單範例。只是這一次,我們會把它們拆成兩個頁面,而非把用戶名稱跟有關乳酪的重要問題放在一個頁面上。
所以,我們會有三個函數而非兩個。此外,我們還會把它們的名字變更,以反映內容的改變。display_form() 現在已經被改名為 display_name()。
<?php
function display_name() {
global $PHP_SELF;
?>
<FORM TARGET="<?php echo $PHP_SELF; ?>" METHOD=GET>
Name: <INPUT TYPE=TEXT NAME="name"><BR>
<INPUT TYPE=HIDDEN NAME="stage" VALUE="cheese">
<INPUT TYPE=SUBMIT VALUE="Thanks!">
</FORM>
<?php
}
?>
這跟我們先前所介紹的函數一樣,不過我們把名字以下的問題抽出來,另外還把 stage 的名稱改為 cheese 如此一來,比較正確的告訴用戶, 下一步要做什麼。
再來是 display_cheese()。
<?php
function display_cheese() {
global $PHP_SELF;
global $name;
?>
<FORM TARGET="<?php echo $PHP_SELF; ?>" METHOD=GET>
Favorite Cheese: <INPUT TYPE=RADIO NAME="cheese" VALUE="brie">Very soft French Brie
<INPUT TYPE=RADIO NAME="cheese" VALUE="cheddar">Farmhouse English Cheddar
<INPUT TYPE=RADIO NAME="cheese" VALUE="mozzarella">Italian Buffalo MozzarellaFavorite Times to Eat Cheese:
<INPUT TYPE=CHECKBOX NAME="times[]" VALUE="m">Morning
<INPUT TYPE=CHECKBOX NAME="times[]" VALUE="n">Noon
<INPUT TYPE=CHECKBOX NAME="times[]" VALUE="d">Dinner
<INPUT TYPE=CHECKBOX NAME="times[]" VALUE="l">Late night
<INPUT TYPE=HIDDEN NAME="name" VALUE="<?php echo htmlspecialchars($name); ?>">
<INPUT TYPE=HIDDEN NAME="stage" VALUE="results">
<INPUT TYPE=SUBMIT VALUE="Thanks!">
</FORM>
<?php
}
?>
以上的程式碼看起來應該非常熟悉。除了我們在印出隱藏的 stage 以前,先印出上一頁 $name 變數的名稱跟內含的值之外,我們並沒有做任何你預期不到的修改。我們並沒有直接把值印出來,而是透過一個叫做 htmlspecialchars() 的 PHP 函數。在 HTML 程式碼中,有四個字元除了當作標記(markup)用之外,在其他地方是不應該被使用的:<, >,", 以及 &。因此,為了確保我們不會使得網頁瀏覽器昏頭轉向,我們透過 htmlspecialchars() 使用 $name 變數。如此一來,某個人的名字誤為 "Bret & Jeff" 就會是 "Brett & Jeff" 了。
現在,當這個新表單傳送出去時,我們不會漏失任何資訊。
透過以上技巧,我們不必更改原來 process_form() 函數的一字一句。事實上,我們還會保持函數名稱不變。我們只須加上一行邏輯敘述。
<?php
if (empty($stage)) { display_name(); }
elseif ($stage == 'cheese') { display_cheese(); }
else { process_form(); }
?>
你看到了嗎?我們只要把先前的兩個敘述中間塞入 elseif 。這就是使用 $stage 變數的巧妙之處。如果我們要再加幾個頁面, 我們只要寫一個新的函數,以顯示我們要的,然後再加一行控制邏輯來控制它何時顯示頁面即可。
Cookies
用 PHP 來設定以及讀取 cookie 是一件極其簡 -- 我們敢說嗎?-- 單的事情。我們不想要大力鼓吹 cookie,不過它們實在既重要又有用。有時候,在做某些事情時,它們是唯一適用的工具。
要建立並修改一個 cookie,你可以使用 PHP 函數 setcookie()。取決於你想要控制 cookie 的程度,以及誰可以讀取它的值,setcookie() 最多可有六個參數。
設定 cookie 最簡單的方式如下:
setcookie('name', 'bret');
然後,在用戶登出之前,接下來每一個使用同樣的瀏覽器觀看的網頁,都會有一個內含值為 'bret' 的變數 $name, 如此一來在 PHP 程式碼裡,就可以很容易取得這個值。這類 cookie 被稱為 session cookie,因為它的生命週期是一個用戶連結(user session)的時間。
如果你要在用戶關閉他的瀏覽器之後,保留這個 cookie,你必須傳送第三個參數給 setcookie() 函數,亦即設定這個 cookie 的有效日期。既然 PHP 的整體出身背景是源於 Unix 的人們腦中,你可以把這個有效期限以從 1970 年一月一日起算的總秒數來代表。 如果你是個 Unix 程式設計師,這種算法對你而言可能是合理合理的。但是,如果你是來自 Windows 或 Macintosh 背景的人,你可能只能搖頭嘆息,不知道那些 Unix 陣容的怪傢伙在想些什麼。
不要害怕。PHP 提供一個很好用的函數 mktime()。 你只要照順序傳送給 mktime() 你想要表示的小時,分鐘, 秒數,月份,日期,以及年份,mktime() 就會回傳給你該日期自從 1970 年一月一日的總秒數。因此,如果你要模擬 Y2K 問題:
<?php
$y2k = mktime(0,0,0,1,1,2000);
setcookie('name', 'bret', $y2k);
?>
現在,你的 cookie 將會在千禧年失效。
如果你想更新 cookie,讓它儲存新的值,你只要把它原來的值蓋掉即可。因此,即使你已經在過去幾頁裡面送出剛剛的 cookie 了,你還是可以把名字改為 "jeff"。
<?php
$y2k = mktime(0,0,0,1,1,2000);
setcookie('name', 'jeff', $y2k);
?>
請注意,這樣做並不會改變變數 $name 的值。它在當初網頁載入的時候,就已經定下來了。如果你想要同時改變 cookie 以及 $name 變數,你可以編寫程式如下:
<?php
$name = 'jeff';
$y2k = mktime(0,0,0,1,1,2000);
setcookie('name', $name, $y2k);
?>
setcookie() 的下兩個參數可以讓你控制從哪個網域, 哪個目錄路徑送來的程式碼,才可以讀取你的 cookie。原本的設定是,只有在與送出 cookie 的同一個伺服器且同層級或以下的目錄架構內的程式才可以讀取 cookie,這是為了網路安全起見而做的設定。然而,如果你有一個網路帳號,是 "www.domain.com" 但也是 "other.domain.com" 而且你的帳戶允許你從 ~/myhome 目錄送出動態網頁,你就應該如下更改你的 setcookie():
<?php
setcookie('name', 'jeff', $y2k, '~/myhome', '.domain.com');
?>
setcookie() 的最後一個參數,我們從未用過,是設定 cookie 只傳送給有實行安全保密連線諸如 SSL 的網頁伺服器。要使這項功能生效,只要把第六個參數設為一。
刪除掉 cookie 很簡單,只要將你的 cookie 的名次傳送給 setcookie(),PHP 就會安排把它刪除掉。
<?php setcookie('name'); ?>
最後一個有關使用 cookie 的重要的事項是,因為 cookie 與 HTTP 的某種協定方式,你必須在你印出任何文字前,把所有的 cookie 傳送出去。否則的話,PHP 會送給你一個警告,然後你的 cookie 也不會被傳送出去。因此,這樣做是對的:
<?php
setcookie('name', 'jeff');
echo "Hello Everyone!";
?>
但是你不可以這樣做:
<?php
echo "Hello Everyone!";
setcookie('name', 'jeff');
?>
日期及時間
PHP 有很多便於使用的函數,可以幫你顯示及操作日期。
要以某種格式顯示日期或時間,使用 date() 函數。它需要兩個參數: 一個是要如何顯示日期的格式,另一個是代表你所要顯示日期的時間。這個時間必須是先前所提自從 1970 年起算的總秒數。(如果你要使用現在的時間,你可以使用 time() 函數,這個函數會回傳「現在」這個時間的秒數。) date() 有一拖拉庫的格式選項,就跟 C 語言的 strftime() 函數或者 Perl 語言的 POSIX::strftime()函數一樣。
<?php //小時,分鐘, 秒數,月份,日期,以及年份//
$birthday_stamp = mktime(19,45,0,3,10,1975);
$birthday_formatted = date('F d, Y - g:i a',$birthday_stamp);
echo "David was born on $birthday_formatted."
?>
程式碼會產生結果如下
David was born on March 10, 1975--7:45 p.m.
當然,如果你要的是某個已知的特定日期,這種花俏的格式函數並不會有多大用處,因為,你事先已經知道你的格式會是什麼。這些函數會當在某個表單中,需要網路用戶選擇某日期的時候,會比較有用:
<SELECT NAME="when">
<?php
$d = time();
for ($i = 0; $i < 10; $i++) {
echo '<OPTION VALUE="'.$d.'">'.date('F d',$d);
$d += 86400;
}
?>
</SELECT>
以上會引出一個選單,其中有十個選擇 -- 今天以及以後九天。在程式中迴圈敘述開始之前,我們會將現在時間存在 $d 變數裡面。某一個 <OPTION> 的值會被印出來, 其中的值會是以 Unix 算法計算的總秒數,而且所顯示出來的文字設定為月份以及日期("July 27," "July 28," 等等。)在顯示過 <OPTION> 的值後,$d 變數會被加上 86,400(這就是一天二十四小時的總秒數 -- 24 小時 * 60 分鐘 * 60 秒)。
將 mktime() 以及 date() 合用,你就可以得出關於某個用戶輸入日期的相關資訊。那如果你要尋找從某個日期算起的第一個星期天(或者一個禮拜中的任一天)呢?首先,你先編寫一個會印出適當格式的函數:
<?php
function display_form() {
global $PHP_SELF;
$dotw = array('Sunday','Monday','Tuesday','Wednesday','Thursday',
'Friday','Saturday');
$months = array( 1 => 'January','February','March','April','May','June',
'July','August','September','October','November','December');
?>
<FORM TARGET="<?php echo $PHP_SELF; ?>" METHOD=GET>
Find the first
<SELECT NAME="dotw">
<?php
for ($i = 0; $i < 7; $i++) {
echo "<OPTION> $dotw[$i]";
}
echo '</SELECT> after <SELECT NAME="month">';
for ($i = 1; $i <= 12; $i++) {
echo "<OPTION VALUE=\"$i\"> $months[$i]";
}
echo '</SELECT> <SELECT NAME="day">';
for ($i = 1; $i <= 31; $i++) {
echo "<OPTION> $i";
}
echo '</SELECT>, <SELECT NAME="year">';
$start_year = date('Y') - 10;
$end_year = $start_year + 20;
for ($i = $start_year; $i <= $end_year; $i++) {
echo "<OPTION> $i";
}
echo '<INPUT TYPE="HIDDEN" NAME="stage" VALUE="process">';
echo '</SELECT> <INPUT TYPE="SUBMIT" VALUE="Do it!"7></FORM>';
}
?>
這當中含有一些函數是我們到目前為止還沒討論到的。$months 陣列寫得有點不一樣, 因為我們要讓一月份的陣列索引為 1,而非 0。另外,以程式自動產生這個表單要比將所有這個表單元素的值一一手動列出,要來得簡單多了,因此 display_form() 函數中唯一不是屬於 PHP 模式的部分,在於表單的開端部分。還有,使用 date('Y') 設定 $start_year 變數以及 $end_year 變數,讓我們能夠方便計算今年算起十年前以及十年後的時間範圍。
下面是處理表單的函數:
<?php
function process_form() {
global $dotw;
global $month;
global $day;
global $year;
$timestamp = mktime(0,0,0,$month,$day,$year);
$next_dotw = '';
$next_timestamp = $timestamp;
while ($next_dotw != $dotw) {
$next_timestamp += 86400;
$next_dotw = date('l',$next_timestamp);
}
$formatted_first = date('F d, Y',$timestamp);
$formatted_next = date('F d, Y',$next_timestamp);
echo "The first $dotw after $formatted_first is $formatted_next.";
}
?>
首先,這段程式碼將所得到的日期以 Unix 方式計算總秒數。如果我們要更固執,更謹慎的話,我們可以加某些程式碼,以便檢查所得到的日期是否在合法的日期範圍內,不過在這裡我們沒有必要這樣做。
接下來的迴圈敘述,只要我們要尋找的某個日期的下一個星期數,不是網路用戶所輸入的要找的那一個星期數,就會一直迴圈下去。當星期數不一樣時,日期所代表的總秒數就會被增加(又是那個 86400 秒 = 24 小時 * 60 分鐘 * 60 秒)然後那個秒數所代表的星期數就會被重新計算。
一旦星期數一致了(equal),process_form() 函數就會印出一行訊息:
The first Sunday after June 25, 1999 is June 27, 1999.
我們也需要那個大家都熟悉的主要敘述,將這些函數綁在一起:
<?php
if (empty($stage)) { display_form(); }
else { process_form(); }
?>
日期處理程式碼有時需要再複雜一點,才能處理日光節約(daylight savings time)時間,還有不同的時區,不過 date() 以及 mktime() 函數都是基本的變換 Unix 總秒數的函數, 它們操作簡單,而且也以易讀易懂的方式,表達日期跟時間。date() 以及 mktime() 函數以你的機器所在時區來操作時間。如果你想要用格林威治時間(GMT),你可以使用 gmdate() 以及 gmmktime()。
例如,在一部處於美國東部日光節約時間的機器(落後格林威治時間四小時):
<?php
$today = mktime(12,0,0,6,25,1999);
echo 'Here it is '.date('g:i:s a, F d, Y',$today);
echo '';
echo 'In GMT it is '.gmdate('g:i:s a, F d, Y',$today);
?>
會產生如下結果
Here it is 12:00:00 pm, June 25, 1999
In GMT it is 4:00:00 pm, June 25, 1999
結論
PHP 是個很不錯的工具,為你的網站帶來動態的網頁內容。它所使用的語法感覺起來不陌生,而且也不會佔用多大的電腦資源 -- 還有你也不必為必須注意很多繁瑣的細節而感到沮喪,你所需要的只是寫簡單的描述語言。
這篇文章中所介紹的只是 PHP 語言強大功能的開端。PHP 還可以讓你從各式各樣的資料庫擷取以及儲存資料,包括: MySQL,Oracle, Microsoft SQL Server,還有很多其他資料庫軟體。你可以隨時製作以及修改影像。你可以使用 regular expression 操控文字資料。 你可能被這一連串英文縮寫所搞混了,不過你可以用 IMAP,LDAP,PDF,SNMP,WDDX,XML,等等,來改善你的程式。
想知道有關 PHP 的最新資訊,你可以到它的官方網站。另外,其線上使用手冊 則是用來查詢如何使用某些函數好地方。你甚至可以跟那些 PHP 程式設計師夥伴們分享你的想法。因此,本質上,連手冊都是開放原始碼(open source)的。
你果你有興趣與 PHP 社群的愛好者們做互動,這裡有個討論區,所有的主要程式開發工程師都會來這裡看看並且回答一些問題。客戶支援網頁 上面有更多有關這個討論區的資訊,同時它也提供其他有用的資源。