PHPでDBに接続、CRUDを利用して掲示板を作る③　Updateについて

過去の記事はこちらから

①DB接続から記事投稿まで（Create）
https://qiita.com/progterry/items/2f82b82a5118c16010a0

②Read機能について
https://qiita.com/progterry/items/1b0d1576c5d90af003ba

今回はCRUDの中でもUpdateに触れていこうと思います。

Updateは、一度掲示板に投稿した内容を編集し、更新（上書き）する機能です。

そのためには、idの使い方が重要になってきます。
idはテーブルを作成したときに、カラムを作成しておいてA.Iを設定しておきます。
おうすることで、投稿順に自動的にidが割り振られていきます。

詳細はこのあたりの記事を参考にしてください
https://www.dbonline.jp/mysql/table/index7.html

Updateするためには、
１．readの画面で、「編集」の項目を作る
２．「編集」のための機能を実装する

の大まかに分けて2つが必要です。
まず１から。

#readの画面で「編集」の項目を作る
read.phpの、投稿者と発言の表示を、今回ではテーブル状態に整えます。
コードとしては以下のようになります。

```
echo "<table>";
    echo "<tr>";
    echo "<th>お名前</th><th>メッセージ</th>\n";
    echo "</th>";
    foreach($stmt as $user){
        echo "<tr>\n";
            echo "<td>" . $user['submit_name'] . "</td>\n";
            echo "<td>" . $user['submit_content'] . "</td>\n";
            echo  "<td>" . "<a href=edit.php?id=" . $user['id'] . ">編集する</a>" . "</td>\n";
            echo  "<td>" . "<a href=delete_confirm.php?id=" . $user['id'] . ">削除する</a>" . "</td>\n";            
        }


echo "</table>";
```

こうすることで、テーブル状態で表示されます。
また、CRUDのDELETEを見越して、「削除する」の項目も付け足しておきました。

この中で大事なのは、

```
"<a href=edit.php?id=" . $user['id'] . ">
```

この部分です。
DBのテーブルのカラムは、
id
submit_name
submit_content
と名付けています。
それぞれ、

（蛇足。submit_nameは投稿者を示すように設定し、submit_contentは投稿内容を示すように設定してあります。）

a hrefでリンクを設定し、リンク先はedit.php（内容を変更するための画面）に設定します。
しかしこれだけだと、「どの投稿内容を変更するのか」が分からないため、A.Iされたidで投稿内容を区別します。
そのために
```$user['id'] .```
でidをテーブルから受け取ります。
idが1であれば、一番目に投稿された内容ということで、1番目の投稿内容の編集画面にうつります。

#編集画面を作る
今度は別ファイルで項目の編集機能を実装します。

コードを前半部と後半部に分けます。

##DB接続まで
前半部。

```
<?php

try{

    //DBに接続
    $dsn = 'mysql:dbname=test_bbs2; host=localhost';
    $username= 'root';
    $password= 'root';

    $dbh = new PDO($dsn, $username, $password);
    //準備
    $stmt = $dbh->prepare('SELECT * FROM contacts WHERE id = :id');

    //実行
    $stmt->execute(array(':id' => $_GET["id"]));
    $result = $stmt->fetch(PDO::FETCH_ASSOC);

    echo "OK";
    echo "<br>";
} catch(PDOException $e){
    echo "失敗:" . $e->getMessage() . "\n";
    exit();
}
?>
```

前半部では主にDBへの接続を行っています。
```SELECT * FROM contacts WHERE id = :id
```
この部分では、contactsテーブルからすべてを参照し、WHERE区でidを限定しています。
idを限定するのですが、「どのidを指定するのか？」が分からないため、
id = :idとして仮置きしておきます。
ここの仮置きは、？マークとかでも代用できるのですが、機能的な違いは（今のところ）探せませんでした。単純にどちらが書きやすいかor見やすいか？だけなのか？

```
$stmt->execute(array(':id' => $_GET["id"]));
```
この部分でやっと、:idに実際のidを代入します。実際のidはGETで受け取ります。

以上ここまでが、「指定したidの投稿への接続」です。


##編集画面のコード
後半部のコードは次のとおり。

```
<html>
<head>
    <meta charset="utf-8">
    <title>編集</title>

<h2>編集</h2>
    <form action="update.php" method="post">
        <input type="hidden" name="id" value="<?php if(!empty($result['id']))  echo(htmlspecialchars($result['id'], ENT_QUOTES, 'UTF-8')); ?>">
    <p>
        <label>お名前</label>
        <input type="text" name="update_name" value="<?php if(!empty($result['submit_name']))  echo(htmlspecialchars($result['submit_name'], ENT_QUOTES, 'UTF-8')); ?>">
    </p>
    <p>
        <label>発言</label>
        <input type="text" name="update_content" value="<?php if(!empty($result['submit_content']))  echo(htmlspecialchars($result['submit_content'], ENT_QUOTES, 'UTF-8')); ?>">
    </p>

        <input type="submit" value="編集する">

    </form>

        <a href="index.php">投稿一覧へ</a>
</body>
</html>
```

まずlabelタグで、項目を作ります。

その後
```<input type="text" name="update_name" value="<?php if(!empty($result['submit_name']))  echo(htmlspecialchars($result['submit_name'], ENT_QUOTES, 'UTF-8')); ?>">
```
このコード。
valueの中のコードで、変更前（すでにDBに保存されている内容）をPHPで呼び出します。
そうすると、項目の中に投稿した内容が反映されています。

実際の変更の機能は```<form action="update.php" method="post">```
ここにたくされています。
postで渡され、update.phpで実行されると。

#update.phpについて
ここまでで、投稿画面一覧から編集画面への移行を実装してきました。
ここから編集の機能を実装します。

update.phpのコードはこのようになっています。


```
<?php 

$dsn = 'mysql:dbname=test_bbs2; host=localhost';
$username= 'root';
$password= 'root';

try{

    $dbh = new PDO($dsn, $username, $password);
    echo "接続成功";
    //変数に格納
    $sql="UPDATE contacts SET submit_name = :name, submit_content = :message WHERE id = :id";
    //準備
    $stmt = $dbh->prepare($sql);

    //配列に格納
    $params = array(':name' => $_REQUEST['update_name'], ':message' => $_REQUEST['update_content'], ':id' => $_REQUEST['id']);

    $stmt->execute($params);

    echo "情報を更新しました。";
} catch(PDOException $e){
    echo "失敗:" . $e->getMessage() . "\n";
    exit();
}
?>


<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>更新完了</title>
  </head>
  <body>          
  <p>
      <a href="index.php">投稿一覧へ</a>
  </p> 
  </body>
</html>
```

この中でも、
```    $params = array(':name' => $_REQUEST['update_name'], ':message' => $_REQUEST['update_content'], ':id' => $_REQUEST['id']);
    $stmt->execute($params);
```
この部分で、編集画面のコードで、入力した内容を受けとっています。
編集の画面のコードでは、それぞれ項目の名前を

```
 <label>発言</label>
        <input type="text" name="update_content"
```

このように、```name="update_content"```としていますので、それをupdate.phpで受け取ります。

それらを最終的にDBに保存すれば、Update機能の完了となります。


#まとめ
繰り返しになりますが、以下の流れで機能を作っていきます。
１．DBに接続し、idの値で指定した入力内容をもってくる
２．入力内容を項目に反映させ、編集する画面をつくる
３．２で作った内容を受け取り、DBへ再度保存する。

以上です。