jackytom
@jackytom

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

PHPでSQLSTATE[HY093]エラー

Q&A

Closed

PHPでmariadbにinsertとupdateをするソースを書いているのですが、下記のエラーになります。

Fatal error: Uncaught PDOException: SQLSTATE[HY093]: Invalid parameter number in C:\xampp\htdocs\Portfolio\reserve_commit.php:61 Stack trace: #0 C:\xampp\htdocs\Portfolio\reserve_commit.php(61): PDOStatement->bindValue('customer_id', 1) #1 {main} thrown in C:\xampp\htdocs\Portfolio\reserve_commit.php on line 61

61行目のcustomer_idで引っ掛かっているように思えます。
https://qiita.com/sefp-maru/items/b8850c752def93106e34
を確認して調査したのですが、該当箇所は見つかりませんでした。

DBのログを確認しましたが、下記のようになってます。

 93 Prepare	call reservation
							('customer_id',
							'reserve_date',
							'time_zone_id',
							'service_id',
							'option_id',
							'total_amount',
							'reserve_flg'
						)
		    93 Close stmt	
		    93 Quit	

2本のSQLを「reservation」というプロシージャーで実行しようとしてるのですが、その「reservation」をcallしようとして止まっているように思えます。

原因究明にご協力いただければ幸いです。
ソースと、プロシージャー作成のSQLを添付します。

PHPのソース

<?php
	session_start();
		if(!isset($_SESSION['token']) || !isset($_POST['token']) || $_SESSION['token'] !== $_POST['token']){
		die('不正なリクエストです。処理を中断します。');
	}

	function escape($val)
	{
		return htmlspecialchars($val, ENT_QUOTES | ENT_HTML5, 'UTF-8');
	}
	require_once('db_connect.php');
	require_once('password_db.php');

	var_dump($_POST['service_id']);
?>
<!doctype html>
<html lang=ja>
	<head>
		<meta charset="utf-8">
		<title>予約登録</title>
		<meta name="description" content="ヘッドセラピーを中心としたセラピーのサービスを提供しております。">
		<!--リセットcss-->
		<link rel="stylesheet" href="https://unpkg.com/ress/dist/ress.min.css">
		<!--css-->
		<link href="css/contact_style.css" rel="stylesheet">
		<!--レスポンシブ対応-->
		<meta name="viwport" content="width=device-width, initial-scale=1">
		<!--Googleフォント-->
		<link href="https://fonts.googleapis.com/css2?family=Sawarabi+Gothic&display=swap" rel="stylesheet">
		<link href="https://fonts.googleapis.com/css2?family=Shippori+Mincho:wght@500&display=swap" rel="stylesheet">
	</head>
	<body>
		<?php require_once('header.php');?>
		<main>
			<h1>
				会員情報登録
			</h1>
		<?php
			if($_SERVER['REQUEST_METHOD'] === 'POST'){
				if(empty(escape($_POST['sei'])) || empty(escape($_POST['mei'])) || empty(escape($_POST['reserve_date']))){
					echo '未入力の項目があります。';
				}
				else if(escape($_POST['time_zone']) === "1" || escape($_POST['service_id']) === "1" || escape($_POST['item']) === 1 ){
					echo '選択してください。';
				}
				else if(escape($_POST['total_amount']) === "0" ){
					echo 'サービスを選択してください。';
				}
				else if(escape($_POST['service_id']) === "2" || escape($_POST['service_id']) === "3" ){
						$sql = 
						("call reservation
							('customer_id',
							'reserve_date',
							'time_zone_id',
							'service_id',
							'option_id',
							'total_amount',
							'reserve_flg'
						)");
						$stmt = $pdo->prepare($sql);
						$stmt -> bindValue('customer_id', $_SESSION['customer']['customer_id']);
						$stmt -> bindValue('reserve_date', escape($_POST['reserve_date']));
						$stmt -> bindValue('time_zone_id', escape($_POST['time_zone_id']));
						$stmt -> bindValue('service_id', escape($_POST['service_id']));
						$stmt -> bindValue('option_id', escape($_POST['potion_id']));
						$stmt -> bindValue('total_amount', escape($_POST['total_amount']));
						$stmt -> bindValue('reserve_flg', 1);
						$stmt -> bindValue('reserve_date', escape($_POST['reserve_date']));
						$stmt -> bindValue('time_zone_id', escape($_POST['time_zone_id']));
						$stmt -> execute();
						require_once('reserve_self_mail.php');
						require_once('reserve_staff_mail.php');
						header('Location: reserve_end.php', true, 303);
						exit();
						}
				else {
					echo '登録に失敗しました。';
					}
				}
		?>
		<?php require_once('footer.php');?>
	</body>
</html>

プロシージャー作成したSQL

delimiter //
create procedure reservation(in customer_id int(10),in reserve_date date,in time_zone_id int(10),in service_id int(10),in option_id int(10),in total_amount int(10),in reserve_flg int(10))
begin
insert into reservation(customer_id,reserve_date,time_zone_id,service_id,option_id,total_amount) values(customer_id,reserve_date,time_zone_id,service_id,option_id,total_amount);
update r_calender set reserve_flg = reserve_flg where calender_date = reserve_date and ampm_flg = time_zone_id;
end
//
0

1Answer

						$sql = 
						("call reservation
							('customer_id',
							'reserve_date',
							'time_zone_id',
							'service_id',
							'option_id',
							'total_amount',
							'reserve_flg'
						)");

この SQL でプロシージャの引数が文字列リテラルになっているのが原因です。プレースホルダにしてください。

また以下の bindValue が2回ずつ現れているので重複を消してください。

						$stmt -> bindValue('reserve_date', escape($_POST['reserve_date']));
						$stmt -> bindValue('time_zone_id', escape($_POST['time_zone_id']));
1Like

Comments

  1. @jackytom

    Questioner

    回答ありがとうございます。
    ご指摘の部分を修正して解決しました。
    大変助かりました。
    本件、クローズさせていただきます。

Your answer might help someone💌