Portfolio作成 ⑦ 管理画面 - 記事編集画面 & 編集(Update)/ 削除(Delete)機能実装編

作業内容

先に完成状態の共有から

記事一覧画面(posts.php)に「編集」ボタン と 「削除」ボタン を追加

「編集」ボタンから遷移できる記事編集画面(edit-post.php)を作成

「削除」ボタンから遷移できる記事削除画面(delete-post.php)を作成

では、作業手順をお伝えします。

記事編集画面の作成

posts.php(記事一覧画面)へ「編集」ボタンを設置

edit-post.php(記事編集画面)ファイルの作成

edit-post.php(記事編集画面)ファイルへ記述

動作確認(記事一覧画面→記事編集画面)

編集(Update)機能実装

edit-post.php(記事編集画面)ファイルへ記事更新処理を追加で記述

動作確認(記事編集画面→編集→「更新」ボタンを押す→記事一覧画面へ戻される→記事一覧画面と記事編集画面で更新の反映を確認する)

削除(Delete)機能実装

posts.php(記事一覧画面)へ「削除」ボタンを設置

delete-post.php(記事削除画面)ファイルの作成

delete-post.php(記事削除画面)ファイルへ記述

動作確認(記事一覧画面→記事削除画面→「削除」ボタンを押す→「更新」ボタンを押す→記事一覧画面へ戻される→記事一覧画面で更新の反映を確認する)


管理者の記事一覧画面を作成について詳しく知りたい方は、こちらの記事を是非ご一読ください。

Portfolio作成 ⑥ 管理画面 - 記事一覧画面編

目標 管理画面での記事一覧画面の作成 この画面から記事の編集や削除へ繋がっていく予定の画面です。 記事一覧画面のファイル作成 /独自ドメイン/public_html/portfolio/a…

記事編集画面の作成

posts.php(記事一覧画面)へ「編集」ボタンを設置

posts.php(記事一覧画面)へ「編集」ボタンを設置していきます。

<?php

require_once '../config/database.php';

