首頁 >後端開發 >php教程 >PHP學習寶典-第九章

PHP學習寶典-第九章

黄舟
黄舟原創
2016-12-23 09:54:231236瀏覽

網頁間的訊息傳遞

本章重點

為什麼HTTP會生生不息地擴散?

GET參數

另一種使用GET風格式樣的URL

處理窗體變數

PHP超數組

本章簡單講解一些有關在Web頁之間傳遞資料的內容。這樣的一些資訊不是PHP特有的,而是PHH/HTML或HTTP協定本身很重要的部份。

HTTP是沒有狀態紀錄的(stateless)

需要記住有關Web服務一項最重要的事情是,HTTP協定本身沒有狀態紀錄的(stateless)。如果讀者有詩意的靈魂,可能會說每個HTTP請求(request)孑然一身,沒有家園,就像一個全然未知的……你知道這類的說法。對缺乏詩意的我們,說白點就是指每個HTTP請求(每一次的請求和傳送頁面)獨立於所有其它的內容、不知道客戶端身份,而且也沒有記憶。每個請求產生一個獨立過程,完成一件檔案服務、看似微小卻重要的任務,然後自動消失(這樣呼起來很無情,或許可以說成「回到可處理的狀態」)。

即使把網站設計成非常不嚴格的單嚮導航(頁1引導至頁2,頁2引導到3等等),PTTP協助從來不知道也不關心某個人瀏覽的頁2是否來自頁1。因此,不可以把頁1上的變數設定成透過HTML本身來匯入該頁。可以使用HTML顯示窗體,用窗體輸入一些訊息,但是除非用一些別的方法把訊息傳送到另一頁或另一個程序,否則一旦移到另一頁,變數就消失了。

這是為什麼導入像PHP這樣的窗體處理技術的原因。 PHP可以擷取從一頁輾轉傳到另頁的變量,能對它進行更進一步的動用。 PHP函數剛好非常擅長這種型態的資料傳遞函數,這樣可以更快、更輕鬆地完成各種Web網站的任務。

HTML窗體是網站上用來由一個網頁傳遞一些資料最有用的方法,有許多更持久的方式可以維護橫跨許多網頁的狀態方法,例如cookie與session,我們會在第27章介紹這些功能。本章會著重在更基本的技術巧用來傳遞網頁之間的訊息,就是使用HTTP和GET與POST方法來進行動態產生網頁以及處理資料。

ASP程式設計者看到這裡可能要說「PHP真爛!」因為他們讓為ASP的session變數是非常神奇的。這不是要截破誰的泡泡,而是微軟正打算利用cookie來儲存session變量,不過這樣就打開了所有潛在問題的大門。

GET參數

GET方法把參數當成URI [Uniform Resource Indicator,一致資源指示器;也有人更習慣用URI (Uniform Resource Indicator,一致資源定位器)]查詢字串的一部分,從一個頁面傳遞到另一個頁面。當用於窗體處理時,GET用問號(?)當成分隔符號把變數名稱和值附加給在ACTION屬性中來反指定的URL,並把所有內容提交給提供處理的技術(在這個例子中是Web伺服器)。

這是一個使用GET方法的HTML窗體範例(把檔案存在team_select.html):





A GET example, HEAD >

A GET example, part 1 /HEAD >





Root, root, root for the :

Root, root, root for the :



當使用者進行選擇並按一下Submit按鈕時,瀏覽器按照下面的順序把這些元素接合、一起,中間不會有空格:

