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

PHP 表單數組輸入:name="field[]" 獲取多值的正確姿勢

     編輯:PHP 相關知識

問題場景

HTML 表單中多個同名輸入框 (如動態添加的行、複選框),直接用 name="field" 只能獲取最後一個值。需用 name="field[]" 讓 PHP 解析為數組。

HTML 結構

<form method="post" action="">
    <table>
        <tr>
            <th>商品名</th><th>價格</th><th>數量</th>
        </tr>
        <!-- 第 1 行 -->
        <tr class="item-row">
            <td><input type="text" name="items[0][name]" required></td>
            <td><input type="number" name="items[0][price]" step="0.01" min="0" required></td>
            <td><input type="number" name="items[0][qty]" min="1" value="1" required></td>
        </tr>
        <!-- 第 2 行 (JS 動態添加) -->
        <tr class="item-row">
            <td><input type="text" name="items[1][name]" required></td>
            <td><input type="number" name="items[1][price]" step="0.01" min="0" required></td>
            <td><input type="number" name="items[1][qty]" min="1" value="1" required></td>
        </tr>
    </table>
    <button type="button" id="addRow">+ 添加行</button>
    <button type="submit">提交訂單</button>
</form>

PHP 處理

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // 獲取二維數組
    $items = $_POST['items'] ?? [];
    
    // 驗證結構
    if (!is_array($items)) {
        die('數據格式錯誤');
    }
    
    $validItems = [];
    foreach ($items as $index => $item) {
        // 過濾非數組項 (防範污染)
        if (!is_array($item)) continue;
        
        $name = trim((string)($item['name'] ?? ''));
        $price = filter_var($item['price'] ?? '', FILTER_VALIDATE_FLOAT, ['options' => ['min_range' => 0]]);
        $qty = filter_var($item['qty'] ?? '', FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]);
        
        if ($name === '' || $price === false || $qty === false) {
            // 記錄錯誤行號,返回前端提示
            continue;
        }
        
        $validItems[] = [
            'name' => $name,
            'price' => $price,
            'qty' => $qty,
            'subtotal' => $price * $qty,
        ];
    }
    
    if (empty($validItems)) {
        die('至少需要一個有效商品');
    }
    
    // 業務邏輯:保存訂單、計算總價...
    $total = array_sum(array_column($validItems, 'subtotal'));
    echo "訂單提交成功,共 " . count($validItems) . " 種商品,總計 ¥" . number_format($total, 2);
    
    // 調試輸出
    // var_dump($validItems);
}

JS 動態添加行 (維护索引)

<script>
document.getElementById('addRow').addEventListener('click', () => {
    const tbody = document.querySelector('table tbody') || document.querySelector('table');
    const rows = tbody.querySelectorAll('.item-row');
    const newIndex = rows.length; // 0-based 索引
    
    const tr = document.createElement('tr');
    tr.className = 'item-row';
    tr.innerHTML = `
        <td><input type="text" name="items[${newIndex}][name]" required></td>
        <td><input type="number" name="items[${newIndex}][price]" step="0.01" min="0" required></td>
        <td><input type="number" name="items[${newIndex}][qty]" min="1" value="1" required></td>
        <td><button type="button" class="remove-row">刪除</button></td>
    `;
    tbody.appendChild(tr);
    
    // 綁定刪除事件 (需重新索引或使用 data-index)
    tr.querySelector('.remove-row').addEventListener('click', (e) => {
        e.target.closest('tr').remove();
        reindexRows();
    });
});

function reindexRows() {
    document.querySelectorAll('.item-row').forEach((row, i) => {
        row.querySelectorAll('input').forEach(input => {
            // 替換 name 中的索引
            input.name = input.name.replace(/items\[\d+\]/, `items[${i}]`);
        });
    });
}
</script>

複選框/多選下拉框

<!-- 多選下拉 -->
<select name="tags[]" multiple>
    <option value="php">PHP</option>
    <option value="js">JavaScript</option>
    <option value="go">Go</option>
</select>

<!-- 複選框組 -->
<label><input type="checkbox" name="colors[]" value="red"> 紅</label>
<label><input type="checkbox" name="colors[]" value="green"> 綠</label>
<label><input type="checkbox" name="colors[]" value="blue"> 藍</label>

<?php
$tags = $_POST['tags'] ?? []; // ['php', 'go']
$colors = $_POST['colors'] ?? []; // ['red', 'blue']
// 注意:未勾選時 $_POST 不包含該鍵,而非空數組
// 建議:$tags = (array)($_POST['tags'] ?? []);

進階:嵌套數組與 JSON 輸入

現代 SPA/Vue/React 前端常直接發送 JSON,PHP 需手動解析:

<?php
// API 端點
$input = json_decode(file_get_contents('php://input'), true);
if (json_last_error() !== JSON_ERROR_NONE) {
    http_response_code(400);
    exit('Invalid JSON');
}
$items = $input['items'] ?? [];
// 後續驗證邏輯同表單數組

常見錯誤

錯誤後果修正
name="item[]" 但 PHP 用 $_POST['item'] 當字符串Notice: Array to string conversion遍歷數組或 implode(',', $_POST['item'])
動態行索引不連續 (刪除中間行)PHP 仍正常接收,數組鍵為 0,2,3...用 foreach 遍歷,不依賴連續索引
未驗證數組結構直接入庫污染數據、異常嚴格 filter_var + 結構校驗
超大數組導致內存/執行時間耗盡DoS 風險限制最大行數 (如 1000),分頁提交

總結

name="field[]" 是 PHP 解析表單數組的約定語法。關鍵在於:

  1. HTML 正確命名 (支持多維 items[0][name])
  2. JS 維護索引一致性
  3. PHP 用 foreach 遍歷 + filter_var 逐項驗證
  4. 現代項目優先 JSON API,避免表單數組解析歧義
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved