form.php
<?php include 'inc/base.php' ?>
<?php
// PHP 自動提供 $_GET、$_POST、$_ENV、$_COOKIE、$_SERVER、$_FILES 等多個 global 陣列
// 不要用 register_globals 將上述陣列的 key/value 轉為 global 變數,很危險的
// 盡量用明確的 $_GET 或 $_POST,不要偷懶用 $_REQUEST
// $_REQUEST 依照 variables_order 定義的順序,依序將 $_GET、$_POST、$_ENV、$_COOKIE、$_SERVER 多個陣列整合成單一陣列
// 用一個 php 負責 get 與 post,以減少程式不一致的機會
// $_SERVER['REQUEST_METHOD'] 取得大寫的 GET 或者 POST
// POST - 送出 form
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$b = backingObject();
// binding & validate
$errors = array();
$b->account = Moca::validateString('account', $errors, true, 50);
$b->password = Moca::validateString('password', $errors, true, 50);
$b->status = Moca::validateRadio('status', $errors, User::$STATUS);
$b->type = Moca::validateString('type', $errors, false, 50);
$b->description = Moca::validateString('description', $errors, false, 200);
$b->power = Moca::validateCheckbox('power', $errors, User::$POWER);
$b->score = Moca::validatePint('score', $errors, true);
if (!count($errors)) {
if (isset($b->id)) {
$msg = User::update($b);
}
else {
$msg = User::add($b);
}
if (isset($msg)) {
$errors['account'] = $msg;
}
else {
header('Location: userList.php');
exit();
}
}
}
// GET - 進 form
else if ($_SERVER['REQUEST_METHOD'] == 'GET') {
$b = backingObject();
}
else {
echo "不支援的 REQUEST_METHOD - {$_SERVER['REQUEST_METHOD']}";
exit();
}
function backingObject() {
$id = Moca::findId();
// 有傳 id 表示要修改
if (isset($id)) {
// load from database
$b = User::get($id);
}
// 沒有傳 id 表示要新增
else {
$b = new User();
$b->createTime = time();
}
return $b;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<?php include 'inc/head.php' ?>
<script type="text/javascript">
</script>
</head>
<body>
<table cellspacing="0" cellpadding="3" width="100%">
<tbody>
<tr>
<td>使用者管理</td>
</tr>
<tr>
<td height="5"></td>
</tr>
</tbody>
</table>
<table width="720" align="center">
<tbody>
<tr>
<td>
<table width="100%">
<tbody>
<tr>
<td>
<!-- 因為用同一個 php 處理 get 與 post,所以可以用 $_SERVER['SCRIPT_NAME'] 以減少更名造成的錯誤 -->
<form id="userForm" action="<?php echo $_SERVER['SCRIPT_NAME'] ?>"
method="post"><input type="hidden" class="text" id="id" name="id"
value="<?php echo $b->id; ?>" />
<table width="100%" border="1" cellspacing="1" cellpadding="2">
<tr>
<td align="left" class="required">帳號</td>
<td><input name="account" type="text" id="account"
value="<?php echo $b->account ?>" class="text" /><?php Moca::showError('account'); ?></td>
</tr>
<tr>
<td align="left" class="required">密碼</td>
<td><input name="password" id="password" type="password"
class="text" value="<?php echo $b->password ?>" /><?php Moca::showError('password'); ?></td>
</tr>
<tr>
<td align="left" class="required">狀態</td>
<td><?php foreach (User::$STATUS as $key => $value) { ?> <input
name="status" type="radio" value="<?php echo $key; ?>"
class="radio"
<?php echo $b->status == $key ? 'checked="checked"' : ''; ?> /><?php echo $value; ?>
<?php } ?><?php Moca::showError('status'); ?></td>
</tr>
<tr>
<td align="left">類型</td>
<td><input name="type" id="type" type="text" class="text"
value="<?php echo $b->type ?>" /><?php Moca::showError('type'); ?></td>
</tr>
<tr>
<td align="left" class="required">Email</td>
<td><input name="email" id="email" type="text" class="text"
value="<?php echo $b->email ?>" /><?php Moca::showError('email'); ?></td>
</tr>
<tr>
<td align="left" class="m_tdcolor_04">備註說明</td>
<td><textarea name="description" id="description"
class="textarea"><?php echo $b->description ?></textarea><?php Moca::showError('description'); ?></td>
</tr>
<tr>
<td align="left" class="m_tdcolor_04">權限</td>
<td><?php
foreach (User::$POWER as $key => $value ) {
$checked = strpos($b->power, $key) !== false ? "checked='checked'" : "";
// name 要加上 [],告知 PHP 以陣列處理
echo "<input type='checkbox' name='power[]' value='$key' $checked/>$value<br/>";
}
?><?php Moca::showError('power'); ?></td>
</tr>
<tr>
<td align="left" class="required">分數</td>
<td><input name="scroe" id="scroe" type="text" class="text"
value="<?php echo $b->scroe ?>" /><?php Moca::showError('scroe'); ?></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit"
class="button" value="存檔" /> <input type="button"
class="button" value="取消" onclick="history.back(); " />
<input type="reset" class="button" value="重設" />
</td>
</tr>
</table>
</form>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</body>
</html>
base.php
<?php
date_default_timezone_set('Asia/Taipei');
setlocale(LC_ALL, 'zh_TW');
session_start();
class Moca {
// 日期時間 long 變 字串
public static function formatDT($t) {
if (!isset($t)) {
return;
}
if (strlen($t) === 0) {
return;
}
return date('Y-m-d H:i', $t);
}
// 日期 long 變 字串
public static function formatD($t) {
if (!isset($t)) {
return;
}
if (strlen($t) === 0) {
return;
}
return date('Y-m-d', $t);
}
// 日期字串變 long
public static function parseDT($t) {
if (!isset($t)) {
return;
}
if (strlen($t) === 0) {
return;
}
return strtotime($t);
}
// 從陣列中取出對應的錯誤訊息
public static function showError($field) {
global $errors;
if (isset($errors) && isset($errors[$field])) {
print " <span class='error'>$errors[$field]</span>";
}
}
// PHP 的 strlen() 不支援 Unicode,網路抄來的解法
public static function strlen($s) {
$a = preg_split("//u", $s);
$i = -2;
foreach ($a as $b)
$i++;
return $i;
}
public static function findId() {
$id = NULL;
// GET - 進 form
if (isset($_GET['id']) && ctype_digit($_GET['id'])) {
$id = trim($_GET['id']);
}
// POST - 送出 form
else if (isset($_POST['id']) && ctype_digit($_POST['id'])) {
$id = trim($_POST['id']);
}
return $id;
}
// 字串用 strlen() 驗證長度,text、textarea 與 file 都會送出字串
// PHP 的 strlen() 不支援 Unicode
// 不可用 empty() 取代 strlen(),因為 empty() 會將某些字串視為 false,如字元 0
// 檢查長度前,最好先用 trim() 整理一下
public static function validateString($field, &$errors, $required, $max) {
// 未傳入或者傳入空字串
// 注意:http://...?account=&password=123,$_POST['account'] 為空字串,$_POST['name'] 才是未傳入
if (!isset($_POST[$field]) || Moca::strlen(trim($_POST[$field])) === 0) {
if ($required) {
$errors[$field] = '必填欄位';
}
}
else if (Moca::strlen(trim($_POST[$field])) > $max) {
$errors[$field] = "長度必須不可超過 $max 個字元";
}
return isset($_POST[$field]) ? trim($_POST[$field]) : '';
}
// 驗證正整數用 ctype_digit()
// is_numeric 不適合做數值驗證,因為它接受一堆奇怪的格式
public static function validatePint($field, &$errors, $required) {
$value = NULL;
if (!isset($_POST[$field]) || Moca::strlen(trim($_POST[$field])) === 0) {
if ($required) {
$errors[$field] = '必填欄位';
}
}
else if (!ctype_digit(trim($_POST[$field]))) {
$errors[$field] = "必須為正整數";
}
else {
$value = intval(trim($_POST[$field]));
}
return $value;
}
// 驗證整數,先用 intval 將字串轉為整數,再用 strval 將整數轉回字串,最後和原字串比較
public static function validateInt($field, &$errors, $required) {
$value = NULL;
if (!isset($_POST[$field]) || Moca::strlen(trim($_POST[$field])) === 0) {
if ($required) {
$errors[$field] = '必填欄位';
}
}
else if ( trim($_POST[$field]) != strval(intval(trim($_POST[$field])))) {
$errors[$field] = "必須為整數";
}
else {
$value = intval(trim($_POST[$field]));
}
return $value;
}
// 驗證浮點數,先用 floatval 將字串轉為浮點數,再用 strval 將浮點數轉回字串,最後和原字串比較
public static function validateInt($field, &$errors, $required) {
$value = NULL;
if (!isset($_POST[$field]) || Moca::strlen(trim($_POST[$field])) === 0) {
if ($required) {
$errors[$field] = '必填欄位';
}
}
else if ( trim($_POST[$field]) != strval(floatval(trim($_POST[$field])))) {
$errors[$field] = "必須為浮點數";
}
else {
$value = floatval(trim($_POST[$field]));
}
return $value;
}
// 輸入 2012-06-01,輸出日期 long
public static function validateDate($field, &$errors, $required) {
$value = NULL;
if (!isset($_POST[$field]) || Moca::strlen(trim($_POST[$field])) === 0) {
if ($required) {
$errors[$field] = '必填欄位';
}
}
else {
$value = Moca::parseDT(trim($_POST[$field]));;
}
return $value;
}
// 輸入 2012-06-01、時與分,輸出日期 long
public static function validateDateTime($field, &$errors, $required) {
$value = NULL;
if (!isset($_POST[$field]) || Moca::strlen(trim($_POST[$field])) === 0) {
if ($required) {
$errors[$field] = '必填欄位';
}
}
else {
$h = str_pad($_POST[$field.'_h'], 2, '0', STR_PAD_LEFT);
$m = str_pad($_POST[$field.'_m'], 2, '0', STR_PAD_LEFT);
$dt = trim($_POST[$field]).' '.$h.':'.$m;
$value = Moca::parseDT($dt);
}
return $value;
}
// 用 array_key_exists 做 double check
public static function validateRadio($field, &$errors, $array) {
if (!isset($_POST[$field])) {
$errors[$field] = '必填欄位';
}
else if (!array_key_exists($_POST[$field], $array)) {
$errors[$field] = "所勾選的值不存在";
}
return isset($_POST[$field]) ? trim($_POST[$field]) : '';
}
// 使用 array_intersect 取得交集以確認勾選的項目均存在
public static function validateCheckbox($field, &$errors, $array) {
if (isset($_POST[$field])) {
if (array_intersect($_POST[$field], array_keys($array)) != $_POST[$field]) {
$errors[$field] = '所勾選的值不存在';
}
else {
return $_POST[$field];
}
}
return NULL;
}
}
?>
沒有留言:
張貼留言