$stmt = $pdo->query("
    SELECT *
    FROM posts
    ORDER BY id DESC
");

$posts = $stmt->fetchAll();

?>

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>記事一覧</title>
</head>
<body>

<h1>記事一覧</h1>

<p>
    <a href="new-post.php">新規投稿</a>
</p>

<table border="1" cellpadding="10">

<tr>
    <th>ID</th>
    <th>タイトル</th>
    <th>投稿日</th>
</tr>

<?php foreach ($posts as $post): ?>

<tr>
    <td><?= $post['id'] ?></td>

    <td>
        <?= htmlspecialchars($post['title'], ENT_QUOTES, 'UTF-8') ?>
    </td>

    <td><?= $post['created_at'] ?></td>


    <td>
        <a href="edit-post.php?id=<?= $post['id'] ?>">
            編集
        </a>
    </td>

</tr>

<?php endforeach; ?>

</table>

</body>
</html>

href="edit-post.php"

編集ページへのリンクです。

id=<?= $post['id']

どの記事の編集画面か特定できないためidを受け渡し、edit-post.php 側で判別できるようにしています。

edit-post.php(記事編集画面)ファイルの作成

portfolio(個人開発環境)配下の admin(管理者画面)配下に edit-post.php(記事編集画面)ファイルの作成を行います。

portfolio/

├── index.php ← 記事一覧(フロント)
├── post.php ← 記事詳細(フロント)
├── header.php ← 共通ヘッダー
├── footer.php ← 共通フッター
├── style.css ← CSS
├── test-db.php ← DB接続テスト
├── test-posts.php ← 投稿取得テスト

├── config/
│ └── database.php ← PDO接続設定

└── admin/
  └── index.php ← 管理トップ
 ├── posts.php ← 記事一覧(管理)
  ├── new-post.php ← 記事作成
 ├── edit-post.php ← 記事編集
  └── delete-post.php ← 記事削除

edit-post.php(記事編集画面)ファイルへ記述

作成した edit-post.php(記事編集画面)へ記述していきます。

<?php

require_once '../config/database.php';

/*
|--------------------------------------------------------------------------
| ID取得
|--------------------------------------------------------------------------
*/

$id = $_GET['id'] ?? null;

if (!$id) {
    exit('記事IDが指定されていません');
}

/*
|--------------------------------------------------------------------------
| 記事取得
|--------------------------------------------------------------------------
*/

$stmt = $pdo->prepare("
    SELECT *
    FROM posts
    WHERE id = :id
");

$stmt->bindValue(':id', $id, PDO::PARAM_INT);

$stmt->execute();

$post = $stmt->fetch();

if (!$post) {
    exit('記事が見つかりません');
}

include '../header.php';

?>

<h2>記事編集</h2>

<form>

    <p>
        タイトル
    </p>

    <input
        type="text"
        name="title"
        value="<?= htmlspecialchars($post['title'], ENT_QUOTES, 'UTF-8') ?>"
        style="width:500px;"
    >

    <p>
        本文
    </p>

    <textarea
        name="content"
        rows="10"
        cols="80"
    ><?= htmlspecialchars($post['content'], ENT_QUOTES, 'UTF-8') ?></textarea>

    <br><br>

    <button type="submit">
        更新する
    </button>

</form>

<?php include '../footer.php'; ?>

$_GET['id'] ?? null

posts.php(記事一覧画面)から受け渡したidを取得しています。取得できない場合はエラーを避けるため未定義ではなく、nullを入れる形となっています。

if (!$id) {
exit('記事IDが指定されていません');

もしidがない(null)場合、注意文として「記事IDが指定されていません」を指定しています。

prepare()

SQLの準備。

SELECT *
FROM posts
WHERE id = :id

指定しているidが該当する記事情報を MySQL postsテーブル からすべて呼び出しています。

bindValue(':id', $id, PDO::PARAM_INT)

bindValue()は、値の割り当て。今回では、「$id」の値を「:id」に割り当てしています。PDO::PARAM_INTは、「割り当ての値は整数型だよー」と伝えています。

execute()

SQLの実行。

fetch()

SQLの実行結果から1件だけデータを取得。

if (!$post) {
exit('記事が見つかりません');
}

もしpostがない(null)場合、注意文として「記事が見つかりません」を指定しています。

include '../header.php'; ~ include '../footer.php';

HTMLです。画面に必要なものを置きましょう。

動作確認(記事一覧画面→記事編集画面)

https://kimimachilab.com/portfolio/admin/posts.php

まず、posts.php(記事一覧画面)に「編集」ボタンが設置されているか確認。

「編集」ボタンの設置確認完了。次にedit-post.php(記事編集画面)へのリンクが作動しているか確認。

問題なく遷移していることを確認。

画面の崩れもなく、MySQL から記事情報も取得できていることを確認。

編集(Update)機能実装

edit-post.php(記事編集画面)ファイルへ記事更新処理を追加で記述

記事の更新機能を実装するため、さらに edit-post.php(記事編集画面)へ記述していきます。

$post = $stmt->fetch();

if (!$post) {
exit('記事が見つかりません');
}

(ここの部分へ)

include '../header.php';

更新処理を記述します。

$post = $stmt->fetch();

if (!$post) {
    exit('記事が見つかりません');
}

/*
|--------------------------------------------------------------------------
| 更新処理
|--------------------------------------------------------------------------
*/

if ($_SERVER['REQUEST_METHOD'] === 'POST') {

    $title = trim($_POST['title']);
    $content = trim($_POST['content']);

    $stmt = $pdo->prepare("
        UPDATE posts
        SET
            title = :title,
            content = :content
        WHERE id = :id
    ");

    $stmt->bindValue(':title', $title);
    $stmt->bindValue(':content', $content);
    $stmt->bindValue(':id', $id, PDO::PARAM_INT);

    $stmt->execute();

    header("Location: posts.php");
    exit;
}

include '../header.php';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {}

このページ(記事編集画面)が POST メソッドで送信されたときだけ処理を実行

$title = trim($_POST['title']); $content = trim($_POST['content']);

フォームから送信された「タイトル」と「本文」を取得。 前後の空白(スペース・改行・タブなど)を削除

prepare()

SQLの準備。

UPDATE posts
SET
title = :title,
content = :content
WHERE id = :id

postsテーブル 内で指定しているidが該当する「タイトル」と「本文」へ、フォームから送信された「タイトル」と「本文」を更新

$stmt->bindValue(':title', $title);
$stmt->bindValue(':content', $content);
$stmt->bindValue(':id', $id, PDO::PARAM_INT);

bindValue()は、値の割り当て。「$○○」の値を「:○○」に割り当て。PDO::PARAM_INTは、「割り当ての値は整数型だよー」と伝えています。

execute()

SQLの実行。

header("Location: posts.php");

ブラウザを posts.php(記事一覧画面)へ自動的に移動(リダイレクト)

exit;

PHPの処理を終了する宣言

動作確認(記事編集画面→編集→「更新」ボタンを押す→記事一覧画面へ戻される→記事一覧画面と記事編集画面で更新の反映を確認する)

https://kimimachilab.com/portfolio/admin/edit-post.php?id=(編集したい記事のid)

実際に編集を行い、「更新する」ボタンを押してみます。

タイトルを

「SNSシェア動作確認用テスト記事②」

「SNSシェア動作確認用テスト記事②(編集済み)

へ変更。

「更新する」ボタンを押す。

自動で posts.php(記事一覧画面)へ遷移し

posts.php(記事一覧画面)で、タイトルの編集が反映されていることを確認。

もう一度「編集」ボタンを押して

edit-post.php(記事編集画面)でも、タイトルの編集が反映されていることを確認。

削除(Delete)機能実装

posts.php(記事一覧画面)へ「削除」ボタンを設置

posts.php(記事一覧画面)へ「削除」ボタンを設置していきます。

<td>
    <a href="edit-post.php?id=<?= $post['id'] ?>">
        編集
    </a>
</td>

<?php

require_once '../config/database.php';

$stmt = $pdo->query("
    SELECT *
    FROM posts
    ORDER BY id DESC
");

$posts = $stmt->fetchAll();

?>

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>記事一覧</title>
</head>
<body>

<h1>記事一覧</h1>

<p>
    <a href="new-post.php">新規投稿</a>
</p>

<table border="1" cellpadding="10">

<tr>
    <th>ID</th>
    <th>タイトル</th>
    <th>投稿日</th>
</tr>

<?php foreach ($posts as $post): ?>

<tr>
    <td><?= $post['id'] ?></td>

    <td>
        <?= htmlspecialchars($post['title'], ENT_QUOTES, 'UTF-8') ?>
    </td>

    <td><?= $post['created_at'] ?></td>


    <td>

     <a href="edit-post.php?id=<?= $post['id'] ?>">
         編集
     </a>

     |

     <a href="delete-post.php?id=<?= $post['id'] ?>">
         削除
     </a>

    </td>

</tr>

<?php endforeach; ?>

</table>

</body>
</html>
href="delete-post.php"

削除ページへのリンクです。

id=<?= $post['id']

どの記事の削除画面か特定できないためidを受け渡し、delete-post.php 側で判別できるようにしています。

delete-post.php(記事削除画面)ファイルの作成

portfolio(個人開発環境)配下の admin(管理者画面)配下に delete-post.php(記事削除画面)ファイルの作成を行います。

portfolio/

├── index.php ← 記事一覧(フロント)
├── post.php ← 記事詳細(フロント)
├── header.php ← 共通ヘッダー
├── footer.php ← 共通フッター
├── style.css ← CSS
├── test-db.php ← DB接続テスト
├── test-posts.php ← 投稿取得テスト

├── config/
│ └── database.php ← PDO接続設定

└── admin/
  └── index.php ← 管理トップ
 ├── posts.php ← 記事一覧(管理)
  ├── new-post.php ← 記事作成
 ├── edit-post.php ← 記事編集
  └── delete-post.php ← 記事削除

delete-post.php(記事削除画面)ファイルへ記述

作成した delete-post.php(記事削除画面)へ記述していきます。

<?php

require_once '../config/database.php';

$id = $_GET['id'] ?? null;

if (!$id) {
    exit('記事IDが指定されていません');
}

$stmt = $pdo->prepare("
    SELECT *
    FROM posts
    WHERE id = :id
");

$stmt->bindValue(':id', $id, PDO::PARAM_INT);
$stmt->execute();

$post = $stmt->fetch();

if (!$post) {
    exit('記事が見つかりません');
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {

    $stmt = $pdo->prepare("
        DELETE FROM posts
        WHERE id = :id
    ");

    $stmt->bindValue(':id', $id, PDO::PARAM_INT);

    $stmt->execute();

    header('Location: posts.php');
    exit;
}

include '../header.php';
?>

<h2>記事削除</h2>

<p>
    本当に削除しますか?
</p>

<h3>
    <?= htmlspecialchars($post['title'], ENT_QUOTES, 'UTF-8') ?>
</h3>

<form method="POST">

    <button type="submit">
        削除する
    </button>

</form>

<p>
    <a href="posts.php">
        キャンセル
    </a>
</p>

<?php include '../footer.php'; ?>

$_GET['id'] ?? null

posts.php(記事一覧画面)から受け渡したidを取得しています。取得できない場合はエラーを避けるため未定義ではなく、nullを入れる形となっています。

if (!$id) {
exit('記事IDが指定されていません');

もしidがない(null)場合、注意文として「記事IDが指定されていません」を指定しています。

prepare()

SQLの準備。

SELECT *
FROM posts
WHERE id = :id

指定しているidが該当する記事情報を MySQL postsテーブル からすべて呼び出しています。

bindValue(':id', $id, PDO::PARAM_INT)

bindValue()は、値の割り当て。今回では、「$id」の値を「:id」に割り当てしています。PDO::PARAM_INTは、「割り当ての値は整数型だよー」と伝えています。

execute()

SQLの実行。

fetch()

SQLの実行結果から1件だけデータを取得。

if (!$post) {
exit('記事が見つかりません');
}

もしpostがない(null)場合、注意文として「記事が見つかりません」を指定しています。

if ($_SERVER['REQUEST_METHOD'] === 'POST') {}

このページ(記事編集画面)が POST メソッドで送信されたときだけ処理を実行

DELETE FROM posts
WHERE id = :id

指定しているidが該当する記事情報を MySQL postsテーブル からすべて削除しています。

header("Location: posts.php");

ブラウザを posts.php(記事一覧画面)へ自動的に移動(リダイレクト)

exit;

PHPの処理を終了する宣言

include '../header.php'; ~ include '../footer.php';

HTMLです。画面に必要なものを置きましょう。

動作確認(記事一覧画面→記事削除画面→「削除」ボタンを押す→「更新」ボタンを押す→記事一覧画面へ戻される→記事一覧画面で更新の反映を確認する)

https://kimimachilab.com/portfolio/admin/posts.php

まず、posts.php(記事一覧画面)に「削除」ボタンが設置されているか確認。

「削除」ボタンの設置確認完了。次にdelete-post.php(記事削除画面)へのリンクが作動しているか確認。

問題なく遷移していることを確認。

画面の崩れもなく、MySQL から記事情報も取得できていることを確認。

「削除する」ボタンを押す。

自動で posts.php(記事一覧画面)へ遷移し

posts.php(記事一覧画面)で、記事の削除が反映されていることを確認。

まとめ

今回は

「記事編集画面」「記事削除画面」の作成
「編集(Update)機能」「削除(Delete)機能」の実装

を行いました。

前回は、記事を作成・投稿までの最低限の機能を実装しましたが、

今回は、CRUD(クラッド)処理である

Create作成新しい記事を投稿する
Read読み取り記事を表示する
Update更新記事を編集する
Delete削除記事を削除する

の実装を完了しました。

データを扱うシステムでの基本操作なので、一区切りといった印象です。

次回は、管理画面を操作できる権限の機能として「ログイン機能(Session)」の実装を予定しています。

ご興味があれば是非ご一読ください。

ここまで読んでいただき、ありがとうございました。

\ 最新情報をチェック /

コメントを残す

※ が付いている項目は必須です

CAPTCHA