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

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

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

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

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

Q&A

解決済

4回答

1752閲覧

Invalid parameter number: number of bound variables does not match number of tokens

yuuu752

総合スコア18

MySQL

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

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

0グッド

0クリップ

投稿2020/11/14 13:14

編集2020/11/15 08:11

前提・実現したいこと

入力内容チェック後に正常にデータベースに反映させたい。

ここに質問の内容を詳しく書いてください。

[エラー箇所]
stock_edit_check.phpで入力内容チェック後、stock_edit_done.phpでDBに反映させる所でエラーが出ましたので、エラー箇所はstock_edit_done.phpのtry内と思われます。

発生している問題・エラーメッセージ

array(6) { [":purchase_date"]=> string(10) "2020-10-26" [":deadline"]=> string(10) "2020-11-26" [":stock_name"]=> string(18) "国産きゅうり" [":price"]=> int(200) [":number"]=> int(10) [":gazou"]=> string(14) "kyuri_yama.jpg" } エラー発生:SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens ただいま障害により大変ご迷惑をお掛けしております。

該当のソースコード

「stock_edit.php:修正内容を入力」

php

1<?php 2session_start(); 3session_regenerate_id(true); 4if(isset($_SESSION['login'])==false) 5{ 6 print'ログインされません。<br />'; 7 print'<a href="../user_login/login_form.html">ログイン画面へ</a>'; 8 exit(); 9} 10else 11{ 12 print $_SESSION['user_name']; 13 print'さんログイン中<br />'; 14 print'<br />'; 15} 16?> 17 18<!DOCTYPE html> 19<html> 20<head> 21<meta charset="UTF-8"> 22<link rel="stylesheet" href="css/common.css"> 23<title>在庫削除</title> 24</head> 25<body> 26 27<?php 28 29try 30{ 31 32$stock_id=$_GET['stockid']; 33 34$dsn='mysql:dbname=user;host=localhost;charset=utf8'; 35$user='yusei'; 36$password='rogin1111'; 37$dbh=new PDO($dsn,$user,$password); 38$dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 39 40$sql='SELECT purchase_date,deadline,stock_name,price,number,gazou FROM stocks WHERE stock_id=?'; 41$stmt=$dbh->prepare($sql); 42$data[]=$stock_id; 43$stmt->execute($data); 44 45$rec=$stmt->fetch(PDO::FETCH_ASSOC); 46$stock_purchase_date=$rec['purchase_date']; 47$stock_deadline=$rec['deadline']; 48$stock_name=$rec['stock_name']; 49$stock_price=$rec['price']; 50$stock_number=$rec['number']; 51$stock_gazou_name_old=$rec['gazou']; 52 53$dbh=null; 54 55if($stock_gazou_name_old=='') 56{ 57 $disp_gazou=''; 58} 59else 60{ 61 $disp_gazou='<img src="./gazou/'.$stock_gazou_name_old.'">'; 62} 63 64} 65catch(Exception $e) 66{ 67 echo "エラー発生:" . htmlspecialchars($e->getMessage(),ENT_QUOTES, 'UTF-8') . "<br>"; 68 print'ただいま障害により大変ご迷惑をお掛けしております。'; 69 exit(); 70} 71 72?> 73 74<h4>商品ID:<?php print $stock_id; ?></h4> 75<?php print $disp_gazou; ?> 76<br /> 77<form method="post" action="stock_edit_check.php" enctype="multipart/form-data"> 78<input type="hidden"name="stockid" value="<?php print $stock_id; ?>"> 79<input type="hidden" name="gazou_name_old" value="<?php print $stock_gazou_name_old; ?>"> // 既に登録されている画像を表示 80 81<label for="purchase_date">購入日:  </label> 82<input type="date" name="purchase_date" value="<?php print $stock_purchase_date ?>"><br> 83 84<label for="deadline">消費期限:</label> 85<input type="date" name="deadline" value="<?php print $stock_deadline ?>"><br> 86 87<label for="stock_name">商品名: </label> 88<input type="text" name="stock_name" style="width:200px" value="<?php print $stock_name; ?>"><br> 89 90<label for="price">値段:  </label> 91<input type="text" name="price" style="width:50px" value="<?php print $stock_price; ?>"><br> 92 93<label for="number">在庫数:  </label> 94<input type="number" name="number" value="<?php print $stock_number; ?>"><br> 95 96<label for="gazou">画像:   </label> 97<input type="file" name="gazou" style="width:400px"><br> 98<input type="button" onclick="history.back()" value="戻る"> 99<input type="submit" value="修正"> 100 101</form> 102 103</body> 104</html>

