酷!學園

技術討論區 => 程式討論版 => PHP程式設計討論區 => 主題作者是: Darkhero 於 2005-06-20 05:16

主題: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: Darkhero2005-06-20 05:16
不知道為什麼半夜四點忽然醒來睡不著....就來寫寫文件好了....

SA.PHP觀念教室 首部曲:了解$_POST,$_GET

前言: 各位親愛的SA學員們好,本觀念教室不會教你寫php程式,所以要是你抱著在這就會學到寫程式的,恭喜你來錯地方了.
這個叫做觀念教室.只教程式語言的觀念,不教程式撰寫方法.

預期本堂的學員程度:


緣起: 說到 php 的$_POST跟$_GET這兩個變數,得從PHP4.1開始帶來的變化說起.

想當初php開始發展的時候,開發人員為了方便操作各種變數與網頁傳進來的值,所以就採用了將所有的不管是client傳進來的變數值,跟Server 端自動產生的變數值,都自動以 $變數名稱 存在於整個php程式中.
所以當你在當時(php4.1 以前,也就是 php3 ~ php4.0 的時代),會很習慣使用各種 $變數名稱,或是從使用者送出的表單之中的輸入欄位名稱為變數 $欄位名稱.

問題:但是這種情況,在php發展到了一定的規模後,遇到了一個問題.

這個問題主要在於安全上的隱憂!
客戶瀏覽器傳入的值,與系統自動產生的變數,或是系統內部變數,甚至是程式當中的原有變數產生衝突怎麼辦??...
要是程式當中有個 $subtotal 是存放購物金額的. 但是傳入的表單欄位中不知道為什麼不小心多打了個 subtotal 呢?... 程式會以哪個為準?...
要是cookie之中的變數名稱與我要用的程式變數名稱重複了?.....

$_POST與$_GET等變數陣列誕生: 如此多的問題困擾著開發php程式的開發人員,也讓php產生了很多安全上的隱憂, 所以php開發團隊當初建議使用者,使用像是 $HTTP_SERVER_VARS ,$HTTP_GET_VARS ,$HTTP_POST_VARS ,$HTTP_COOKIE_VARS 等陣列來取得該變數..

