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

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

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Q&A

解決済

4回答

498閲覧

データベースの値が削除できません

newyee

総合スコア213

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

0グッド

0クリップ

投稿2019/03/04 07:33

編集2019/03/04 07:34

PHPの学習としまして簡易な掲示板を作成したのですが、うまくいかない部分がありご助言頂きたいです。
以下は、ユーザのコメント入力画面である、「bbs.php」です。

php

1<?php 2include 'includes/login.php'; 3 error_reporting(E_ALL); 4 ini_set("display_errors",1); 5 //1ページに表示されるコメントの数 6 $num = 10; 7 $user = 'root'; 8 $password = ''; 9 $dsn = 'mysql:host=localhost;dbname=online_bbs;charset=utf8'; 10 //ページ数が指定されている時 11 $page = 0; 12 if(isset($_GET['page']) && $_GET['page'] > 0){ 13 $page = intval($_GET['page']) -1; 14 15 } 16 17 try{ 18 $dbh = new PDO($dsn,$user,$password); 19 $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 20 $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); 21 22 $stmt = $dbh->prepare("SELECT * FROM post ORDER BY created_at DESC LIMIT 23 :page,:num"); 24 //パラメーターを割り当て 25 $page = $page * $num; 26 27 $stmt->bindValue(':page',$page,PDO::PARAM_INT); 28 $stmt->bindValue(':num',$num,PDO::PARAM_INT); 29 $stmt->execute(); 30 31 }catch(PDOException $e){ 32 echo "エラー: " . $e->getMessage(); 33 } 34 35 36 37?> 38 39 <html> 40 <head> 41 <title>交流サイト:掲示板</title> 42 <meta charset="utf-8"> 43 </head> 44 <body> 45 <h1>掲示板</h1> 46 <form action="write.php" method="post"> 47 <p>名前:<input type="text" name="name" value="<?php echo isset($_COOKIE['name']) ? $_COOKIE['name'] : '' ?>"></p> 48 <p>タイトル:<input type="text" name="title" size="60"></p> 49 <textarea name="comment"></textarea> 50 <p>削除パスワード(数字4桁):<input type="text" name="pass"> 51 <input type="submit" name="submit" value="書き込む"> 52 <input type="hidden" name="token" value="<?php echo password_hash(session_id(),PASSWORD_DEFAULT); ?>"> 53 </form> 54 <hr> 55 <?php 56 while($row = $stmt->fetch()): 57 $title = $row['title'] ? $row['title'] : '(無題)'; 58 ?> 59 <p>名前:<?php echo $row['name'] ?></p> 60 <p>タイトル:<?php echo $title ?></p> 61 <p><?php echo nl2br(htmlspecialchars($row['comment'],ENT_QUOTES,'UTF-8'),false) ?></p> 62 <p><?php echo $row['created_at'] ?></p> 63 <form action="delete.php" method="post"> 64 <input type="hidden" name="id" value="<?php echo $row['id']; ?>"> 65 削除パスワード:<input type="password" name="pass"> 66 <input type="submit" value="削除"> 67 <input type="hidden" name="token" value="<?php echo password_hash(session_id(),PASSWORD_DEFAULT); ?>"> 68 </form> 69 <?php 70 endwhile; 71 //ページ数の表示 72 try{ 73 $stmt = $dbh->prepare("SELECT COUNT(*) FROM post"); 74 $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); 75 $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 76 77 //クエリの実行 78 $stmt->execute(); 79 80 }catch(PDOException $e){ 81 echo "エラー:" . $e->getMessage(); 82 } 83 /** 84 * コメントの件数を取得 85 *fetchColumn関数で 最初のレコードを取り出し、最初の列「id」のデータを取り出す 86 * idは降順に設定されているため、コメントの件数が分かる 87 * */ 88 $comments = $stmt->fetchColumn(); 89 $max_page = ceil($comments / $num); 90 echo '<p>'; 91 for($i = 1; $i <= $max_page; $i++){ 92 echo '<a href="bbs.php?page=' . $i .'">' . $i . 93 '</a>&nbsp;'; 94 } 95 echo '</p>'; 96 ?> 97 98 </body> 99 </html>

上記を実行した際の画像が以下になります。
イメージ説明
以下の画像は、削除パスワードを入力し、削除ボタンを押したら、データベースよりコメント情報(名前、タイトル、日付)を削除する処理となる、「delete.php」です

php

1<?php 2include 'includes/login.php'; 3 error_reporting(E_ALL); 4 ini_set("display_errors",1); 5 $id = intval($_POST['id']); 6 $pass = $_POST['pass']; 7 $token = $_POST['token']; 8 //var_dump($id); 9 $err_msg = []; 10 11 if($pass == ''){ 12 13 $err_msg[] = 'パスワードが入力されていません'; 14 15 } 16 17 //CRLF対策 18 if(!password_verify(session_id(),$token)){ 19 header('Location:bbs.php'); 20 exit(); 21 }; 22 23 if(count($err_msg) === 0){ 24 25 26 $dsn = 'mysql:host=localhost;dbname=online_bbs;charset=utf8'; 27 $user = 'root'; 28 $password = ''; 29 30 try{ 31 $dbh = new PDO($dsn,$user,$password); 32 $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); 33 $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 34 $stmt = $dbh->prepare(" 35 SELECT password FROM post where id = :id 36 "); 37 $stmt->bindValue(':id',$id,PDO::PARAM_INT); 38 39 $stmt->execute(); 40 41 $db_pass = $stmt->fetch(); 42 43 if(!password_verify($pass,$db_pass['password'])){ 44 45 die('パスワードが違います'); 46 47 } 48 49 }catch(PDOException $e){ 50 51 die('エラー:'. $e->getMessage()); 52 } 53 54 try{ 55 $dbh = new PDO($dsn,$user,$password); 56 $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); 57 $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 58 $stmt = $dbh->prepare( 59 "DELETE FROM post WHERE id = :id AND password = :pass" 60 ); 61 62 $stmt->bindValue(':id',$id,PDO::PARAM_INT); 63 $stmt->bindvalue(':pass',$pass,PDO::PARAM_STR); 64 $stmt->execute(); 65 66 }catch(PDOExeption $e){ 67 68 die( "エラー:" . $e->getMessage()); 69 } 70 71 header('Location: bbs.php'); 72 exit(); 73 74 } 75 76?>

以下は、コメント情報を格納しているテーブルである、「post」テーブルになります。
イメージ説明

お聞きしたい部分なのですが、削除パスワードを正しく入力しているにも関わらず、「delete.php」にて削除処理がなされず、「bbs.php」に投稿されたコメントが残り続けています。
原因が分からない為、ご助言頂けましたら幸いです。よろしくお願いします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2019/03/04 07:47

if(!password_verify(session_id(),$token)){ ↑に入った際に単にリダイレクトさせているだけなのでそこで引っかかったと知る術がありませんよ。
newyee

2019/03/04 08:02

実は、あれから、削除パスワードをデータベースに入力する際、password_hashで暗号化し、delete.phpにて、データベースに入っているパスワードとの照合を行う処理を追記してみたのですが、そしたら、何故か削除できなくなってしまったんですよね...
m.ts10806

2019/03/04 08:09

整合性がきちんと取れているかどうか確認する必要がありますよ。 暗号化するということは入力文字数よりも増えることになるので。
newyee

2019/03/04 08:10

すみません。ご回答頂いた点も踏まえてもう一度確認してみます。
guest

回答4

0

ベストアンサー

if(!password_verify($pass,$db_pass['password'])){

としてある以上カラムpasswordにはハッシュ値が入っている
$stmt->bindvalue(':pass',$pass,PDO::PARAM_STR);
この時passwordカラムと比較するデータは生のパスワード
例えば$2y$10$b0050/lEAPEv5fzI68bare2unjkoGKFzgQq3.FXZHYyYXZepAEMk
などのデータが入っています。
DELETE FROM post WHERE id= 1 AND password = "password"
となり実際に入っているだろうと思われるハッシュ値とは一致しません。
またこのハッシュ値と完全に一致させることはほぼ無理です。
同じpasswordというハッシュ値を作成しても作成するたびに違う文字列になります。

なのでこの削除処理だとpassword_verifyでpasswordが一致したら次のDELETEでIDだけ指定して削除するのがいいと思います。

投稿2019/03/04 08:17

date

総合スコア1820

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

newyee

2019/03/04 08:24

ご回答ありがとうございます。 今色々見直していたのですが、何故、削除できないかの理由がご回答いただきましたおかげで分かりました... コードの方、修正して削除されるか検証してみたいと思います...
guest

0

PDOExeption ではなくPDOException
一箇所スペルミスがあります。
手打ちではなくマニュアルからコピペが原則です。
というか手打ちであってもIDEを利用すれば自動でチェックしてくれますし
イメージ説明

予測で候補も出してくれます
イメージ説明

※いずれもEclipseの例

このあたりでのケアレスミスがなくなればコーディングに集中できるので、
導入しない理由はないです。


おかしいですね。
前の質問に登録処理のコードも貼ってもらいましたが
password_verify()はあくまでトークンのチェックに行われているだけでパスワードに対しては行ってませんよね?
登録処理は修正して、修正後にデータを新しく登録しなおして、
その新しいデータに対して対応を行いましたか?
もし登録処理を修正していないのでしたら修正する必要がありますし、
修正前に登録したデータを削除しようとしているのであれば、
暗号化行われていないpasswordなので合致しないのは当たり前です。

あと、暗号化すると入力した文字数より長くなります。

php

1echo password_hash("test", PASSWORD_DEFAULT); 2//$2y$10$/IFPho40PbQ5H84qsSQVzO0fXJL5cNdUf9WvQPiB0r825aBcIMoLe

暗号化方式もあわせて文字数が入るじゅうぶんな桁数がパスワードカラムに設定されている必要があります。
元々暗号化されてなかったのでしたら、それなりの文字数しか設定してなかったのでは?

そのあたり全て整合性を確認してください。


蛇足:
同じコードの中で何度も接続処理を書くのは無駄ですし、
Exceptionを拾ったら処理終了なのであれば全部囲うべきですね。

php

1try{ 2 $dbh = new PDO($dsn,$user,$password); 3 $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); 4 $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 5 $stmt = $dbh->prepare(" 6 SELECT password FROM post where id = :id 7 "); 8 $stmt->bindValue(':id',$id,PDO::PARAM_INT); 9 10 $stmt->execute(); 11 12 $db_pass = $stmt->fetch(); 13 14 if(!password_verify($pass,$db_pass['password'])){ 15 16 die('パスワードが違います'); 17 18 } 19 20 $stmt = $dbh->prepare( 21 "DELETE FROM post WHERE id = :id AND password = :pass" 22 ); 23 24 $stmt->bindValue(':id',$id,PDO::PARAM_INT); 25 $stmt->bindvalue(':pass',$pass,PDO::PARAM_STR); 26 $stmt->execute(); 27 28}catch(PDOException $e){ 29 30 die( "エラー:" . $e->getMessage()); 31} 32

投稿2019/03/04 08:06

編集2019/03/04 08:12
m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

newyee

2019/03/04 08:38

ご丁寧にありがとうございます。 >Exceptionを拾ったら処理終了なのであれば全部囲うべきですね dateさんのご回答を元に、mtsさんにご提示頂きましたようにtry,catch文を一つにまとめましたら、かなりコードもスッキリとなりエラーも解決しました。 僕のコードはいかに、無駄が多かったのかを実感致しました...
newyee

2019/03/04 08:40

ご回答に記載いただきましたIDEなのですが、良いですね...今使っています、エディッタが結構気に入っているので、拡張機能でどうにかならないか、一度調べてみてから、検討してみたいと思います。
m.ts10806

2019/03/04 09:06

Atomでしたっけ? 使ったことないですが構文チェックくらいならプラグインでなんとかなりそうに思います。
newyee

2019/03/04 20:39

いえ、vscodeですね。プラグイン調べてみたいと思います。
newyee

2019/03/05 02:53

ご親切にありがとうございます。 拡張機能導入できました。
guest

0

パスワードカラムの文字列の長さは十分とっていますか?
自動で切り詰められた場合イコールではヒットしません

投稿2019/03/04 07:56

yambejp

総合スコア114769

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

newyee

2019/03/04 08:08

ご回答ありがとうございます。 passwordには、当初は4文字のみしか格納できないよう、「char(4)」としていたのですが、それではpassword_verifyで照合できないと知り、「varchar(255)」に変更したんですよね... 入力された削除パスワードをpassword_hashで暗号化する前は、削除できていたのですが、暗号化し、delete.phpにて、入力されたパスワードと照合を行う処理を追記したら、何故か削除できなくなってしまいました...
guest

0

commit していますか?

投稿2019/03/04 07:44

Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2019/03/04 07:49

MySQLはオートコミットで、そもそもトランザクション張ってdeleteしてるわけではないのであまり関係なさそうです。
Orlofsky

2019/03/04 07:59

オートコミットでしたか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問