「stock_edit_check.php:入力内容をチェックする。」

php

1<?php 2session_start(); 3session_regenerate_id(true); 4if(isset($_SESSION['login'])==false) 5{ 6 print'ログインされません。<br />'; 7 print'<a href="../user_login/login_form.html">ログイン画面へ</a>'; 8 exit(); 9} 10else 11{ 12 print $_SESSION['user_name']; 13 print'さんログイン中<br />'; 14 print'<br />'; 15} 16?> 17 18<!DOCTYPE html> 19<html> 20<head> 21<meta charset="UTF-8"> 22<link rel="stylesheet" href="css/common.css"> 23<title>在庫修正</title> 24</head> 25<body> 26 27<?php 28 29require_once('../common/common.php'); 30 31$post=sanitize($_POST); 32 33if (!empty($_POST['stock_id'])) 34{ 35 $stock_id=$_POST['stock_id']; 36} 37 38if (!empty($_POST['purchase_date'])) 39{ 40 $stock_purchase_date=$_POST['purchase_date']; 41} 42 43if (!empty($_POST['deadline'])) 44{ 45 $stock_deadline=$_POST['deadline']; 46} 47 48if (!empty($_POST['stock_name'])) 49{ 50 $stock_name=$_POST['stock_name']; 51} 52 53if (!empty($_POST['price'])) 54{ 55 $stock_price=$_POST['price']; 56} 57 58if (!empty($_POST['number'])) 59{ 60 $stock_number=$_POST['number']; 61} 62 63if (!empty($_POST['gazou_name_old'])) 64{ 65 $stock_gazou_name_old=$_POST['gazou_name_old']; 66} 67 68if (!empty($_FILES['gazou'])) 69{ 70 $stock_gazou=$_FILES['gazou']; 71} 72 73if($stock_gazou['size']>0) 74{ 75 if($stock_gazou['size']>1000000) 76 { 77 print'画像が大き過ぎます。'; 78 } 79 else 80 { 81 move_uploaded_file($stock_gazou['tmp_name'],'./gazou/'.$stock_gazou['name']); 82 print'<img src="./gazou/'.$stock_gazou['name'].'">'; 83 print'<br />'; 84 } 85} 86 87if($stock_purchase_date=='') 88{ 89 print '購入日が入力されていません。<br />'; 90} 91else 92{ 93 print '購入日 :'; 94 print $stock_purchase_date; 95 print '<br />'; 96} 97 98if($stock_deadline=='') 99{ 100 print '消費期限が入力されていません。<br />'; 101} 102else 103{ 104 print '消費期限:'; 105 print $stock_deadline; 106 print '<br />'; 107} 108 109if($stock_name=='') 110{ 111 print '商品名が入力されていません。<br />'; 112} 113else 114{ 115 print '商品名 :'; 116 print $stock_name; 117 print '<br />'; 118} 119 120if(preg_match('/\A[0-9]+\z/',$stock_price)==0) 121{ 122 print '価格をきちんと入力してください。<br />'; 123} 124else 125{ 126 print '価格  :'; 127 print $stock_price; 128 print '円<br />'; 129} 130 131if($stock_number=='') 132{ 133 print '数量が入力されていません。<br />'; 134} 135else 136{ 137 print '数量  :'; 138 print $stock_number; 139 print '<br />'; 140} 141 142if($stock_name=='' || preg_match('/\A[0-9]+\z/',$stock_price)==0 || $stock_gazou['size']>1000000) 143{ 144 print '<form>'; 145 print '<input type="button" onclick="history.back()" value="戻る">'; 146 print '</form>'; 147} 148else 149{ 150 print '上記のように変更します。<br />'; 151 print '<form method="post" action="stock_edit_done.php">'; 152 if(isset($stock_id)) 153 { 154 print '<input type="hidden" name="stock_id" value="'.$stock_id.'">'; 155 } 156 if(isset($stock_purchase_date)) 157 { 158 print '<input type="hidden" name="purchase_date" value="'.$stock_purchase_date.'">'; 159 } 160 if(isset($stock_deadline)) 161 { 162 print '<input type="hidden" name="deadline" value="'.$stock_deadline.'">'; 163 } 164 if(isset($stock_name)) 165 { 166 print '<input type="hidden" name="stock_name" value="'.$stock_name.'">'; 167 } 168 if(isset($stock_price)) 169 { 170 print '<input type="hidden" name="price" value="'.$stock_price.'">'; 171 } 172 if(isset($stock_number)) 173 { 174 print '<input type="hidden" name="number" value="'.$stock_number.'">'; 175 } 176 if(isset($stock_gazou_name_old)) 177 { 178 print '<input type="hidden" name="gazou_name_old" value="'.$stock_gazou_name_old.'">'; 179 } 180 if(isset($stock_gazou['name'])) 181 { 182 print '<input type="hidden" name="gazou_name" value="'.$stock_gazou['name'].'">'; 183 } 184 print '<br />'; 185 print '<input type="button" onclick="history.back()" value="戻る">'; 186 print '<input type="submit" value="OK">'; 187 print '</form>'; 188} 189 190?> 191</body> 192</html>