但是聰明的你跟懶惰的我,絕對發現了.這樣寫起來.每個變數名稱又臭又長,誰會想這樣寫程式阿  :(

所以,在 php4.1 以後 變產生了 $_POST $_GET $_SERVER $_COOKIE $_SESSION 等 陣列,其功用就如同上面所列的.是將使用者經由表單送出的資料以陣列的方式進行一個存放,而非直接註冊在 $欄位名稱 這樣的變數裡面.

接著 PHP 開發團隊更進一步的預設了 php.ini 中 global register 的設定
值為關閉的狀態.

這樣.親愛的學員朋友們,你清楚為什麼要使用$_POST 與 $_GET 來取得使用者傳入的表單了嗎?
希望這一篇文章能幫助您將來撰寫php程式的時候更順利唷.

HTML補充教室: 使用者傳入的表單為什麼要放入 $_POST 跟 $_GET 兩個不同的陣列阿?

由於 html 表單傳遞資料的時候分為兩種方法
1 GET 將資料於 url 中一併送出. 會於網址列顯示像是 http://url/xxx.php?欄位名稱=欄位值
2 POST 將資料於http request 時,於表頭中直接送出,所以該資料並不會以 http://url/xxx.php?欄位名稱=欄位值 的方式出現在瀏覽器的網址列

而表單設定的方式則是如下.
代碼: [選擇]
<form method="get">
代碼: [選擇]
<form method="post">

而什麼時候會用到 get ? 什麼時候又要用 post 呢?...

通常使用 post 都是在只能送出一次的資料,像是留言版的留言.會員的登入資料,或是註冊表等.

而 get 的使用通常是在可以重複,且是用來判斷目前所在位置的情況,像製作換頁功能的時候,用來帶入該頁數,或是像 phpbb2 利用 get 取得目前使用的功能與目前觀看的版面編號等. :D
主題: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: Darkhero2005-06-20 05:21
第一次寫這樣的教學文章.還請各位學長們多多指教阿..^_^..
若有文筆不順暢的地方還請各位多多指教.
主題: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: ricky2005-06-20 09:53
鼓掌鼓掌  :D
我也覺得這邊的型態可以弄成一個工具快速索引的地方
而不是淪落成一個只是在教導大家如何用for畫出一棵聖誕樹
之前花了好幾個禮拜在研究nusoap以及他那完全看不懂得官方使用文件
最後還是自己慢慢try看sample才大致了解怎麼使用
如果把他建成一個工具索引
讓以後如果有人也需要這方面的資源時就可以快速的上手
不用再去翻那外星人文件
不知意下如何呢
主題: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: 文九智2005-06-22 11:31
完全贊成!! :D
書上寫的大部分都是順利情況下的狀態,可每個人因軟硬體的些微差異,或資質、先學後學的不同,總是會有一些疑難雜症產生,這也就是為何本站如此蓬勃,生生不息的原因之一啊!
若能在學習告一階段後,針對某一部份自己,甚至留言上大部分的的問題,整理出類似錯誤學習報告的東西,相信對於往後遭到類似問題的同好,能減少許多不必要的發問。
日後若集結成冊,搞不好可以一起初書哩! :lol:
主題: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: Darkhero2005-06-22 12:26
感謝各位的回應.^_^..

小弟正在思考下一個要寫什麼...
目前是計畫延伸$_POST ,$_GET... 講解關於 $_FILES 陣列 ,也就是檔案上傳的概念.以及需要注意的像是 is_uploaded_files .
當然其中也會說到 form 的額外設定...
主題: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: alva2005-07-06 15:37
優哦...!

我家如果在"饒河夜市" , 我可能也會常常睡不著 

希望你常常睡不者 :D:D:D
主題: Re: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: 學飛的小鳥2005-11-06 09:59
引述: "Darkhero"

由於 html 表單傳遞資料的時候分為兩種方法
1 GET 將資料於 url 中一併送出. 會於網址列顯示像是 http://url/xxx.php?欄位名稱=欄位值
2 POST 將資料於http request 時,於表頭中直接送出,所以該資料並不會以 http://url/xxx.php?欄位名稱=欄位值 的方式出現在瀏覽器的網址列

而表單設定的方式則是如下.
代碼: [選擇]
<form method="get">
代碼: [選擇]
<form method="post">

而什麼時候會用到 get ? 什麼時候又要用 post 呢?...

通常使用 post 都是在只能送出一次的資料,像是留言版的留言.會員的登入資料,或是註冊表等.

而 get 的使用通常是在可以重複,且是用來判斷目前所在位置的情況,像製作換頁功能的時候,用來帶入該頁數,或是像 phpbb2 利用 get 取得目前使用的功能與目前觀看的版面編號等. :D


剛剛看到這裏, 有一點點迷惑.....
印象中, get 適用於上傳資料量少或是要追蹤 url 串列時,
因為 get 的資料是存放在 php 的環境變數內, 所以容量有限,
而且get 資料會完整的儲存在 $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING']變數內..

post 是上傳較大資料量的方式, 或是想保留上傳資料原始格式的時候,
例如上傳檔案, 檔案資料不會做任何編碼, server 端可以直接存檔...
server 端的CGI程式(如php、perl or asp...)可以用讀取"標準輸入"的方式取得資料.

另外 post 的資料不會列在url, 有保密的功能,
如果要上傳帳號密碼之類的資料通常都用 post, 這樣密碼就不會顯示在url...

post 資料通常是相同的資料只上傳一次, 而且資料量可能很大,
post 之後, 如果回上一頁, 會顯示網頁已過期(或其他警告訊息)提醒瀏覽者...
所以, 像是上傳文章之類的功能, 也都是用 post
主題: Re: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: Darkhero2005-11-06 12:04
引述: "學飛的小鳥"
引述: "Darkhero"

由於 html 表單傳遞資料的時候分為兩種方法
1 GET 將資料於 url 中一併送出. 會於網址列顯示像是 http://url/xxx.php?欄位名稱=欄位值
2 POST 將資料於http request 時,於表頭中直接送出,所以該資料並不會以 http://url/xxx.php?欄位名稱=欄位值 的方式出現在瀏覽器的網址列

而表單設定的方式則是如下.
代碼: [選擇]
<form method="get">
代碼: [選擇]
<form method="post">

而什麼時候會用到 get ? 什麼時候又要用 post 呢?...

通常使用 post 都是在只能送出一次的資料,像是留言版的留言.會員的登入資料,或是註冊表等.

而 get 的使用通常是在可以重複,且是用來判斷目前所在位置的情況,像製作換頁功能的時候,用來帶入該頁數,或是像 phpbb2 利用 get 取得目前使用的功能與目前觀看的版面編號等. :D


剛剛看到這裏, 有一點點迷惑.....
印象中, get 適用於上傳資料量少或是要追蹤 url 串列時,
因為 get 的資料是存放在 php 的環境變數內, 所以容量有限,
而且get 資料會完整的儲存在 $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING']變數內..

post 是上傳較大資料量的方式, 或是想保留上傳資料原始格式的時候,
例如上傳檔案, 檔案資料不會做任何編碼, server 端可以直接存檔...
server 端的CGI程式(如php、perl or asp...)可以用讀取"標準輸入"的方式取得資料.

另外 post 的資料不會列在url, 有保密的功能,
如果要上傳帳號密碼之類的資料通常都用 post, 這樣密碼就不會顯示在url...

post 資料通常是相同的資料只上傳一次, 而且資料量可能很大,
post 之後, 如果回上一頁, 會顯示網頁已過期(或其他警告訊息)提醒瀏覽者...
所以, 像是上傳文章之類的功能, 也都是用 post


感謝您的回應...

基本上兩種說法都可以...

GET 的訊息的確是有不安全的疑慮. 所以適合用在不會改變資料庫內容的功能.
POST 則不一定是為了作資料保密喔.
post 的資料也是以明碼傳送的.除非整個連線session是使用 ssl 加密過.

或許用實例會更清楚...
以最常見的使用 get 的方式來說,應該就是所謂的分頁功能了.
分頁功能,並不會牽涉到任何資料的改變.且也沒有資料保密的需求,再加上該頁面可以接受不斷的reload或是將網址Copy下來保存甚至傳給其他人看.

post 最常則是用在 登入(帳號密碼不適合放在網址,且登入也不會是可以一重複的.且登入的時候會改變資料庫存入使用者登入時間,以及保存該次的sessionID等,也是一種改變資料庫囉),發表文章(除了長度以外,他會改變資料庫資料表,所以不應該讓使用者會重複該頁). 填寫問卷,聯絡站長表單. 等...

而再前面對於 GET 的部份則有一種例外....
應該採用sessionc來處理.
那就是列出使用者個人資訊的功能.

這部份雖然不會修改資料也不會造成資料庫內容改變,但是由於資料內容本身應該是要保密的,所以應該採用將該 username 的 value 存放在 session 中,而非採用 get 取得來顯示會員個人資料唷!!..
相信很多朋友有看過新聞,XX銀行線上信用卡申請表的result頁,採用get的方式顯示使用者申請的內容,且是連續的序號..所以造成資料外流的軒然大波.

希望這樣說明能更明白囉..^_^..
主題: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: FIEND2006-04-04 11:45
get  在 ie 上預設長度限制 為 2k

而 在 firefox 上則為 4k 在寫php 時請小心注意 使用

若 丢出來的字串長度太長 請 使用 post 避免 程式錯誤

get 最大的好處是可以運用在 版型邏輯 及 內容邏輯層的帶入參數

也可以做 快取的依據 ..

 這要視個人在規劃系統上的 習慣了


例如 我在規劃系統時


search

record

page

relation

sort

insert

delete

update

這些 都是時常出現的

要帶什麼 get 或 post 才會使系統富有一致性和延展性都是要深思熟慮的

提供參考 歡迎指教 ..
主題: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: FIEND2006-04-04 11:54
安全性的問題的話

超全域陣列變數 php.ini 有設定可以擋住 injection 的字元

但是建議大家在 寫入 db 時

加入 mysql_escape_string 或是 addslashes 可以 過濾 injection 的攻擊方式
主題: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: qrtt12006-08-25 10:13
最近惡搞了另一種作法
在某一個處理用的檔ex. my_tool.php
有時用url query string
有時用post method
就使用了$_REQUEST變數。
可能有一點亂來唄:P
主題: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: cool20072007-07-26 01:34
我只知道一個是會保密的
一個不會
但是我不知道那個是那個
看完這篇後
看來我也多了解php一點了
主題: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: Darkhero2007-07-26 10:34
引述: "cool2007"
我只知道一個是會保密的
一個不會
但是我不知道那個是那個
看完這篇後
看來我也多了解php一點了


正確來說,兩個都達不到保密防諜的功能。
只是一個你網址上看不到一個看得到。
主題: 回覆: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: junesnow172008-11-11 12:14
睡不著就可以寫這樣的文字。。
不知道大大住哪
我哪天拿個麥克風去你們家樓下好了。。 :P
主題: 回覆: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: TyroneYeh2009-02-27 18:57
現在很多 Framework 都能處理這種問題,應該大致上不用單擔心這方面!!
不過就是要學一下 Framework 的用法才行囉!!
主題: 回覆: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: westlifehk2009-03-12 17:25
現在很多 Framework 都能處理這種問題,應該大致上不用單擔心這方面!!
不過就是要學一下 Framework 的用法才行囉!!

十分認同 :)
主題: 回覆: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: Darkhero2009-03-13 10:58
的確是目前大部分的 Framework 都可以很漂亮的把這些問題處理調...

