PHPでプレースホルダを使ったフォーム作成


PHPでフォーム作成

以前の記事で、DVWAでは変数をSQL文にそのままいれたことから、SQLインジェクションが可能なコードとなってしまっていました。

そこで今回は、そんなSQLインジェクションに対処するための方法として、プレースホルダについて紹介したいと思います。

プレースホルダとは?

プレースホルダはその名の通り、SQL文に対して後から値をセットするための場所を確保する機能となっています。

プレースホルダは、疑問符プレースホルダの?、名前付きプレースホルダの:値、で表現されまます。

また、後から入れる値のバインド値のことを、プリペアドステートメント(予約文)と言います。

このプレースホルダを使うことによって、入力値から直接SQLインジェクションが行われることを、回避できるというわけです。

HTML/PHP/MySQLでフォーム作成

ここでは、実際にフォームを作成し、プレースホルダを使うコードについて記載していきたいと思います。

コードは下記の記事を参考にしています。
https://noumenon-th.net/programming/2016/01/18/mysql-2/

前提条件

  • PHP 5.46
  • MySQL 14.14

MySQLでDB、テーブル、カラムの設定

まずは、MySQLでDBとテーブルとカラムをセットしていきます。

ここではDBをtest1、テーブルをname_list、カラムをid・nameでセットします。

# mysql -u root -p

mysql> CREATE DATABASE test1;
mysql> USE test1;
mysql> CREATE TABLE name (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,name TEXT NOT NULL) DEFAULT CHARACTER SET=utf8;

フォームのHTMLファイルを作成

まず基本となる簡単な、フォームをHTMLで記載していきます。

index.html
<!DOCTYPE html>
<html>
  <head>
    <title>データを入力する</title>
    <meta charset="utf-8">
    </head>
<body>
  <h1>フォーム画面</h1> 
      <form action="form.php" method="post">
          名前を入力:<input type="text" name="name">
          <input type="submit" value="登録する">
      </form>
</body>
</html>

フォーム情報を登録するPHPファイル作成

次に、フォーム情報をMySQLに登録するPHPファイルを作成していきます。

SQL文はプレースホルダを使って表示していきます。

form.php
<?php

header("Content-type: text/html; charset=utf-8");

//データベース接続
$server = "IPアドレス";  
$userName = "MySQLのユーザー名"; 
$password = "MySQLのパスワード"; 
$dbName = "test1";

$mysqli = new mysqli($server, $userName, $password, $dbName);

if ($mysqli->connect_error){
    echo $mysqli->connect_error;
    exit();
}else{
    $mysqli->set_charset("utf-8");
}

if(empty($_POST)) {
    echo "<a href='index.php'>index.php</a>←登録はこのページから";
}else{
    //名前入力判定
    if (!isset($_POST['name'])  || $_POST['name'] === "" ){
        echo "名前が入力されていません。";
    }else{
        //プリペアドステートメントの設定(SQL文を最初に用意して、その後はクエリ内のパラメーターの値だけを変更する)
        $stmt = $mysqli->prepare("INSERT INTO name_list (name) VALUES (?)");

        if($stmt){
            //プレースホルダに値を設定する、bind_paramsの第一引数は文字列が入るので's'
            $stmt->bind_param('s', $name);
            $name = $_POST['name'];

            //登録する名前をhtml表記、クオテーションを取った状態で表示
            if($stmt->execute()){
                echo htmlspecialchars($name, ENT_QUOTES, 'UTF-8')."さんを登録しました";
            }else{
                echo $stmt->errno . $stmt->error;
            }

            $stmt->close();
        }else{
            echo $mysqli->errno . $mysqli->error;
        }
    }
}

// データベース切断
$mysqli->close();

?>

実際にはこんな感じに動作します。

これで、プレースホルダを利用したPHPのフォーム作成は完了です。