「stock_edit_done.php:DBに反映」

php

1<?php 2session_start(); 3session_regenerate_id(true); 4if(isset($_SESSION['login'])==false) 5{ 6 print'ログインされません。<br />'; 7 print'<a href="../user_login/login_form.html">ログイン画面へ</a>'; 8 exit(); 9} 10else 11{ 12 print $_SESSION['user_name']; 13 print'さんログイン中<br />'; 14 print'<br />'; 15} 16?> 17 18<!DOCTYPE html> 19<html> 20<head> 21<meta charset="UTF-8"> 22<link rel="stylesheet" href="css/common.css"> 23<title>在庫修正</title> 24</head> 25<body> 26 27<?php 28 29require_once('../common/common.php'); 30 31try 32{ 33 34$post=sanitize($_POST); 35 36if (!empty($_POST['stock_id'])) 37{ 38 $stock_id=$_POST['stock_id']; 39} 40 41if (!empty($_POST['purchase_date'])) 42{ 43 $stock_purchase_date=$_POST['purchase_date']; 44} 45 46if (!empty($_POST['deadline'])) 47{ 48 $stock_deadline=$_POST['deadline']; 49} 50 51if (!empty($_POST['stock_name'])) 52{ 53 $stock_name=$_POST['stock_name']; 54} 55 56if (!empty($_POST['price'])) 57{ 58 $stock_price=$_POST['price']; 59} 60 61if (!empty($_POST['number'])) 62{ 63 $stock_number=$_POST['number']; 64} 65 66if (!empty($_POST['gazou_name_old'])) 67{ 68 $stock_gazou_name_old=$_POST['gazou_name_old']; 69} 70 71if (!empty($_POST['gazou_name'])) 72{ 73 $stock_gazou_name=$_POST['gazou_name']; 74} 75 76$dsn='mysql:dbname=user;host=localhost;charset=utf8'; 77$user='yusei'; 78$password='rogin1111'; 79$dbh=new PDO($dsn,$user,$password); 80$dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 81$dbh->beginTransaction(); 82 83$sql='UPDATE stocks SET purchase_date=:purchase_date,deadline=:deadline,stock_name=:stock_name,price=:price,number=:number,gazou=:gazou_name WHERE stock_id=:stock_id'; 84$stmt=$dbh->prepare($sql); 85$dbh->commit(); 86 87if(isset($stock_purchase_date)) 88{ 89 $data[':purchase_date']=$stock_purchase_date; 90} 91 92if(isset($stock_deadline)) 93{ 94 $data[':deadline']=$stock_deadline; 95} 96 97if(isset($stock_name)) 98{ 99 $data[':stock_name']=$stock_name; 100} 101 102if(isset($stock_price)) 103{ 104 $data[':price']=(int)$stock_price; 105} 106 107if(isset($stock_number)) 108{ 109 $data[':number']=(int)$stock_number; 110} 111 112if(isset($stock_gazou_name)) 113{ 114 $data[':gazou_name']=$stock_gazou_name; 115} 116 117if(isset($stock_id)) 118{ 119 $data[':stock_id']=(int)$stock_id; 120} 121 122var_dump($data); 123 124 125$stmt->execute($data); 126 127$dbh=null; 128 129if($stock_gazou_name_old!=$stock_gazou_name) 130{ 131 if($stock_gazou_name_old!='') 132 { 133 unlink('./gazou/'.$stock_gazou_name_old); 134 } 135} 136 137print '修正しました。<br />'; 138 139} 140catch(Exception$e) 141{ 142 $dbh->rollBack(); 143 144 echo "エラー発生:" . htmlspecialchars($e->getMessage(),ENT_QUOTES, 'UTF-8') . "<br>"; 145 print'ただいま障害により大変ご迷惑をお掛けしております。'; 146 exit(); 147} 148 149?> 150 151<form action="list.php"> 152 <input type="submit" value="戻る"> 153</form> 154 155</body> 156</html>