但是我相信對於超全域變數的理解與使用. 乃至於 Server Client 傳遞參數等的方法,是一個 PHP 程式設計師應該要清楚理解的.. :) ..
這樣在 Framework 有錯誤或是無法在 Framework 自動處理的時候,自己才能有應變的能力...

就像籃球的運球一樣,基礎很重要....
主題: 回覆: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: see7di2010-10-26 13:06
我寫了一個函式,不需要判斷是post還是get類型就可以獲取數據
//函数:获取数据
//用法:不管是post還是get全部都是Toget("字段名")來獲取
//参数:表单名,是否需要转译
Function Toget($__k,$Slash=True){
   IF($__k==""){Return False;}

   IF(Array_key_exists($__k,$_REQUEST)){
      $Value=IsSet($_POST["".$__k.""])?$_POST["".$__k.""]:$_GET["".$__k.""];
   }Else{
      Return False;
   }

   IF(Is_array($Value)){
      $Value=Array_Filter($Value,'_nul');
   }Else{
      $Value=Trim($Value);
      IF($Value==""){Return False;}
   }

   IF(!Get_magic_quotes_gpc() And $Slash==True){//如果系统转译关闭了且参数要求转译
       IF(!Is_array($Value)){
         $Value=addslashes($Value);
      }Else{
         Foreach($Value as $key => $val){$Value["".$key.""] = Addlash($val);}
      }
   }

   //反馈结果
   IF(Is_array($Value)){Return $Value;}
   IF($Value=="" Or !Isset($Value)){
      Return False;
   }Else{
      Return $Value;
   }
}
主題: 回覆: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: Darkhero2010-10-26 13:14
要不管是$_POST 或是 $_GET .. 那從 $_REQUEST 就可以取得了....
主題: Re: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
作者: 小笨豬2011-07-17 18:06
$_REQUEST不是也有COOKIE ???