CodeIgniter,自己覺得非常感動 XD,也非常欣慰,希望把好東西推廣給大家知道。廢話不多說,先來說說問題點,先前發表的一篇 [CodeIgniter] 利用 jQuery 簡易驗證使用者帳號/Email 最後有人留言針對 input->post() 在中文官網上面的 Input Class 教學有些疑慮,底下我先來說明網友的問題點。
input->post 如果為空,則塞進去資料庫竟然是 0 該網友引用了 Input Class 中文文件的內容
使用 POST, COOKIE, 或 SERVER 資料CodeIgniter 提供三個讓你取出 POST, COOKIE 或 SERVER 中項目的補助函數。使用這些函數的主要便利性在於, 它們會確認並檢視是否這些項目已被設定並且在未設定時回傳 false (boolean) , 而不是直接取出 ($_POST[‘something’]),官方範例↓這讓你可以方便地使用資料而不必預先測試它們是否存在。不然, 通常你可能會像這樣做:if ( ! isset($_POST[‘something’])) { $something = FALSE; } else { $something = $_POST[‘something’]; } 網友敘述:
但是為什麼還是為設定為0呢??這應該是檢查資料有沒有被設定而已,那我如果沒有輸入,又怎麼會出現 0 呢?? 網友希望 $username = $this->input-post(“username”); 能幫他判斷如果 username 沒有資料,就直接回傳 NULL,Insert 到資料庫時,應該是 NULL 而不是 0。
程式範例 網友其實沒有錯,根據文件上顯示,如果 $something =
$this->input->post(“something”); 取值過後,如果系統沒有 $_POST[‘something’],則會回傳 FALSE,我猜網友在跟 model 作搭配的時候使用了底下的寫法來塞值進入資料庫:
$data = array(
"username" => $this->input->post('username'),
"passwd" => $this->input->post('passwd'),
"email" => $this->input->post('email'),
);
$this->load->model('members');
$this->members->register($data);
假設如果沒有 $_POST['email'] 的話,該欄位就會被設定為 0,原因很簡單,就是出在要塞值進入資料庫的時候,程式針對資料的型態判斷啦,底下從最開始取得$_POST 資料開始說起。
Input Class 核心程式流程($_POST) 程式剛開始是這樣寫 $username = $this->input->post(“username”); 對應到系統
system/core/Input.php 程式裡面的 post method:
/**
* Fetch an item from the POST array
*
* @access public
* @param string
* @param bool
* @return string
*/
function post($index = NULL, $xss_clean = FALSE)
{
// Check if a field has been provided
if ($index === NULL AND ! empty($_POST))
{
$post = array();
// Loop through the full _POST array and return it
foreach (array_keys($_POST) as $key)
{
$post[$key] = $this->_fetch_from_array($_POST, $key, $xss_clean);
}
return $post;
}
return $this->_fetch_from_array($_POST, $index, $xss_clean);
}當你傳入 username 的參數,就會直接會被送到$this->_fetch_from_array($_POST, $index, $xss_clean); 接著我們看 _fetch_from_array 這 private method
/**
* Fetch from array
*
* This is a helper function to retrieve values from global arrays
*
* @access private
* @param array
* @param string
* @param bool
* @return string
*/
function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE)
{
if ( ! isset($array[$index]))
{
return FALSE;
}
if ($xss_clean === TRUE)
{
return $this->security->xss_clean($array[$index]);
}
return $array[$index];
}有看到程式會先判斷$_POST[‘username’] 是否存在,如果不存在則回傳 FALSE,也就是先前的 $username 就會是個 bool 函數,其值是 FALSE,那接著我們來看看 Database 怎麼處理傳入的 Value 值,先到 system/database 打開 DB_driver.php,找到 Insert 資料庫的 method:
/**
* Generate an insert string
*
* @access public
* @param string the table upon which the query will be performed
* @param array an associative array data of key/values
* @return string
*/
function insert_string($table, $data)
{
$fields = array();
$values = array();
foreach ($data as $key => $val)
{
$fields[] = $this->_escape_identifiers($key);
$values[] = $this->escape($val);
}
return $this->_insert($this->_protect_identifiers($table, TRUE, NULL, FALSE), $fields, $values);
}會看到處理 value 是在$values[] = $this->escape($val);,接著我們找到 escape 這 method:
/**
* "Smart" Escape String
*
* Escapes data based on type
* Sets boolean and null types
*
* @access public
* @param string
* @return mixed
*/
function escape($str)
{
if (is_string($str))
{
$str = "'".$this->escape_str($str)."'";
}
elseif (is_bool($str))
{
$str = ($str === FALSE) ? 0 : 1;
}
elseif (is_null($str))
{
$str = 'NULL';
}
return $str;
}有看到解答了嗎?關鍵就在 is_bool($str) 這判斷式,因為 $username 值為 FALSE,所以在這裡會被設定為 0,也就是為什麼網友會說資料庫欄位怎麼都是一堆 0,原因就是這樣啦,當然也不是沒有解法阿,其實解法很容易,只是自己還是要判斷一下:$data = array(
"username" => ($username) ? $username : NULL,
"passwd" => ($passwd) ? $passwd : NULL,
"email" => ($email) ? $email : NULL,
);這樣就可以了See also
- 來聊聊 PHP & JavaScript & CSS 的 Coding Style
- 為什麼我選擇使用 Laravel Framework?
- Laravel 搭配 Google, Facebook, Twitter 第三方 OAuth 認證
- 將 wordpress 強制使用 SSL 連線
- PHP 7 vs HHVM Benchmark 比較
- Laravel 50 個小技巧 + Laravel 5.2 新功能
- Laravel Homestead 支援 MySQL 5.7 和 Node 5.0
- PHP-FIG 新網站
- Laravel Homestead 支援 PHP 7
- Laravel 5.1 is released
