02
2014
02

CodeIgniter中get_post 方法需要注意的地方

今天一個正在進行中的案子,接到開發伙伴來的訊息,說他用POST來的資料,進去資料庫都是空白。看到這個訊息,我的心頭小鹿禁不住一陣亂撞,這下不得了,趕快測試看看:Model寫入資料庫沒問題,Controller丟資料給Model沒問題,難道是接收POST資料有問題?

於是趕緊打開心愛的Notepadd++看看程式,由於我是負責寫API接收Client丟資料來處理,然後回傳處理結果,而且Client端有可能用GET也可能用POST丟來,資料欄位多少不一定(這是我們訂好的規格),所以接收資料我是這樣寫的:

$data_array = $this->input->get_post(NULL,TRUE);

這樣我可以接收整個POST資料或GET資料,而且CI會幫我把整個$_POST或$_GET陣列過濾掉XSS然後傳回陣列給我。至於順序呢,依照CI的官方手冊說,它會先看POST再看GET。好了,這時候我們一般人的理解應該就是:如果有POST資料,它就用POST,然後傳回給我,如果沒有POST,它會再去看GET,然後一樣處理好傳回給我。

但,真的是這樣嗎? 當我單獨用$this->input->get(NULL,TRUE)或$this->input->post(NULL,TRUE)都沒問題,可以正常接收到整個GET或POST來的陣列,但是get_post這樣用就挫賽了。舉個例子,譬如我的某個API的URL點是這樣的:

http://api.example.com/v1/user/add

他可以接受POST或GET丟任意數量的資料來,我就接收起來,處理好存入資料庫。好了,如果Client端是這樣丟來的:

http://api.example.com/v1/user/add?token=9c6b99753ff8c41cda0331d634d2a4eac8e53a34

然後POST內容是這樣

name=David+Pai&mobile=0999123456

那這樣透過$this->input->get_post(NULL,TRUE)會得到什麼呢? 你以為$data_array會是這樣:

array(3) {
  ["token"]=>
  string(40) "9c6b99753ff8c41cda0331d634d2a4eac8e53a34"
  ["name"]=>
  string(9) "David Pai"
  ["mobile"]=>
  string(10) "0999123456"
}

結果不是,只剩下這樣:

array(1) {
  ["token"]=>
  string(40) "9c6b99753ff8c41cda0331d634d2a4eac8e53a34"
}

只剩下GET來的資料,POST全都不見了。

怎麼會這樣,不是說會先看POST再看GET,那至少給我POST資料吧,怎麼反而只給GET資料呢? 好的,這是我的膝蓋第一次被CI射了一箭,直到我去追了Input Class的原始碼…讓我們看看get_post這個方法:

function get_post($index = '', $xss_clean = FALSE)
{
    if ( ! isset($_POST[$index]) )
    {
        return $this->get($index, $xss_clean);
    }
    else
    {
        return $this->post($index, $xss_clean);
    }
}

看出來了嗎? 這下真相終於大白,如果你這樣用$this->input->get_post(NULL,TRUE),它會因為$_POST[NULL]判斷為false而直接跑去用$this->get(NULL,TRUE),所以得到的結果就只剩下GET來的東西了。

所以,對於CI的get_post,有幾個地方要注意:

  • 它沒有像get或post那樣,第一個參數指定為NULL就可以處理整個$_POST或$_GET

  • 如果第一個參數指定為NULL,只會得到跟get一樣的結果

  • 如果要像手冊說的那樣,第一個參數一定要指定

那麼,如果要像上面那個例子那樣,我POST和GET都要接收,然後碰到相同的以POST為先,這樣怎麼做呢? 既然CI沒有這樣的方法,那我們只好自力救濟啦,分開來接,然後再自己merge囉:

$data_get = $this->input->get(NULL, TRUE);
$data_post = $this->input->post(NULL, TRUE);
            
$data_get = is_array($data_get) ? $data_get : array();
$data_post = is_array($data_post) ? $data_post : array();

$data_array = array_merge($data_get, $data_post);

於是,這個Bug解決了,而我的膝蓋也復原了…

參考資料
CI官方手冊對於Input Class的說明

原文转自:http://www.davidpai.tw/php/2012/something-need-to-pay-attention-about-codeigniter-get_post-method/

« 上一篇下一篇 »

相关文章:

PHP中判断变量为空的几种方法  (2014-1-24 9:40:14)

#学习笔记#php字符递增问题  (2013-6-4 10:10:47)

随便弄了个天气预报  (2013-3-24 2:23:12)

一个简单的MySql连接操作类  (2013-1-7 13:33:30)

#学习笔记#php实现计划任务  (2012-11-23 21:2:27)

#学习笔记#php时间格式参数  (2012-11-20 9:24:22)

一个实现无刷新文件上传的思路  (2012-11-11 21:37:19)

php+ajax+json实现分页  (2012-10-5 21:59:44)

php实现手机号码归属地查询  (2012-10-2 22:58:14)

php替换函数preg_match()  (2012-9-23 21:8:0)