在單字ACTION後面,括在引號中的URL(http://localhost/baseball.php)

問號(?)指示以下字元即會組成GET字串

NAME變數、等號、以及配合的VALUE(Team = Cubbies)

「 &」符號與下一對「NAME = VALUE」(Submit = Submit);只要伺服器查詢字串的長度限制允許,這些使用&區隔的name – value組合可以重複許多次。

這樣會構成這樣一個URL字串:

(http://locahost/baseball .php ? Team = Cubbies&Submit = Select)

其中字串成為新的請求傳送到瀏覽器的位址空間。上面的窗體提交後,處理窗體的PHP script(baseball.php)將從請求字串的尾端取得GET變量,並對這些變數進行相對應的操作,在下面這個例子中,就是把兩個值中的一個插入文字字串中。

以下程式碼是PHP用來處理原先HTML窗體的窗體處理部分:

 



A GET example ,part 2 = “text/css”>


BODY {font-size: 24pt;}

-- >
🎜





Go,




/DY /HTML >

最後你應會看見網頁上呈現大字樣的Go,Cubbies。

窗體處理中的GET方法有一個比POST方法好很多的優點:它建立了一個真正新的、完全不同的URL查詢字串。如此一來使用者就可以把這一頁記為書籤(當開發小組意志消沉時,看到這篇就能鼓舞士氣了)。從使用POST方法的表單所得到的結果是不能記成書籤的。

然而,你可以用GET參數完成想要的功能不代表你應該使用,對於大多數表單處理程序,GET方法的缺點實在是太嚴重了,以致於最初的HTML 4.0正式規格不贊成使用它。這些缺點包括:

GET不適合用於登入(login),因為把使用者名稱和密碼當成訪問過的面潛藏儲存有用戶端瀏覽器的記憶體中時,在螢幕是也是完全可看見的。

每個GET提交都被記錄在Web伺服器log中,資料集也包括在內。

因為GET會分配資料到伺服器環境變數,所以URL的長度有受到限制。你可以想像使用GET時非常長的URL是長什麼樣子,不過事實上誰也不想用這種方法嘗試傳遞三百字的HTML格式的文章。

初使的HTML正式規格中對查詢的字符串長度的限制是255個字符,雖然後來放寬了對255個字符的限制,但是使用很長的字符串真的是自尋煩惱。

在進行過很多爭論後,W3仍然恢復使用表單處理中的GET方法,主要是由於書籤功能的因素。雖然GET方法仍然是表單處理的預設選取項,但我們還是建議你只把它用於沒什麼副帶作用於的地方。將兩個優點和兩個缺點放在一起考慮思量一番,使用GET處理表單的最適合的用途其實應該是「搜尋方塊(search box)」。除非迫不得已的原因才把GET方法用在非搜尋性的表單處理程序,不然你就用POST方法來取代。

一種更好的GET風格URL用法

雖然對表單處理GET方法已經被建議不採用了。但是和它相關的URL風格對於網站的導航還是非常有用的,尤其適用於動態廣告的網站,例如那些經常用PHP建構的網站,因為附加了變數格式的URL,就非常適合以樣版當基礎的內容發展系統。

有如下例所示,假設你所經營的是一個關於太陽能汽車資料豐富的Web網站,而你已將冗長且一致格式的資料豐富與誘有頁面存放如下:

suspension_design.html

windtunnel_testinging .html

friction_braking.html

但是當網站規模增大時,如此簡單的檔案網站結構就要耗費很多時間進行管理,因為一些瑣碎的變動都必須在每個頁面上重複進行。如果這些頁面的結構非常簡單,就可以用PHP把網站轉換成以樣版基底的系統。

你可能決定用一個單一的樣版來將每個主題的文字檔案區分(包括資訊、照片、意見,等等):

topic.php

suspension_design .inc

windtunnel_testing . . inc 

或是你可能決定一個更大、更為特殊選擇處理的樣版檔案:

vehicle_structure . php

tubular_frames . inc

mechanical_systems . . php 

solar_array . inc

racing . php 

race _strategy . inc

一個簡單的樣版可能有如此例所示(因為我們未含括所需的.inc文字檔案,這個檔案將無法實際運作):





Solar – car topics




-- >













Friction braking



Steering


Suspenion





Tires and wheels










“#FFFFFF” ALIGN = LEFT VALIGN=TOP WIDTH = 75% >









請注意,當被按一下時導覽列上的連線會被瀏覽器處理,就像是提交一個GET處理一樣。

但是對於這個處理方案,仍然必須手動更改一部分程序碼:以確保每個被包含進去的檔案都是正確的HTML格式,每次給網站添加新頁面時讓導航欄加入新的連接,以及其它類似的內容。盡可能按照一般常規把表單和內容分開,你可以選擇使用資料庫。若使用資料庫,URL就會類似如下:

(http://localhost/topic .php ?topicID = 2)

它將指向某個處理資料庫呼叫的PHP樣版(使用數字變數而不是使用單字可以更快查詢資料庫)。當為資料庫新增新的主題時,該系統會幫導航列加入連結,所以不用手動就可以產生所有的Web頁面(這裡的「所有」一詞是有些誇大了,但是的確可以省去人員與時間的多餘勞力)。

POST參數

POST是目前相對好的表單處理方法,尤其適合需要不是一次使用完的情況(指定長期配合處理的一些資料或作用),例如在為資料庫添加資訊的處理。當表單資料傳送到處理程序(這裡指PHP)時,被包含在表單本體內。提交的資料不同時,在URL看不出任何變化。

POST方法有以下這些優點:

◎ 它比GET更安全,因為在URL查詢字串、伺服器log中,或在螢幕上(如果採用了預防措施,例如總是使用HTML的password輸入格式來表達密碼欄位)看不到使用者輸入的資訊。

◎ 對能被傳遞的資料的數量限制更寬鬆了(可到二千個元組,而不只是二百多個字符)。

不過POST也有一些缺點:

◎ 其結果不能被標記為書籤。

◎ 這種方法和某些防火牆設定不相容,為了安全上的考慮,防火牆會去除某些表單資料。

在本書中我們一致使用POST方法來處理表單,尤其在使用寫入檔案或INSERT的SQL語法將資料填入系統時。我們只在網站的瀏覽與搜尋方塊才會使用GET的方法,換句話說,使用時機分別為將資料寫到資料儲存位置以及顯示網頁,本章其餘表單皆會使用POST方法。

同時使用GET和POST方法

你知道嗎? PHP允許在同一頁上同時使用GET和POST變數,因此可以自在地編寫動態表單!

但是這樣立刻引發一個問題:如果在GET 和POST陣列中(故意或由於其原因)使用同樣的變數名稱會怎麼樣呢?如果你將你的php .ini檔案內的register_globals指令設定為on的話,PHP把ENVIRONMENT、GET、POST、COOLIE與SERVER 等變數存放在$GLOBAL陣列中,如果產生衝突的話,它會根據你所設定的順序來重新調整變數內容來解決,藉由你在php .ini內的變數_order選項設定。較後者會取代前者,所以如果你使用預設的“EGPCS”值的話,POST會取代GET,COOKIE會取代POST,你可以藉由在這個檔案內適當調整字母的順序來控制取代的順序,或是甚至最好將register_globals關閉並使用PHP新的超全局陣列,我們會在以下部分介紹。

在PHP中的變數處理

PHP對於傳遞資料非常有效率是因為開發者決定使用一項很方便但(在理論上)有點複雜的設計。當使用GET或POST方法提交資料集時,PHP會自動擔以看不見的方式為新頁面上的變數地行指定。其它大多數的程式語言讓程式設計者自己在頁面上執行明確顯生的指定處理;如果忘記指定或寫錯了,則資訊就不能傳到處理代理程式中。相較之下,PHP更快、更簡單,更能防呆。

但是由於這樣的自動變數指定,你必須永遠為每個INPUT控制項取一個好的NAME屬性,其實NAME屬性並不是HTML強制需要的,你的表單即使少了它仍可以運作正常,但是資料將會沒有任何功用,因為這些HTML的NAME表單欄位屬性將會是表單處理程序的變數名稱。

換句話說,以下的表單:

” METHOD =“POST” >







email文字欄位將會使得當表格傳送時PHP產生變數為$_OPET[ 'email'](或是如果你使用舊式的陣列變數則為$ HTTP_POST_VARS[ 'email'],甚或是你將register_globals啟動則為$email),同樣的,傳送按鈕會使得下一個網頁產生$_POST ['submit']變數,你在HTML表單所使用的名稱將會成為你PHP表單處理的變數表單欄位。

另外一個產和生HTML表單必須記住的就是如果你希望表單在填寫之前顯示初始字樣的話,你必須設定VALUE屬性,這特別有用在兩種類型的表單上:用來將資料輸入資料庫的表單,以及用來傳送超過一次的表單,其中後者常常出現在表單需要在出現填入錯誤時重新顯示表單的情形,例如,一個用來登入的表單會直到使用才輸入有效的email地址或是其它相關資料才能送出。

例如,以下的表單(用來當作退休金試算表)被設計為當使用者填入資料時可以傳送多次,每當你傳送表單,你前一次所填入的次料會自動填入,請注意以下程式範例表單欄位的VALUE屬性。





A POST example:retirement savings worksheet




.heading {font-size:18pt; color:red}

-->










//will check to see if the form is being rendered for the first time

//(in which case it will display with only the default annual it / )

If (!IsSet($_POST[′Submit?])||$_POST[′Submit?]!=′Calculate?){

$_POST['CurrentAge'] = “”;

$ 'RetieAge']= “”;

$_POST['Contrib']= “”;

$Total = 7;

}else{

$AnnGain = $AnnGain'];AnnGain']; = $_POST['RetireAge'] - $_POST['CurrentAge'];

$YearCount = 0;

$Total = $_POST['Countrib'];

While($YearCount$Total = round($Total *(1.0 + $AnnGain/100)+$_POST['Contrib']);

$YearCount = $YearCount+1;

}

}
}
?
? BODY >

