初級 jQuery PHP フォーム 配列

「行追加」ボタンで入力欄を増やす(テキスト)

ボタンを押すたびにフォームの入力欄が1行ずつ増える仕組みを作ります。増えた入力欄の値を、PHP で配列としてまとめて受け取る方法も学びます。

このサンプルは2017〜2018年ごろに作成したものです。PHPのバージョンが上がり、そのままでは動かなくなっていたため、2026年に PHP 8.3 で動くように書き直し、解説も新しくしました。

DEMO 実際に動かしてみよう

料理の「材料」と「数量」を入力する表です。「行追加」を押すと入力欄が1行ずつ増えます。いくつか入力して「送信」を押すと、PHP が受け取った値を確認できます。

材料 数量

解説コードを読んでみよう

このサンプルでわかること

  • jQuery で表(table)に1行ずつ入力欄を追加する方法
  • name="text_1[]" のように [] を付けると、PHP で配列として受け取れること
  • 受け取った配列を foreach で1行ずつ取り出す方法

使っているファイル

  • index.php入力フォームと「行追加」の JavaScript
  • data.php送信された値を受け取って表示する PHP

1. 入力フォームを作る

入力欄は表(table)の中に並べます。行を追加する場所は <tbody> の中です。ボタンは <tfoot> に置いて、行が増えても常に表のいちばん下に来るようにしています。

index.php(13〜35行目) PHP
<form action="data.php" method="post">
<table class="add-form">
  <thead>
    <tr>
      <th>材料</th>
      <th>数量</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><input type="text" name="text_1[]" placeholder="例:たまご"></td>
      <td><input type="text" name="text_2[]" placeholder="例:2個"></td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td colspan="2"><button id="add" class="btn btn-default" type="button">+ 行追加</button></td>
    </tr>
  </tfoot>
</table>
<hr>
<input type="submit" class="btn btn-default" name="send" value="送信">
</form>

注目してほしいのは入力欄の名前です。name="text_1[]" のように、名前の最後に [] を付けています。

同じ名前の入力欄がいくつもあると、普通は最後の1つの値しか PHP に届きません。名前に [] を付けておくと、PHP は同じ名前の値を全部まとめて配列で受け取ってくれます。入力欄の数が決まっていない「行追加」フォームでは、この書き方が欠かせません。

2. 「行追加」ボタンで1行増やす(jQuery)

index.php(37〜53行目) PHP
<script>
$(function() {

  // 「行追加」ボタンが押されたら、1行分の HTML を表の最後に追加する
  $('button#add').click(function(){

    var tr_row = '' +
    '<tr>' +
      '<td><input type="text" name="text_1[]"></td>' +
      '<td><input type="text" name="text_2[]"></td>' +
    '</tr>';

    $(tr_row).appendTo($('.add-form > tbody'));
  });

});
</script>
  1. $('button#add').click(function(){ ... }) … 「行追加」ボタン(id="add")がクリックされたら、中の処理を実行します。
  2. var tr_row = '<tr>...</tr>' … 追加する1行分の HTML を文字列として作ります。最初の行と同じ name にするのがポイントです。
  3. $(tr_row).appendTo($('.add-form > tbody')) … 文字列を HTML の部品に変えて、class="add-form" の表の tbody の最後に追加します。

追加先を $('table > tbody') のように書くと、ページ内のすべての表に行が追加されてしまいます。class="add-form" のような目印を付けて、追加先の表を1つに絞りましょう。

ボタンには必ず type="button" を付けます。<form> の中にある <button> は、何も書かないと「送信ボタン」として扱われ、押した瞬間にフォームが送信されてしまいます。

3. PHP で配列として受け取る

送信先の data.php では、$_POST['text_1'] が配列になっています。たとえば2行入力して送信すると、中身は次のようになります。

print_r($_POST) の結果 TEXT
Array
(
    [text_1] => Array
        (
            [0] => たまご
            [1] => 牛乳
        )
    [text_2] => Array
        (
            [0] => 2個
            [1] => 200ml
        )
    [send] => 送信
)

同じ行の「材料」と「数量」は、同じ番号(添字)に入ります。そこで、text_1 を foreach で1つずつ取り出し、同じ番号の text_2 と組み合わせて表にしています。

data.php(5〜7行目) PHP
// 受け取った値(送信されていなければ空の配列にする)
$text_1 = (array)($_POST['text_1'] ?? []);
$text_2 = (array)($_POST['text_2'] ?? []);
data.php(20〜29行目) PHP
<table class="table table-striped">
  <tr><th>添字 [i]</th><th>$_POST['text_1'][i](材料)</th><th>$_POST['text_2'][i](数量)</th></tr>
<?php foreach ($text_1 as $i => $value): ?>
  <tr>
    <td><?= h($i) ?></td>
    <td><?= h($value) ?></td>
    <td><?= h($text_2[$i] ?? '') ?></td>
  </tr>
<?php endforeach; ?>
</table>

画面に表示するときは、必ず h()(中身は htmlspecialchars())を通しています。入力欄に <script> などを書かれても、ただの文字として表示されるので安全です。

PHP 8.3 で書き直したポイント

何も送信せずに data.php を直接開くと、$_POST['text_1'] は存在しません。古い書き方のままだと PHP 8 では警告が出るため、?? [](値がなければ空の配列を使う)で初期値を決めてから使うようにしました。

data.php PHP
// 送信されていなければ空の配列にする
$text_1 = (array)($_POST['text_1'] ?? []);

3列目に「メモ」の入力欄(name="text_3[]")を追加してみましょう。最初の行と、JavaScript で追加する行の両方に書き足すのを忘れずに。data.php では $_POST['text_3'] で受け取れます。

↑