【PHP応用-2】PHPからデータベースを操作せよ!PDOを使った接続と保存

前回、phpMyAdminを使って「箱(データベース)」と「表(テーブル)」を作りました。
今回は、PHPプログラムを使って、その箱の中にデータを放り込んでみましょう。

使う技術は以下の2つです。

  1. PDO(ピーディーオー): PHPとデータベースを繋ぐための「プラグ」のようなもの。
  2. SQL(エスキューエル): データベースへの「命令文」。

データベースに接続する呪文

まずはPHPからデータベースへ電話をかけるようなイメージで、「接続」を確立します。

// データベースの設定(XAMPPの人の例)
$dsn = 'mysql:dbname=bbs_app;host=localhost;charset=utf8mb4';
$user = 'root';
$password = ''; // XAMPPは空欄、MAMPの人は 'root'

try {
    // 接続!
    $pdo = new PDO($dsn, $user, $password);
    echo "接続成功!";
} catch (PDOException $e) {
    echo "接続失敗: " . $e->getMessage();
    exit;
}

解説

  • $dsn(Data Source Name): 「どこの(host)」「どのDB(dbname)」「どの文字コード(charset)」に繋ぐかという宛先情報。
  • try…catch: 「接続を試して(try)、もし失敗したらエラーを受け止める(catch)」という安全装置。これがないとパスワードが画面に丸見えになる事故が起きます。

データを保存する命令「INSERT」

接続ができたら、SQLという言語で「データを入れろ」と命令します。
使うのは INSERT INTO(インサート・イントゥ) 文です。

INSERT INTO テーブル名 (カラムA, カラムB) VALUES ('値A', '値B')

今回の場合、以下のような命令になります。

INSERT INTO messages (username, comment, created_at) VALUES ('田中', 'こんにちは', NOW())

NOW() は「現在時刻」を入れるSQLの便利な関数です。

【最重要】セキュリティの鉄則

ここで初心者が絶対にやってはいけない書き方があります。
変数をSQLの中に直接埋め込むことです。

// ❌ 絶対にダメ!危険!
$sql = "INSERT INTO ... VALUES ('$name', '$text')";

これをやると、悪意あるコードを入力された時にデータベースを破壊される「SQLインジェクション」という攻撃を受けます。

⭕️ 正解:プリペアドステートメント

「値を入れる場所」を一旦「?」や「:name」などの記号(プレースホルダ)にしておき、後から安全に値をはめ込む方法です。

  1. 準備 (prepare): 「ここに値を入れる予定だよ」と予約席を作る。
  2. 実行 (execute): 「ここにはこの値を入れて!」と指示して実行する。

実践:書き込みフォーム作成

では、フォームから入力した内容を、データベースに保存するアプリを作りましょう。

以下のコードを bbs_input.php として保存してください。

<?php
    $message = "";

    // 送信ボタンが押されたら
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        
        // 1. フォームのデータを受け取る
        $username = $_POST['username'];
        $comment  = $_POST['comment'];

        // 2. データベース接続(呪文)
        // ※自分の環境に合わせてパスワードを変えてください
        $dsn = 'mysql:dbname=bbs_app;host=localhost;charset=utf8mb4';
        $user = 'root';
        $password = ''; // MAMPの人は 'root'

        try {
            $pdo = new PDO($dsn, $user, $password);

            // 3. SQLの準備(変な値が来ても大丈夫なように :name の形で場所を空けておく)
            $sql = "INSERT INTO messages (username, comment, created_at) VALUES (:username, :comment, NOW())";
            $stmt = $pdo->prepare($sql);

            // 4. 値をセットして実行(ここで安全に無毒化される)
            $stmt->bindValue(':username', $username, PDO::PARAM_STR);
            $stmt->bindValue(':comment', $comment, PDO::PARAM_STR);
            $stmt->execute();

            $message = "書き込みに成功しました!";

        } catch (PDOException $e) {
            $message = "エラー: " . $e->getMessage();
        }
    }
?>

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>ひとこと掲示板</title>
</head>
<body>

    <h1>ひとこと掲示板</h1>
    
    <!-- メッセージ表示 -->
    <?php if ($message): ?>
        <p style="color: blue;"><?= $message ?></p>
    <?php endif; ?>

    <form action="" method="post">
        名前:<input type="text" name="username" required><br>
        本文:<input type="text" name="comment" required><br>
        <button type="submit">送信</button>
    </form>

</body>
</html>

確認方法

  1. ブラウザで送信してみる。
  2. 「書き込みに成功しました!」と出る。
  3. phpMyAdminを開いて messages テーブルを見る。
  4. データが増えていれば大成功です!

まとめ

  • DB接続には PDO を使う。
  • データを追加するSQLは INSERT INTO
  • セキュリティのため、必ず prepare(準備)bindValue(埋め込み) を使う。

これでデータを入れることができました。
しかし、今のままだと「入ったかどうか」をいちいちphpMyAdminで確認しなくてはいけません。

次回は、保存されたデータを引っ張り出してきて、画面にズラッと並べる「データの一覧表示(SELECT)」を行います。
ここまで来れば掲示板の完成です!

📝 今日のミニテスト

クリックで答え合わせ!

Q1. データベースに新しいデータを追加するSQL命令は?

正解:INSERT INTO
INSERT INTO テーブル名 VALUES (...) という形になります。

 

Q2. XAMPPのデフォルトのMySQLパスワードは?(MAMPの人は?)

正解:XAMPPは「空欄(なし)」、MAMPは「root」
ここを間違えると Access denied という接続エラーが出ます。

 

Q3. SQLインジェクション攻撃を防ぐために使うべき仕組みは?

正解:プリペアドステートメント(prepare / bindValue)
変数を直接SQLの文字として繋げてはいけません。

タイトルとURLをコピーしました