A retirement – savings calculator



Fill in all the values(exceptand much money you′ll have for your retirement under different scenarios.You can change the values and resubmit the form as many times as you like.You must fill in the two “Age”variables.The “Annual return” vaultable ust fill in the two “Age”variables.The “Annual return” vaultable has ahas ahas dation -adjusted value (7% = 8% growth minus 1% inflation)which you can change to reflect your greater optimism or pessimism.







The age at which you plan to retire:


NAME = “RetireAge”VALUE = “” >

Annual contribution:〈 INPUT TYPE=“text” SIZE=15 NAME=”Contrib“ VALUE=” “ >

Annual return: ” > %



NEST EGG:












圖9-1顯示上述程式的結果.

PHP學習寶典-第九章

圖9-1顯示上述程式的結果.🎜🎜🎜🎜圖9-1顯示上述程式的結果.🎜🎜🎜🎜圖9-1顯示上述程式的結果.🎜🎜🎜🎜圖9-1顯示上述程式的結果.🎜🎜🎜🎜圖9-1顯示上述程式的結果。

圖9-1:使用方法與VALUE屬性的表單


強化表單與表單處理

如同你可以在上述程序所見,通常將HTML表單與表單處理程序放在同一個程序是簡易的,這樣的方式有許多優點,例如,你的登入網頁將會在登入失敗時顯示錯誤訊息,如果你將表單處理程序分開的話,你可能還需額外藉由GET變數來重新轉址,如果你強化表單運作的話,你可以更加簡易的控制顯示而不需使用如此的機制。

當你強化表單的時假,表單處理程序應該出現在表單顯示之前,有人可能會讓為因為先設計表單才處理程序所以應該將順序顛倒,但是如果你按照這裡的方式,你便會了解其間的邏輯,你必須使你能夠先將變數名稱取好並且在顯示表單之前做選擇,這對如果你在某些情形必須將使用者導向不同的網頁,藉由使用header ()函數,更重要的,因為這個決定必須在任何HTML輸出顯示在瀏覽器之前就變成了。

 以上就是PHP學習寶典-第九章的內容,更多相關內容請關注PHP中文網(www.php.cn)!


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn