作者 主題: SA.PHP觀念教室 首部曲:了解$_POST,$_GET  (閱讀 60989 次)

0 會員 與 1 訪客 正在閱讀本文。

Darkhero

  • 酷!學園 學長們
  • 俺是博士!
  • *****
  • 文章數: 3728
  • 性別: 男
    • 檢視個人資料
    • ㄚ凱隨手紀
不知道為什麼半夜四點忽然醒來睡不著....就來寫寫文件好了....

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

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

預期本堂的學員程度:
    1.剛開始學習PHP程式語言的朋友
    2.知道 $_POST,$_GET 卻不了解為什麼要這樣用的朋友
    3.每次都是要把 global register 打開才會寫php的朋友
    4.正在寫php卻完全不知道啥是 $_POST $_GET 的朋友


緣起: 說到 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
希望我們的討論是為了把問題解決,而不是爭論誰對誰錯.
『灌水才是重點,發文只是順便』
『我寧可讓不會釣魚的工程師餓死,也不想讓會餓死的工程師去攪沉公司....』
Blog: http://blog.darkhero.net/
秘密基地: http://www.darkhero.net/comic/
目前服務的網站: http://www.libook.com.tw/

Darkhero

  • 酷!學園 學長們
  • 俺是博士!
  • *****
  • 文章數: 3728
  • 性別: 男
    • 檢視個人資料
    • ㄚ凱隨手紀
SA.PHP觀念教室 首部曲:了解$_POST,$_GET
« 回覆 #1 於: 2005-06-20 05:21 »
第一次寫這樣的教學文章.還請各位學長們多多指教阿..^_^..
若有文筆不順暢的地方還請各位多多指教.
希望我們的討論是為了把問題解決,而不是爭論誰對誰錯.
『灌水才是重點,發文只是順便』
『我寧可讓不會釣魚的工程師餓死,也不想讓會餓死的工程師去攪沉公司....』
Blog: http://blog.darkhero.net/
秘密基地: http://www.darkhero.net/comic/
目前服務的網站: http://www.libook.com.tw/

ricky

  • 區域板主
  • 鑽研的研究生
  • *****
  • 文章數: 669
    • 檢視個人資料
    • Ricky 碎碎唸
SA.PHP觀念教室 首部曲:了解$_POST,$_GET
« 回覆 #2 於: 2005-06-20 09:53 »
鼓掌鼓掌  :D
我也覺得這邊的型態可以弄成一個工具快速索引的地方
而不是淪落成一個只是在教導大家如何用for畫出一棵聖誕樹
之前花了好幾個禮拜在研究nusoap以及他那完全看不懂得官方使用文件
最後還是自己慢慢try看sample才大致了解怎麼使用
如果把他建成一個工具索引
讓以後如果有人也需要這方面的資源時就可以快速的上手
不用再去翻那外星人文件
不知意下如何呢
我的symfony作品:YOMOpets 寵物誌
有興趣可以一起來討論symfony喔
我的部落格:http://ricky.ez2.us/

文九智

  • 可愛的小學生
  • *
  • 文章數: 11
    • 檢視個人資料
SA.PHP觀念教室 首部曲:了解$_POST,$_GET
« 回覆 #3 於: 2005-06-22 11:31 »
完全贊成!! :D
書上寫的大部分都是順利情況下的狀態,可每個人因軟硬體的些微差異,或資質、先學後學的不同,總是會有一些疑難雜症產生,這也就是為何本站如此蓬勃,生生不息的原因之一啊!
若能在學習告一階段後,針對某一部份自己,甚至留言上大部分的的問題,整理出類似錯誤學習報告的東西,相信對於往後遭到類似問題的同好,能減少許多不必要的發問。
日後若集結成冊,搞不好可以一起初書哩! :lol:

Darkhero

  • 酷!學園 學長們
  • 俺是博士!
  • *****
  • 文章數: 3728
  • 性別: 男
    • 檢視個人資料
    • ㄚ凱隨手紀
SA.PHP觀念教室 首部曲:了解$_POST,$_GET
« 回覆 #4 於: 2005-06-22 12:26 »
感謝各位的回應.^_^..

小弟正在思考下一個要寫什麼...
目前是計畫延伸$_POST ,$_GET... 講解關於 $_FILES 陣列 ,也就是檔案上傳的概念.以及需要注意的像是 is_uploaded_files .
當然其中也會說到 form 的額外設定...
希望我們的討論是為了把問題解決,而不是爭論誰對誰錯.
『灌水才是重點,發文只是順便』
『我寧可讓不會釣魚的工程師餓死,也不想讓會餓死的工程師去攪沉公司....』
Blog: http://blog.darkhero.net/
秘密基地: http://www.darkhero.net/comic/
目前服務的網站: http://www.libook.com.tw/

alva

  • 活潑的大學生
  • ***
  • 文章數: 315
    • 檢視個人資料
SA.PHP觀念教室 首部曲:了解$_POST,$_GET
« 回覆 #5 於: 2005-07-06 15:37 »
優哦...!

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

希望你常常睡不者 :D:D:D

學飛的小鳥

  • 活潑的大學生
  • ***
  • 文章數: 349
    • 檢視個人資料
Re: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
« 回覆 #6 於: 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

Darkhero

  • 酷!學園 學長們
  • 俺是博士!
  • *****
  • 文章數: 3728
  • 性別: 男
    • 檢視個人資料
    • ㄚ凱隨手紀
Re: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
« 回覆 #7 於: 2005-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的方式顯示使用者申請的內容,且是連續的序號..所以造成資料外流的軒然大波.

希望這樣說明能更明白囉..^_^..
希望我們的討論是為了把問題解決,而不是爭論誰對誰錯.
『灌水才是重點,發文只是順便』
『我寧可讓不會釣魚的工程師餓死,也不想讓會餓死的工程師去攪沉公司....』
Blog: http://blog.darkhero.net/
秘密基地: http://www.darkhero.net/comic/
目前服務的網站: http://www.libook.com.tw/

FIEND

  • 鑽研的研究生
  • *****
  • 文章數: 700
    • 檢視個人資料
    • http://bbs.ecstart.com
SA.PHP觀念教室 首部曲:了解$_POST,$_GET
« 回覆 #8 於: 2006-04-04 11:45 »
get  在 ie 上預設長度限制 為 2k

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

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

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

也可以做 快取的依據 ..

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


例如 我在規劃系統時


search

record

page

relation

sort

insert

delete

update

這些 都是時常出現的

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

提供參考 歡迎指教 ..
你累了嗎? 這樣不行 , 人要比 LINUX 兇 @@ " ......

FIEND

  • 鑽研的研究生
  • *****
  • 文章數: 700
    • 檢視個人資料
    • http://bbs.ecstart.com
SA.PHP觀念教室 首部曲:了解$_POST,$_GET
« 回覆 #9 於: 2006-04-04 11:54 »
安全性的問題的話

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

但是建議大家在 寫入 db 時

加入 mysql_escape_string 或是 addslashes 可以 過濾 injection 的攻擊方式
你累了嗎? 這樣不行 , 人要比 LINUX 兇 @@ " ......

qrtt1

  • 懷疑的國中生
  • **
  • 文章數: 73
    • 檢視個人資料
SA.PHP觀念教室 首部曲:了解$_POST,$_GET
« 回覆 #10 於: 2006-08-25 10:13 »
最近惡搞了另一種作法
在某一個處理用的檔ex. my_tool.php
有時用url query string
有時用post method
就使用了$_REQUEST變數。
可能有一點亂來唄:P

cool2007

  • 可愛的小學生
  • *
  • 文章數: 11
    • 檢視個人資料
SA.PHP觀念教室 首部曲:了解$_POST,$_GET
« 回覆 #11 於: 2007-07-26 01:34 »
我只知道一個是會保密的
一個不會
但是我不知道那個是那個
看完這篇後
看來我也多了解php一點了

Darkhero

  • 酷!學園 學長們
  • 俺是博士!
  • *****
  • 文章數: 3728
  • 性別: 男
    • 檢視個人資料
    • ㄚ凱隨手紀
