ユーザーの入力間違えによる、エラーの出力方法について
現在、PHPの勉強としまして、簡易な掲示板のサイトを作成しているのですが、ユーザーが投稿されたコメント欄の削除パスワードを間違えて入力してしまった際に、どのように画面に表示させるか、といった部分でうまくいかず、お力をお貸し頂きたく、ご質問させて頂きました。
削除パスワードが入力され、データベースに接続し、格納されているコメントの削除処理を記載したコードは、以下の「delete1.php」になります。
<?php
include 'bbs_class1.php';
error_reporting(E_ALL);
ini_set('display_errors', '1');
$errs = [];
$bbs = new Bbs('mysql:host=localhost;dbname=online_bbs;charset=utf8', 'root', '12345', 10);
if(!empty($_POST)){
$password = filter_input(INPUT_POST,'password');
$id = intval(filter_input(INPUT_POST,'id'));
if(!$password){
$errs[] = 'パスワードを入力してください';
}elseif(!preg_match('/\A[a-z\d]{8,100}+\z/i',$password)){
$errs[] = 'パスワードは半角英数8文字以上で入力してください';
}
if(!$id){
$errs[] = 'idが送信されていません';
}
if(empty($errs)){
try{
$bbs->delete($id,$password);
}catch(PDOException $e){
echo $e->getMessage();
}
header('Location:bbs1.php');
exit();
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>
<body>
<p>
<?php if(!empty($errs)): ?>
<?php echo implode('<br />',$errs); ?>
<a href="bbs1.php">戻る</a>
<?php endif;?>
</body>
</html>
データベースの接続処理などをまとめたクラスである、「bbs_class1.php」の削除処理、及びデータベース接続処理をまとめたメソッドが以下のコードとなります。
public function delete($id,$password){
$stmt = $this->dbh->prepare("SELECT password FROM post_3 WHERE id = :id");
$stmt->bindValue(':id',$id,PDO::PARAM_INT);
$stmt->execute();
$db_password = $stmt->fetchColumn();
//var_dump($db_password);
if(!password_verify($password,$db_password)){
throw new Exception('パスワードが違います');
}
$stmt = $this->dbh->prepare("DELETE FROM post_3 WHERE id = :id");
$stmt->bindValue(':id',$id,PDO::PARAM_INT);
$stmt->execute();
}
実は、「delete1.php」の
if(empty($errs)){
try{
$bbs->delete($id,$password);
}catch(PDOException $e){
echo $e->getMessage();
}
header('Location:bbs1.php');
exit();
}
こちらの部分におきまして、エラーメッセージを出力させようと思ったのですが、fatalエラーが発生してしまい、エラーメッセージのみを出力させることができません。
また、try,catch文内のcatchにて、deleteメソッドの「throw new Exception('パスワードが違います');」ここの部分で例外をスローしたものをメッセージとして出力する処理にした場合、仮に、データベースに接続できないなどの、エラーが発生した場合は、スローした例外と、データベースエラーのどちらのメッセージがdelete1.phpのcatch(PDOException $e){echo $e->getMessage();}
のメッセージとして出力されるのかなども疑問です...
どなたか、ご教示いただける方いらっしゃいましたら、ご助言頂けましたら幸いです。
※以下は頂きましたご回答を踏まえ、修正&追記しましたコードになります。
まず、新たにパスワード認証用の例外クラスを作成致しました。
以下は、「exception.php」になります。
<?php
class PasswordException extends Exception{
public function __construct($message){
parent::__construct($message);
}
}
以下はbbs_class1.phpのdeleteメソッドを修正したものになります。
public function delete($id,$password){
$stmt = $this->dbh->prepare("SELECT password FROM post_3 WHERE id = :id");
$stmt->bindValue(':id',$id,PDO::PARAM_INT);
$stmt->execute();
$db_password = $stmt->fetchColumn();
//var_dump($db_password);
if(!password_verify($password,$db_password)){
throw new PasswordException('パスワードが違います');
}
$stmt = $this->dbh->prepare("DELETE FROM post_3 WHERE id = :id");
$stmt->bindValue(':id',$id,PDO::PARAM_INT);
$stmt->execute();
}
以下は、delete1.phpのdeleteメソッド呼び出し部分を修正したコードになります。
if(empty($errs)){
try{
$bbs->delete($id,$password);
}catch(PDOException $e){
echo $e->getMessage();
}catch(PasswordException $e){
echo $e->getMessage();
exit();
}
header('Location:bbs1.php');
exit();
}