「テーブル内容」
イメージ説明

試したこと

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/11/14 14:13

そのエラーメッセージが、どのphpのどの行付近で発生したか、も重要な情報ですので、質問文中に補足してください。
YT0014

2020/11/15 02:17

https://teratail.com/questions/301215 での回答は、理解されているのでしょうか?現象、原因とも、同一です。 今回のコードを見る限り、悪化する方向への修正になっていますが。
yuuu752

2020/11/15 02:49

ご指摘ありがとうございます。 推定エラー箇所を追記させて頂きましたので、ご確認の程よろしくお願い致します。 また、前回の質問の回答につきましては、isset で false 判定されるとエラーが発生することと文字列の変換については理解できたのですが、修正方法が分からなかった為、間違った方向に修正してしまいました。 申し訳ございません。 こちらの回答を参考に別の方法で修正に取り組みます。
guest

回答4

0

不具合の修正は、現象の確認を行い、不具合の原因を特定してから行うべきです。
まず、現象を確認してください。

前回、te2jiさんの回答にもありましたが、$dataの内容を(コード上ではなく、処理している最中に)確認しましょう。

php

1if(isset($stock_id)) 2{ 3 $data[]=(int)$stock_id; 4} 5 6var_dump($data); // 追加、格納されている実際の値を出力 7 8$stmt->execute($data); 9

$dataの内容は、想定されているデータ、想定されている順番に、漏れなく格納されていたでしょうか?

「おそらく問題ない」などと考えずに、エラーが出ている以上は、「問題があるはずだ」、と考えて対処を行ってください。

投稿2020/11/15 03:16

YT0014

総合スコア1708

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

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

yuuu752

2020/11/15 07:18