SA.PHP觀念教室 首部曲:了解$_POST,$_GET
« 回覆 #12 於: 2007-07-26 10:34 »
引述: "cool2007"
我只知道一個是會保密的
一個不會
但是我不知道那個是那個
看完這篇後
看來我也多了解php一點了


正確來說,兩個都達不到保密防諜的功能。
只是一個你網址上看不到一個看得到。
希望我們的討論是為了把問題解決,而不是爭論誰對誰錯.
『灌水才是重點,發文只是順便』
『我寧可讓不會釣魚的工程師餓死,也不想讓會餓死的工程師去攪沉公司....』
Blog: http://blog.darkhero.net/
秘密基地: http://www.darkhero.net/comic/
目前服務的網站: http://www.libook.com.tw/

junesnow17

  • 可愛的小學生
  • *
  • 文章數: 10
  • 性別: 女
    • 檢視個人資料
回覆: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
« 回覆 #13 於: 2008-11-11 12:14 »
睡不著就可以寫這樣的文字。。
不知道大大住哪
我哪天拿個麥克風去你們家樓下好了。。 :P
程式是不歸路嗎
那讓我死無葬身之地吧

TyroneYeh

  • 俺是博士!
  • *****
  • 文章數: 2396
  • 性別: 男
    • 檢視個人資料
回覆: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
« 回覆 #14 於: 2009-02-27 18:57 »
現在很多 Framework 都能處理這種問題,應該大致上不用單擔心這方面!!
不過就是要學一下 Framework 的用法才行囉!!
--
TyroneYeh

westlifehk

  • 可愛的小學生
  • *
  • 文章數: 5
    • 檢視個人資料
回覆: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
« 回覆 #15 於: 2009-03-12 17:25 »
現在很多 Framework 都能處理這種問題,應該大致上不用單擔心這方面!!
不過就是要學一下 Framework 的用法才行囉!!

十分認同 :)

Darkhero

  • 酷!學園 學長們
  • 俺是博士!
  • *****
  • 文章數: 3728
  • 性別: 男
    • 檢視個人資料
    • ㄚ凱隨手紀
回覆: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
« 回覆 #16 於: 2009-03-13 10:58 »
的確是目前大部分的 Framework 都可以很漂亮的把這些問題處理調...

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

就像籃球的運球一樣,基礎很重要....
希望我們的討論是為了把問題解決,而不是爭論誰對誰錯.
『灌水才是重點,發文只是順便』
『我寧可讓不會釣魚的工程師餓死,也不想讓會餓死的工程師去攪沉公司....』
Blog: http://blog.darkhero.net/
秘密基地: http://www.darkhero.net/comic/
目前服務的網站: http://www.libook.com.tw/

see7di

  • 懷疑的國中生
  • **
  • 文章數: 51
  • 性別: 男
    • 檢視個人資料
    • http://7di.net
回覆: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
« 回覆 #17 於: 2010-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;
   }
}

Darkhero

  • 酷!學園 學長們
  • 俺是博士!
  • *****
  • 文章數: 3728
  • 性別: 男
    • 檢視個人資料
    • ㄚ凱隨手紀
回覆: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
« 回覆 #18 於: 2010-10-26 13:14 »
要不管是$_POST 或是 $_GET .. 那從 $_REQUEST 就可以取得了....
希望我們的討論是為了把問題解決,而不是爭論誰對誰錯.
『灌水才是重點,發文只是順便』
『我寧可讓不會釣魚的工程師餓死,也不想讓會餓死的工程師去攪沉公司....』
Blog: http://blog.darkhero.net/
秘密基地: http://www.darkhero.net/comic/
目前服務的網站: http://www.libook.com.tw/

小笨豬

  • 可愛的小學生
  • *
  • 文章數: 3
  • 性別: 男
    • 檢視個人資料
Re: SA.PHP觀念教室 首部曲:了解$_POST,$_GET
« 回覆 #19 於: 2011-07-17 18:06 »
$_REQUEST不是也有COOKIE ???