⚠️ 記事内に広告を含みます。

PHPでフォームのデータをDBに登録する方法

PHPでフォームのデータをDBに登録する方法

ユーザから受け取ったデータをサーバ側に保存し、保存したデータを表示するという機能はwebアプリケーションの基本機能です。

HTMLを使ったフォームの作り方とフォームのデータをPHPが受け取る方法は下記事で紹介しました。

次は受け取ったデータをデータベースに保存し、それを表示する方法を紹介します。

DBを用意する

MySQL8.0をインストールして初期セットアップした状態からスタートします。

まずはユーザを登録して、データベースを作成します。

# 現在のユーザを確認
mysql> select user, host from mysql.user;
+------------------+-----------+
| user             | host      |
+------------------+-----------+
| mysql.infoschema | localhost |
| mysql.session    | localhost |
| mysql.sys        | localhost |
| root             | localhost |
+------------------+-----------+
4 rows in set (0.01 sec)

# ユーザ(php_test)を作成する
mysql> create user 'php_test'@'localhost' identified by 'php_test1234';
Query OK, 0 rows affected (0.01 sec)

mysql> select user,host from mysql.user;
+------------------+-----------+
| user             | host      |
+------------------+-----------+
| mysql.infoschema | localhost |
| mysql.session    | localhost |
| mysql.sys        | localhost |
| php_test         | localhost |
| root             | localhost |
+------------------+-----------+
5 rows in set (0.00 sec)
↑hostはlocalhostのみに限定

# 権限の付与
mysql> grant all privileges on *.* to 'php_test'@'localhost';
Query OK, 0 rows affected (0.01 sec)

mysql> show grants for 'php_test'@'localhost'\G
*************************** 1. row ***************************
Grants for php_test@localhost: GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, CREATE ROLE, DROP ROLE ON *.* TO `php_test`@`localhost`
*************************** 2. row ***************************
Grants for php_test@localhost: GRANT APPLICATION_PASSWORD_ADMIN,AUDIT_ABORT_EXEMPT,AUDIT_ADMIN,AUTHENTICATION_POLICY_ADMIN,BACKUP_ADMIN,BINLOG_ADMIN,BINLOG_ENCRYPTION_ADMIN,CLONE_ADMIN,CONNECTION_ADMIN,ENCRYPTION_KEY_ADMIN,FIREWALL_EXEMPT,FLUSH_OPTIMIZER_COSTS,FLUSH_STATUS,FLUSH_TABLES,FLUSH_USER_RESOURCES,GROUP_REPLICATION_ADMIN,GROUP_REPLICATION_STREAM,INNODB_REDO_LOG_ARCHIVE,INNODB_REDO_LOG_ENABLE,PASSWORDLESS_USER_ADMIN,PERSIST_RO_VARIABLES_ADMIN,REPLICATION_APPLIER,REPLICATION_SLAVE_ADMIN,RESOURCE_GROUP_ADMIN,RESOURCE_GROUP_USER,ROLE_ADMIN,SENSITIVE_VARIABLES_OBSERVER,SERVICE_CONNECTION_ADMIN,SESSION_VARIABLES_ADMIN,SET_USER_ID,SHOW_ROUTINE,SYSTEM_USER,SYSTEM_VARIABLES_ADMIN,TABLE_ENCRYPTION_ADMIN,XA_RECOVER_ADMIN ON *.* TO `php_test`@`localhost`
2 rows in set (0.00 sec)

#データベース(php_test)を作成する
mysql> create database php_test;

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| php_test           |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

#テーブルの作成を行う (シェル上でsqlファイルを作成して実行する)
$ cat create_table.sql 
create table php_test.form (
	id int auto_increment not null primary key,
	name VARCHAR(100),
	email VARCHAR(100),
	age INT(3),
	syousai TEXT,
	created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

# sqlをファイルから実行
$ mysql <  create_table.sql 

#mysqlにログインして指定したテーブルができているか確認する。
$ mysql -u root -p

mysql> use php_test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+--------------------+
| Tables_in_php_test |
+--------------------+
| form               |
+--------------------+
1 row in set (0.00 sec)

mysql> explain form;
+------------+--------------+------+-----+-------------------+-------------------+
| Field      | Type         | Null | Key | Default           | Extra             |
+------------+--------------+------+-----+-------------------+-------------------+
| id         | int          | NO   | PRI | NULL              | auto_increment    |
| name       | varchar(100) | YES  |     | NULL              |                   |
| email      | varchar(100) | YES  |     | NULL              |                   |
| age        | int          | YES  |     | NULL              |                   |
| syousai    | text         | YES  |     | NULL              |                   |
| created_at | timestamp    | NO   |     | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
+------------+--------------+------+-----+-------------------+-------------------+
6 rows in set (0.00 sec)

登録フォームをHTMLで作成

データベースには名前、Eメールアドレス、年齢を登録するので登録用のフォームを作成します。フォームの送信先はtouroku.phpでPOSTメソッドで送信します。

<!DOCTYPE html>
<html lang="ja" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>DB登録フォーム</title>
  </head>
  <body>

    <form action="touroku.php" method="post">
        <label for="name">Enter your name:</label>
          <input type="text" name="name"><br>

        <label for="email">Enter your Email:</label>
          <input type="email" name="email"><br>

        <label for="age">Choose age blow:</label>
          <input type="number" name="age" min="0" max="120"><br>
    <input type="submit" value="送信">
    </form>

  </body>
</html>

PHPからDBに接続して登録

MySQL関数:mysql_connect関数 (PHP5系まで)

MySQL関数はPHP7系からは削除されていますが、PHP5系まではよく利用されています。

$link = mysql_connect('127.0.0.1', 'mysql_user', 'mysql_password');

# mysql_connectで接続できた場合はMySQLリンクIDが入り、失敗するとFALSEを返します。

if (!$link) {
    exit('接続できませんでした: ' . mysql_error());
}
# mysql_errorはMySQL処理のエラーメッセージが入る
echo '接続に成功しました';
mysql_close($link);

#mysql_closeでMySQLとの接続を閉じます。

mysql_select_db関数:https://www.php.net/manual/ja/function.mysql-select-db.php
mysql_connect関数:https://www.php.net/manual/ja/function.mysql-connect.php

PHP7系で実行するとMySQL関数が無いのでundefinedと怒られます。

HP Fatal error:  Uncaught Error: Call to undefined function mysql_connect() in

PHP7以降はmysqliかPDOを利用してDBに接続する

古いPHP5系の方法については触れません。

PHP7以降では2つの選択肢がありますが、理由がなければPDOを利用するのが良さそうです。

  • PDO (PHP Data Objects)
  • mysqli

mysqliはmysqlの改良版で複数のステートメント実行やトランザクションをサポートしています。MySQLなどDBに詳しい場合はmysqliを選択しても良さそうです。

mysqliについての概要:https://www.php.net/manual/ja/mysqli.overview.php

PDOでDBに接続する

PDOを利用するにはまずPDインスタンスを作成します

<?php
#DB接続に必要な情報($dsn:Data Source Name)を定義
$dsn = 'mysql:dbname=データベースの名前;host=127.0.0.1';
$user = 'DBのユーザ名';
$password = 'DBのパスワード';

$dbh = new PDO($dsn, $user, $password);
?>

https://www.php.net/manual/ja/pdo.construct.php

https://www.php.net/manual/ja/class.pdo.php

テーブルに登録する

DBへのデータの追加はINSERTを使います。

formというテーブルには以下のカラム(id, name, email, age, spousal, created_at)があります。

mysql> desc form;
+------------+--------------+------+-----+-------------------+-------------------+
| Field      | Type         | Null | Key | Default           | Extra             |
+------------+--------------+------+-----+-------------------+-------------------+
| id         | int          | NO   | PRI | NULL              | auto_increment    |
| name       | varchar(100) | YES  |     | NULL              |                   |
| email      | varchar(100) | YES  |     | NULL              |                   |
| age        | int          | YES  |     | NULL              |                   |
| syousai    | text         | YES  |     | NULL              |                   |
| created_at | timestamp    | NO   |     | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
+------------+--------------+------+-----+-------------------+-------------------+
6 rows in set (0.00 sec)

このテーブルに以下のデータを登録します。

  1. 名前:Minamino takuya
  2. メール:Takuya@example.com
  3. 年齢:36

mysqlに直接登録する場合のSQLはINSERT文で以下のように書きます。

mysql> INSERT into form (name, email, age) values ('minamino takuya', 'takuya@example.com', 36);
Query OK, 1 row affected (0.00 sec)

# 文法 -> INSERT into "テーブル名" (カラム名,...) value ('入れる値', ...);

# 実際に入れたデータを確認する(SELECT文)
mysql> SELECT id,name,email,age from form;
+----+-----------------+--------------------+------+
| id | name            | email              | age  |
+----+-----------------+--------------------+------+
|  1 | minamino takuya | takuya@example.com |   36 |
+----+-----------------+--------------------+------+
1 row in set (0.00 sec)

これと同様のことをPDOで実施します。

<?php
    #変数をセットする
    $name = 'taro takuya';
    $email = 'taro@example.com';
    $age = 11;

    # connect mysql PDO
    $dsn = 'mysql:dbname=php_test;host=127.0.0.1';
    $user = 'php_test';
    $password = 'php_test1234';

    $pdo = new PDO($dsn, $user, $password);
    $sql = $pdo->prepare("INSERT into form (name, email, age) values (:name, :email, :age)");

    # bindPramで:nameなどを変数$nameに設定、PARAM_でデータ型を指定
    $sql->bindParam( ':name', $name, PDO::PARAM_STR);
    $sql->bindParam( ':email', $email, PDO::PARAM_STR);
    $sql->bindParam( ':age', $age, PDO::PARAM_INT);

    $res = $sql->execute();
    $pdo = null;
?>

実際にtaro takuyaのデータが入っているかをmysql上で確認してみます

mysql> SELECT id,name,email,age from form;
+----+-----------------+--------------------+------+
| id | name            | email              | age  |
+----+-----------------+--------------------+------+
|  1 | minamino takuya | takuya@example.com |   36 |
|  2 | taro takuya     | taro@example.com   |   11 |
+----+-----------------+--------------------+------+
2 rows in set (0.00 sec)

簡単なフォームを作ってそこからDBに登録する

pdoを使ってPHPからmysqlへのデータ登録の仕組みが分かったところで次は

form.htmlで簡単な入力フォームを作成し、そこからDBに登録します

フォーム入力データがきちんと入力されているかを確認する

名前、Eメール、年齢を登録するフォーム(form.html)をhtmlで作成しましょう。

このフォームで呼び出すphpはhyouzi.php (form action=”hyouzi.php”)です。

<!DOCTYPE html>
<html lang="ja" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>DB登録フォーム</title>
  </head>
  <body>

    <form action="form.php" method="post">
        <label for="name">Enter your name:</label>
          <input type="text" name="name"><br>

        <label for="email">Enter your Email:</label>
          <input type="email" name="email"><br>

        <label for="age">Choose age blow:</label>
          <input type="number" name="age" min="0" max="120"><br>
    <input type="submit" value="送信">
    </form>

  </body>
</html>

次にこのフォームで登録する内容を表示するhyouzi.phpを作成します。

<?php
echo $_POST['name'];
echo "<br>";
echo $_POST['email'];
echo "<br>";
echo $_POST['age'];
?>

これでブラウザからhttps://example.com/form.htmlを実行するとフォームが現れて各登録情報を入力して送信すると入力した文字列が表示されると思います。

登録用のフォームを作成する

それではmysqlに登録するform.htmlを作成しましょう。

<!DOCTYPE html>
<html lang="ja" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>DB登録フォーム</title>
  </head>
  <body>

    <form action="touroku.php" method="post">
        <label for="name">Enter your name:</label>
          <input type="text" name="name"><br>

        <label for="email">Enter your Email:</label>
          <input type="email" name="email"><br>

        <label for="age">Choose age blow:</label>
          <input type="number" name="age" min="0" max="120"><br>
    <input type="submit" value="送信">
    </form>

  </body>
</html>

フォームデータ送付先のtouroku.phpを作成します。

こちらのPHPでPOSTで受け取ったデータをDBに登録します。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>DB登録</title>
</head>
<body>
<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $age = $_POST['age'];

    #フォームが全て入力されているかチェックする
   if ($name === '' || $email === '' || $age === '')  {
	   echo "入力に不備があります。<br>";
	   echo "<a href="."/form.php".">フォームに戻って編集します。</a>";

          # header('Location: form.php');
           exit();
   } 
    # connect mysql PDO
    $dsn = 'mysql:dbname=php_test;host=127.0.0.1';
    $user = 'php_test';
    $password = 'php_test1234';

    $pdo = new PDO($dsn, $user, $password);
    $sql = $pdo->prepare("INSERT into form (name, email, age) values (:name, :email, :age)");

    # bindPramで:nameなどを変数$nameに設定、PARAM_でデータ型を指定
    $sql->bindParam( ':name', $name, PDO::PARAM_STR);
    $sql->bindParam( ':email', $email, PDO::PARAM_STR);
    $sql->bindParam( ':age', $age, PDO::PARAM_INT);

    $res = $sql->execute();
    $pdo = null;

?>

<p>DB登録完了。<br /><a href="form.html">フォーム画面に戻る</a></p>
</body>
</html>

MySQLから確認するとデータが登録されているのが確認できます。

form.htmlのブラウザ上の見た目
ysql> SELECT id,name,email,age from form;
+----+-----------------+--------------------+------+
| id | name            | email              | age  |
+----+-----------------+--------------------+------+
|  1 | minamino takuya | takuya@example.com |   36 |
|  2 | taro takuya     | taro@example.com   |   11 |
|  3 | test            | test@example.com   |   67 |
+----+-----------------+--------------------+------+
3 rows in set (0.00 sec)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です