ご指摘ありがとうございます。 テキストから拾いながらコードを書いていたので、おそらく問題ないと発言していまいました。 以後エラーが出る限りは、書いたコードを疑い、しっかり改善に取り組みます。 また、今後は処理している最中にデータの格納状況を確認して間違いを把握するようクセづけていきます。 issetでfalse判定が出た時に$dataと?の数が合わなくならないよう、m6uさんからアドバイス頂きましたので、そちらを参考に修正した後、var_dump($data); でしっかり格納されているか値の確認をしました。 修正内容と修正後のエラー内容、値の結果については質問を更新しましたので、お手数ですがご確認お願い致します。
guest

0

stock_edit_check.php の未入力チェックで下記しかみてない

php

1if($stock_name=='' || preg_match('/\A[0-9]+\z/',$stock_price)==0 || $stock_gazou['size']>1000000)

ので、他のが未入力でもそのまま通るんちゃうかなあ。
まあ、実際どんな入力した時にそうなったのかは分かりませんが…
もし、未入力を許容するんだったらSQLもそういう風にしないと。

投稿2020/11/14 14:45

takasima20

総合スコア7458

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

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

yuuu752

2020/11/15 02:50

回答ありがとうございます。 ご指摘頂いた箇所を見直してみます。
yuuu752

2020/11/15 06:45

ご指摘頂いたSQLに関しましては、m6uさんに具体的に解決方法をアドバイス頂きましたので改善してみます。
guest

0

ベストアンサー

直接の回答にはならないかもしれませんが、
気になる点を見つけたので、まず指摘いたします。

データベースに書き込むデータを、
クエリーに置いては「?」を使っているため、
配列で渡すときの順番通り「?」にデータを埋めていく形になりますが、
仮に

php

1if(isset($stock_purchase_date)) 2{ 3 $data[]=$stock_purchase_date; 4}

isset()が成り立たなかったとき$stock_purchase_dateで埋めたかった箇所に次以降のデータが繰り上がって埋められてしまうため、
狙った通りのデータ格納にならない可能性があります。
これを回避するには、名前付きプレースホルダーを使うべきです。

php

1$sql = 'UPDATE stocks SET purchase_date=:purchase_date, deadline=:deadline, stock_name=:stock_name, price=:price, number=:number, gazou=:gazou WHERE stock_id=:stock_id'; 2$stmt = $dbh->prepare($sql); 3 4if (isset($stock_purchase_date)) 5{ 6 $data[':purchase_date'] = $stock_purchase_date; 7}

それと、1回のINSERT INTO文の実行だけど、
トランザクション処理反しないのでしょうか。
PHP: PDO::beginTransaction - Manual
PHP: PDO::commit - Manual
PHP: PDO::rollBack - Manual
データの格納を行って異常がなければcommitするという習慣をつけたいものです。

投稿2020/11/14 14:30

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

yuuu752

2020/11/15 07:21

ご指摘ありがとうございます。 他の方々にもissetでfalse判定時に$dataと?の数が合わなくなることに関してご指摘頂きましたので、m6uさんからアドバイス頂いた通り修正しました。 トランザクション処理に関してましては現在調べながら修正できるよう取り組んでいます。
yuuu752

2020/11/15 07:37

ご指摘ありがとうございます。 他の方々にもissetでfalse判定時に$dataと?の数が合わなくなることに関してご指摘頂きましたので、m6uさんからアドバイス頂いた通り修正しました。 トランザクション処理も追加しましたので、もし書き方に間違いがありましたら、お手数ですがご指摘いただけますと幸いです。
yuuu752

2020/11/16 14:32

stock_edit_check.phpでポスト名に誤りがあり、修正したところ問題なくデータベースに反映されました。 色々とアドバイス頂きありがとうございました。
guest

0

なんか変数の存在チェックをしつつ $data[]に値を投入していますが
投入されなかったときにスタティックに書いた?の数と
$dataの要素数が異なりませんか?

投稿2020/11/14 14:04

yambejp

総合スコア114843

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

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

yuuu752

2020/11/15 06:44

ご指摘ありがとうございます。 m6uさんに、未入力時でも$dataと?の数を合わせる方法をアドバイス頂きましたので改善してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問