作成日:2021/04/12 更新日:2022/06/24

#5 formタグから入力したデータをDBに登録

フォーム部分の作成

htmlでフォーム部品を作ります。
ユーザーがフォームに入力して「送信」ボタンを押したら、 そのフォームに入力されたデータを、データベースに登録する。という処理をしたいと思います。
このようなイメージです。①➔④の処理をコーディングしてみましょう。
まずhtmlを組み立てます。

<body>
<div id="wrapper">

<div id="input_form">
  <form action="index.php" method="POST">
    <input type="text" name="inputName">
    <input type="submit" value="登録">
  </form>
</div><!--/ #input_form-->

<div id="drag-area">
<?php
 表示させる処理…
?>
</div><!--/ #drag-area-->

</div><!--/ #wrapper-->
</body>
<input type="text" name="inputName"> ここのname=" "のクオーテーション部分が、 連想配列のラベル名になります。$_POST['ラベル名']

PHPでデータを受け取り、DBに登録

htmlのformタグからPOST受信した「名前(連想配列)」をデータベースに登録します。 <!DOCTYPE>より上の、データベースへ接続した処理記述の次の行あたりに記述しましょう。

if(!empty($_POST['inputName'])){
  try{
    $sql  = 'INSERT INTO sortable(name) VALUES(:ONAMAE)';
    $stmt = $dbh->prepare($sql);

    $stmt->bindValue(':ONAMAE', $_POST['inputName'], PDO::PARAM_STR);
    $stmt->execute();

    header('location: http://localhost:8001/');
    exit();
  } catch (PDOException $e) {
      echo 'データベースにアクセスできません!'.$e->getMessage();
  }
}

まず「データが渡ってきたら」という条件分岐から開始

if文で「データが来たら、try{ }catch{ }文を実行する」という条件分岐をしています。
!empty( 〜 )は、〜というデータが入っていたら の意味です。 つまり、$_POST['inputName']というデータが有ればということになります。

formタグ内のinputタグname属性名"inputName"というデータがPOSTでsubmitされると、 $_POST['inputName']という変数を、formタグのaction属性のURLに飛ばすという処理を行っています。

登録ボタンが押されたら、$_POST['inputName']という名前の(中身は入力された文字列の)データが index.phpに飛ぶのでそれを受信した瞬間にこの機能が作動するということです。


$sql = 'INSERT INTO sortable(name) VALUES(:ONAMAE)';
SQL文:テーブル`sortable`のカラム`name`に、VALUES()で指定したデータを挿入させる命令文です。
このときの、入れている引数「:ONAMAE」はプレースホルダ(仮に確保した場所)と呼ばれており、 :コロンparameterパラメータ という形で指定します。 実際のデータはその後のbindValue()関数で設定します。


$stmt = $dbh->prepare($sql);
prepare():値をデータベースに入れる準備(プリペア)をします。引数はSQL文が入ります。
プリペアドステートメントと呼ばれ、SQL文にあるVALUESの値をプレースホルダで置き換えて、安全にクエリを実行します。


$stmt->bindValue(':ONAMAE', $_POST['inputName'], PDO::PARAM_STR);

bindValue('SQL文で使われているプレースホルダ名', データ, 型指定);
bindValue():データ(値や変数)を、SQL文で使われているプレースホルダに結びつける(バインドする)。
PDO::PARAM_STR:文字列データであることを指示。


$stmt->execute();
execute():実行します。バインドされた変数を参照しデータベースに登録。

自分の名前やなにかをを、formから登録してみましょう。
確かにDBの13番目にオートインクリメントされ、例ではnameに「(例)櫻井翔」が入りました。 left_xとtop_yは指定していないのでNULL値が入っています。
ここまでのindex.php

<?php
error_reporting(-1);

/* データベース設定 */
define('DB_DNS', 'mysql:host=localhost; dbname=cri_sortable; charset=utf8');
define('DB_USER', 'root');
define('DB_PASSWORD', 'root');

/* データベースへ接続 */
try {
  $dbh = new PDO(DB_DNS, DB_USER, DB_PASSWORD);
  $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
} catch (PDOException $e){
    echo $e->getMessage();
    exit;
}

/* データベースへ登録 */
if(!empty($_POST['inputName'])){
  try{
    $sql  = 'INSERT INTO sortable(name) VALUES(:ONAMAE)';
    $stmt = $dbh->prepare($sql);

    $stmt->bindValue(':ONAMAE', $_POST['inputName'], PDO::PARAM_STR);
    $stmt->execute();

    header('location: http://localhost:8001/');
    exit();
  } catch (PDOException $e) {
      echo 'データベースにアクセスできません!'.$e->getMessage();
  }
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>8001-cri-sortable</title>
  <link href="css/style.css" rel="stylesheet">
</head>
<body>
<div id="wrapper">

<div id="input_form">
  <form action="index.php" method="POST">
    <input type="text" name="inputName">
    <input type="submit" value="登録">
  </form>
</div>

<div id="drag-area">
<?php
$sql = 'SELECT * FROM sortable';
$stmt = $dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
foreach ($stmt as $result)){
  echo '  <div class="drag" data-num="'.$result['id'].'" style="left:'.$result['left_x'].'px; top:'.$result['top_y'].'px;">'.PHP_EOL;
  echo '    <p><span class="name">'.$result['id'].' '.$result['name'].'</span></p>'.PHP_EOL;
  echo '  </div>'.PHP_EOL;
}
?>
</div>

</div>
</body>
</html>