質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.01%

MySQLの論理削除に関して

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,014

onslaught

score 13

教材を元にPHPを学習中なのですが、todoリストの作成にあたって削除ボタンを押すと
押した場所のtodoが削除(論理削除)される機能を作成しています。
現在の時刻をdateメソッドで取得しdeleted_atの値を更新する処理をしたいです。

'UPDATE テーブル名 SET 更新するカラム名 = 更新する値 WHERE 条件';

という理解の元下記UPDATE文を記述してみたのですが、特に押しても反応せず止まっている状態です。
そもそも構文の書き方や理解がおかしいのでしょうか?

追記PHP7.2,MySQL5.7

**index.php**

<?php 
    require_once('functions.php');
?>

<!DOCTYPE html> 
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Home</title>
</head>
<body>
  welcome hello world
  <div>
     <a href="new.php">
       <p>新規作成</p>
     </a>
  </div>
  <div> 
    <table>
      <tr>
        <th>ID</th>
        <th>内容</th>
        <th>更新</th>
        <th>削除</th>
      </tr>
      <?php foreach (getTodoList() as $todo) : ?>
        <tr>
          <td><?= $todo['id']; ?></td>
          <td><?= $todo['todo']; ?></td>
          <td>
            <a href="edit.php?id=<?= $todo['id']; ?>">更新</a>
          </td>
          <td>
            <form action="store.php" method="post">
              <input type="hidden" name="id" value="<?= $todo['id']; ?>">
              <button type="submit">削除</button>
            </form>
          </td>
        </tr>
      <?php endforeach; ?>
    </table>
  </div>
</body>
</html>
**connection.php**

<?php
require_once('config.php');


function connectPdo() //正規処理と例外処理の関数
{
    try {  
        return new PDO(DSN, DB_USER, DB_PASSWORD);
    } catch (PDOException $e) {
        echo $e -> getMessage(); 
        exit();
    }
}

function createTodoData($todoText) 
{
    $dbh  = connectPdo(); 
    $sql  = 'INSERT INTO todos (todo) VALUES (:todoText)'; 
    $stmt = $dbh->prepare($sql); 
    $stmt->bindValue(':todoText', $todoText, PDO::PARAM_STR); 
    $stmt->execute();
}

function getAllRecords()
{
    $dbh = connectPdo();
    $sql = 'SELECT * FROM todos WHERE deleted_at IS NULL';
    return $dbh->query($sql)->fetchAll();
}

function updateTodoData($post)
{
    $dbh  = connectPdo();
    $sql  = 'UPDATE todos SET todo = :todoText WHERE id = :id';
    $stmt = $dbh->prepare($sql);
    $stmt->bindValue(':todoText', $post['todo'], PDO::PARAM_STR);
    $stmt->bindValue(':id', (int)$post['id'], PDO::PARAM_INT);
    $stmt->execute();
}

function getTodoTextById($id)
{
    $dbh = connectPdo();
    $sql = 'SELECT todo FROM todos WHERE deleted_at IS NULL';
    return $data['todo'];
}

function deleteTodoData($id)
{
    $dbh = connectPdo();
    $now = date('Y-m-d H:i:s');
    $sql = 'UPDATE todos SET deleted_at = $now WHERE deleted_at = NULL'; ←この部分の処理が何も行われない。
}

?>
**config.php**

<?php

define('DSN', 'mysql:dbname=php_lesson;host=localhost;unix_socket=/tmp/mysql.sock');
define('DB_USER', 'root');
define('DB_PASSWORD', '');

?>

データベース
データベース

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2019/04/18 15:40

    教材とは何でしょうか?差し支えなければ出典記載してください。またphp、mysqlのバージョンを質問本文に記載してください

    キャンセル

  • yoorwm

    2019/04/18 15:47

    deleted_at IS NULLと、正しく使ってるのに、問題の箇所でdeleted_at = NULLとしているのはなぜでしょうか?
    (他にも色々突っ込みどころがありますが。)

    キャンセル

  • m6u

    2019/04/18 15:50

    deleteTodoData でクエリー実行してない

    キャンセル

  • onslaught

    2019/04/18 15:51

    私が記述した部分以外は教材のコピペになります。
    なので私自身はまだDB操作やPHPの書き方などがあまりわかっていない状態です。

    キャンセル

回答 2

+2

deleteTodoDataはSQL文を宣言していますが、実行していません。
updateTodoDataと同様に、プレースホルダ(:honyarara)を用いてSQL文を宣言した後、パラメータの設定、SQLの実行まで行ってください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/04/18 16:09

    ありがとうございます。

    キャンセル

checkベストアンサー

+1

SQL側の日付関数で処理するほうがよいでしょう

$sql = 'UPDATE todos SET deleted_at = now() WHERE id=?'
$stmt = $dbh->prepare($sql);
$stmt->execute([$id]);


どうしてもPHPから渡したいならそこもprepareで

$sql = 'UPDATE todos SET deleted_at = ? WHERE id=?'
$stmt = $dbh->prepare($sql);
$stmt->execute([$now,$id]);

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/04/19 08:59

    ありがとうございます。
    $dbh = connectPdo();
    $now = date('Y-m-d H:i:s');
    $sql = 'UPDATE todos SET deleted_at = :now WHERE id = :id';
    $stmt = $dbh->prepare($sql);
    $stmt->bindvalue(':now', $post['deleted_at'], PDO::PARAM_STR);
    $stmt->bindvalue(':id', (int)$post['id'], PDO::PARAM_INT);
    $stmt->execute();
    このような記述だと実行できないのですが、取得した現在時刻($now)が使われてないということでしょうか?

    キャンセル

  • 2019/04/19 10:02

    $stmt->bindvalue(':now', @now, PDO::PARAM_STR);
    $stmt->bindvalue(':id', $id, PDO::PARAM_INT);

    じゃないのですか?

    キャンセル

  • 2019/04/19 12:43

    解決しました。
    度々ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.01%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る