ことれいのもり

PHPで複数データをPOST送信する方法

はじめに

PHPであるデータを配列として送信したいときの方法をまとめました。

同じような項目をまとめて送信すると、foreach文のループで値を取り出すことができて便利です。

自作CMSの、画像とalt属性を複数送信したいときの処理で使いました。

前提

言語: PHP 8

参考リンク

方法

$_POSTで送る方法は、name属性に [ ] という記号をつけてform属性で囲むだけです。

複数のテキストを送ることができる以下のようなフォームがあるとします。

<form method="POST" action="upload.php">
    <input type="text" name="input_texts[]" placeholder="テキスト">
    <input type="text" name="input_texts[]" placeholder="テキスト">
    <input type="text" name="input_texts[]" placeholder="テキスト">
</form>

配列のマーク [ ] これをつけると見かけ上は全てinput_texts[ ]ですが、上から順番にinput_texts[0]、input_texts[1]、input_texts[2]と割り振られます。

このデータを使いたいときは、foreachを使うだけで簡単に取り出すことができます。

// テキストを取得
if (!empty($_POST['input_texts'])) {
    foreach($_POST['input_texts'] as $index => $input_text) {
        echo "テキスト" . $index . ": " . htmlspecialchars($index, ENT_QUOTES, 'UTF-8');
    }
}

簡単ですね!

実装例

以下の画像は私が作った自作CMSの記事編集画面です。

画像ファイルとalt属性のテキストをセットとして、それを複数追加することができます。

このとき、それぞれのファイルとalt属性のテキストを配列にして$_POSTで送っています。

記事編集画面の画像

<form action="<?= htmlspecialchars($formAction) ?>" method="POST" enctype="multipart/form-data">
    <!-- 省略: タイトル入力、カテゴリ選択など -->

    <div class="not-inserted-image-set">
    <label>【未挿入】</label>
      <div id="image-input-container">
        <div class="image-input-set">
          <label for="image" class="file-input-label">画像を選択</label>
          <input type="file" id="image" class="hidden-file-input" name="images[]" accept="image/*">
          <input type="text" id="alt_text" name="alt_texts[]" placeholder="altテキスト">
        </div>
      </div>
      <button type="button" id="add-image-button">+ 画像を追加</button>
    </div>
  </div>

    <!-- 省略: 送信ボタンなど -->
 </form>

ファイルはimages[ ] 、alt属性のテキストはalt_texts[ ]というname属性をつけ、formタグのmethodをPOSTにして囲みます。

// 画像の受け取り
if (!empty($_FILES['images']['name'][0])) {
      foreach ($_FILES['images']['name'] as $index => $imageName) {
        $file = [
          'name' => $_FILES['images']['name'][$index],
          'tmp_name' => $_FILES['images']['tmp_name'][$index],
          'type' => $_FILES['images']['type'][$index],
          'size' => $_FILES['images']['size'][$index],
          'error' => $_FILES['images']['error'][$index],
        ];

      // alt属性のテキストの受け取り
        $altText = isset($_POST['alt_texts'][$index]) ? $_POST['alt_texts'][$index] : '';

      // 画像を圧縮して送信
        $imageInfo = $this->uploadImage($file, null, $index);

        // DBに送るデータをひとまとめにする
        $imageData[] = [
          'tmp_path' => $imageInfo['tmp_path'],
          'file_name' => basename($imageInfo['url_path']),
          'file_path' => $imageInfo['url_path'],
          'alt_text' => $altText,
        ];
      }
    }

そしてこれらをforeach文のループの中で受け取っています。

$indexをうまく使うことで、同じ処理を複数書くことなく実装できました。

ここまでの話をまとめると、

まとめて送りたい要素のname属性に配列マーク[ ] をつけて、formタグにPOSTを指定する だけです!

おわりに

データをPOSTでまとめて送る方法を説明しました。

htmlの要素の中に配列マークを書くのはなんだか不思議なかんじがしますが、慣れると便利なので使ってみてください。