首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP Checkbox 多選框取值與預設值完整實作指南

     編輯:PHP 綜合知識

核心關鍵:name="field[] 陣列語法

HTML 表單中,同名 checkbox 若要在 PHP 接收為陣列,name 屬性必須以 [] 結尾。否則 PHP 僅會收到最後一個被勾選的值(覆蓋機制)。

一、基本 HTML 結構

<form method="post" action="">
  <label><input type="checkbox" name="area[]" value="河北"> 河北</label>
  <label><input type="checkbox" name="area[]" value="河南"> 河南</label>
  <label><input type="checkbox" name="area[]" value="山西"> 山西</label>
  <label><input type="checkbox" name="area[]" value="山東"> 山東</label>
  <label><input type="checkbox" name="area[]" value="江蘇"> 江蘇</label>
  <label><input type="checkbox" name="area[]" value="浙江"> 浙江</label>
  <button type="submit">提交</button>
</form>

二、PHP 接收與處理

<?php
$selected = $_POST['area'] ?? $_GET['area'] ?? [];
if (!is_array($selected)) $selected = []; // 防禦性轉型

// 1. 直接輸出
echo '您選擇了:' . implode('、', $selected);

// 2. 迭代處理
foreach ($selected as $val) {
    echo "<div>處理:$val</div>";
}

// 3. 安全過濾(白名單)
$allowed = ['河北','河南','山西','山東','江蘇','浙江'];
$clean = array_intersect($selected, $allowed);
// $clean 只保留合法值
?>

三、預設勾選(資料驅動視圖)

<?php
// 來源:資料庫讀出的字串 "河北,河南" 或陣列 ['河北','河南']
$dbValue = '河北,河南'; // 假設從 DB 讀出
$preselected = array_filter(array_map('trim', explode(',', $dbValue)));
// $preselected = ['河北','河南']

$options = ['河北','河南','山西','山東','江蘇','浙江'];
foreach ($options as $opt) {
    $checked = in_array($opt, $preselected, true) ? ' checked' : '';
    echo "<label><input type=\"checkbox\" name=\"area[]\" value=\"".htmlspecialchars($opt)."\"$checked> ".htmlspecialchars($opt)."</label> ";
}
?>

四、進階:關聯陣列值(值≠顯示文字)

$options = [
    'hebei'   => '河北省',
    'henan'   => '河南省',
    'shanxi'  => '山西省',
    'shandong'=> '山東省',
];
$preselected = ['hebei', 'shandong']; // 儲存的是 key

foreach ($options as $key => $label) {
    $checked = in_array($key, $preselected, true) ? ' checked' : '';
    echo "<label><input type=\"checkbox\" name=\"area[]\" value=\"$key\"$checked> $label</label> ";
}

// 接收端
$keys = $_POST['area'] ?? [];
// $keys = ['hebei', 'shandong']
// 可直接用於 WHERE IN 查詢或關聯表寫入

五、常見陷阱與解決方案

問題原因解決
只收到最後一個值name 未加 []改為 name="field[]
未勾選任何時 $_POST['field'] 不存在瀏覽器不送出未勾選的 checkbox用 $_POST['field'] ?? [] 並 is_array 防禦
值包含特殊字元導致 XSS直接輸出到 HTMLhtmlspecialchars() 編碼 value 與 label
資料庫存逗號字串,查詢不便設計為單欄字串改用 JSON、關聯表或 PostgreSQL array 型別
大量選項渲染緩慢逐個 echo用陣列組裝字串一次輸出、或分頁/虛擬滾動

六、完整封裝類別(可直接複製使用)

class CheckboxGroup
{
    /** @var array $options key=>label */
    private array $options;
    private string $name;
    private array $preselected;
    private array $allowedValues;

    public function __construct(string $name, array $options, array $preselected = [], array $allowedValues = [])
    {
        $this->name = $name;
        $this->options = $options;
        $this->preselected = $preselected;
        $this->allowedValues = $allowedValues ?: array_keys($options);
    }

    public function render(array $attrs = []): string
    {
        $attrStr = '';
        foreach ($attrs as $k => $v) $attrStr .= ' ' . $k . '="' . htmlspecialchars($v) . '"';
        $html = '';
        foreach ($this->options as $value => $label) {
            $checked = in_array($value, $this->preselected, true) ? ' checked' : '';
            $html .= "<label$attrStr><input type=\"checkbox\" name=\"" . htmlspecialchars($this->name) . "[]\" value=\"" . htmlspecialchars($value) . "\"$checked> " . htmlspecialchars($label) . "</label> ";
        }
        return $html;
    }

    public static function getCleanInput(string $name, array $allowed = []): array
    {
        $input = $_POST[$name] ?? $_GET[$name] ?? [];
        if (!is_array($input)) return [];
        return $allowed ? array_intersect($input, $allowed) : $input;
    }
}

// 使用範例
$group = new CheckboxGroup('area', [
    'hebei' => '河北', 'henan' => '河南', 'shanxi' => '山西',
], ['hebei'], ['hebei','henan','shanxi']);

echo $group->render(['class' => 'form-check-input']);

// 處理端
$clean = CheckboxGroup::getCleanInput('area', ['hebei','henan','shanxi']);
// $clean = ['hebei']

七、資料庫儲存建議

  1. JSON 欄位(MySQL 5.7+/PostgreSQL):json_encode($clean) 存入,查詢用 JSON_CONTAINS 或 @>。
  2. 關聯表:user_area (user_id, area_code),標準化、易查詢、支援外鍵。
  3. 逗號字串:僅適合極簡單、不需索引查詢的場景。

總結

Checkbox 多選核心在於 name="[]"、伺服器端預設空陣列、in_array 判斷預選、白名單過濾輸入。封裝為可複用元件可大幅減少重複代碼並提升安全性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved