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

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

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

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

PHP

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

Q&A

解決済

3回答

3832閲覧

PHP SQLを更新したい

n_k23

総合スコア21

SQL

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

PHP

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

0グッド

0クリップ

投稿2021/12/13 07:05

編集2021/12/13 07:39

前提・解決したいこと

PHPの更新フォームからのデータをSQLに反映させる際にうまくデータ更新がされない。
色々と手を尽くしてみたがうまく更新されないため相談させてください。
sqlは/tech.pjin.jp/blog/2017/06/08/sqlのworldcupを使用。
文字制限のため所々省略しています。

データの流れとしては
1、編集更新画面(edit.php)にて変更箇所を記述し送信
2、controllerのバリデーション関数にてチェックし問題なければデータをupdate.phpへ送る
3、update.phpでデータを受け取るとModelのSQL更新用関数にデータを送る

試したこと

他の記事にて参考になるもの(チェックリスト)があったので確認してみた。

  1. stmt->executeはtrueかfalseを返します。trueが返ってきていますか?

A. falseが返っきている。
2. executeした直後にecho $stmt->rowCount();で作用した行数を取ってみてください。
0だったらWHERE句に指定したidがおかしいかも。
A. 0だったのでWHERE句に指定したidがおかしいことが判明。
3. ということで$_POST['id']もチェックしてみてください。値が入ってる?
4. 入ってなかったらなんで入っていないか考えましょう。actionのurlに埋めてる?それって$_POSTで取れるの?
A. 3・4を検証していたがうまくいかず困っている。

$post['id']を出力してみるとデータがしっかりと入っているのみ更新されないので困惑しています。

php

1// MVC View index.php 2<?php 3require_once(ROOT_PATH .'Controllers/PlayerController.php'); 4$player = new PlayerController(); 5$params = $player->index(); 6 7?> 8<!DOCTYPE html> 9<html lang="en"> 10<body> 11 <h2>選手一覧</h2> 12 <table> 13 <?php foreach($params['players'] as $player): ?> 14 <tr> 15 <td><?=$player['id'] ?></td> 16 <td><?=$player['uniform_num'] ?></td> 17 // 省略 18 <td><a href="view.php?id=<?php echo $player['id'] ?>">詳細</a></td> 19 <td><a href="edit.php?id=<?php echo $player['id'] ?>">編集</a></td> 20 <td><a class="delete" href="delete.php?id=<?php echo $player['id'] ?>">削除</a></td> 21 </tr> 22 <?php endforeach; ?> 23 </table> 24</body> 25</html>

php

1//MVC View edit.php 2<?php 3require_once(ROOT_PATH .'Controllers/PlayerController.php'); 4$request = new PlayerController(); 5$params = $request->edit(); 6 7//編集送信画面 8 9$id = $params['player']['id']; 10$country_id = (int)$params['player']['country_id']; 11$uniform_num = $params['player']['uniform_num']; 12$position = $params['player']['position']; 13$name = $params['player']['name']; 14$country = $params['player']['c_name']; 15$club = $params['player']['club']; 16$birth = $params['player']['birth']; 17$height = $params['player']['height']; 18$weight = $params['player']['weight']; 19 20 21 22?> 23 24<!DOCTYPE html> 25<html lang="en"> 26<body> 27 <?php 28 error_reporting(E_ALL & ~E_NOTICE); 29 session_start(); 30 //送信ボタンクリック後 31 if( $_SERVER['REQUEST_METHOD'] === 'POST') { 32 $post = filter_input_array(INPUT_POST, $_POST); 33 echo "<pre>"; 34 echo var_dump($post); //array(9) {["id"]=>string(1) "1" 35 echo "</pre>"; 36 echo "<pre>"; 37 echo var_dump($_POST['id']);// string(1) "1" 38 echo "</pre>"; 39 exit(); 40 //バリデーション 41 list($post,$error) = $request->validate($post); 42 if (count($error) === 0) { 43 $_SESSION['form'] = $post; 44 header('Location: update.php'); 45 exit(); 46 }else { 47 if (isset($_SESSION['form'])){ 48 $post = $_SESSION['form']; 49 } 50 } 51 } 52 ?> 53 <div class="contact_box"> 54 <h2>選手情報編集画面</h2> 55 <form action="" method="POST" id="form"> 56 <input type="hidden" name="id" value="<?php echo $id?>"> 57 <p>ユニフォーム番号:</p> 58 <?php if ($error['uniform_num'] === 'error'):?> 59 <p class="error">ユニフォーム番号は半角数字で入力してください。</p> 60 <?php endif; ?> 61 <input type="text" name="uniform_num" id="uniform_num" value="<?php echo $uniform_num?>"> 62 <p>ポジション:</p> 63 <select name="position" id="position"> 64 <option value="MF" <?php if($position === 'MF')echo "selected"?>>MF</option> 65 <option value="GK" <?php if($position === 'GK')echo "selected"?>>GK</option> 66 <option value="DF" <?php if($position === 'DF')echo "selected"?>>DF</option> 67 <option value="FW" <?php if($position === 'FW')echo "selected"?>>FW</option> 68 </select> 69 <p>名前:</p> 70 <?php if ($error['name'] === 'error'):?> 71 <p class="error">名前を入力してください。</p> 72 <?php endif; ?> 73 <input type="text" name="name" id="name" value="<?php echo $name?>"> 74 <p>国:</p> 75 <select name="country_id" id=""> 76 <option value="1" <?php if($country_id === 1) echo "selected"?>>ブラジル</option> 77 <option value="2" <?php if($country_id === 2) echo "selected"?>>メキシコ</option> 78 // 省略 79 <option value="31" <?php if($country_id === 31) echo "selected"?>>ロシア</option> 80 <option value="32" <?php if($country_id === 32) echo "selected"?>>韓国</option> 81 </select> 82 <p>所属クラブ:</p> 83 <?php if ($error['club'] === 'error'):?> 84 <p class="error">所属クラブを入力してください。</p> 85 <?php endif; ?> 86 <input type="text" name="club" id="club" value="<?php echo $club?>"> 87 <p>誕生日:</p> 88 <?php if ($error['birth'] === 'error'):?> 89 <p class="error">存在する誕生日を入力してください。例,1980-01-01(半角数字)</p> 90 <?php endif; ?> 91 <input type="text" name="birth" id="birth" value="<?php echo $birth?>"> 92 <p>身長:</p> 93 <?php if ($error['height'] === 'error'):?> 94 <p class="error">身長は半角数字で入力してください</p> 95 <?php endif; ?> 96 <input type="text" name="height" id="height" value="<?php echo $height?>"> 97 <p>体重:</p> 98 <?php if ($error['weight'] === 'error'):?> 99 <p class="error">体重は半角数字で入力してください</p> 100 <?php endif; ?> 101 <input type="text" name="weight" id="weight" value="<?php echo $weight?>"> 102 <br> 103 <div class="confirm_btn"> 104 <button class="update" type="submit" >更 新</button> 105 <a href="./index.php" class="back" type="button">トップへ戻る</a> 106 </div> 107 108 </form> 109 </div> 110 111 <script type="text/javascript" src="js/jquery-3.6.0.min.js"></script> 112 <script src="js/jquery.js"></script> 113</body> 114</html>

PHP

1//MVC controller 2<?php 3require_once(ROOT_PATH .'/Models/Player.php'); 4require_once(ROOT_PATH .'/Models/Goal.php'); 5 6 7class PlayerController { 8 private $request; // リクエストパラメータ(GET,POST) 9 private $Player; // Playerモデル 10 private $Goal; // Goalモデル 11 12 public function __construct() { 13 // リクエストパラメータの取得 14 $this->request['get'] = $_GET; 15 $this->request['post'] = $_POST; 16 17 // モデルオブジェクトの生成 18 $this->Player = new Player(); 19 20 // 別モデルとの連携 21 $dbh = $this->Player->get_db_handler(); 22 $this->Goal = new Goal($dbh); 23 } 24 25 public function index() { 26 $page = 0; 27 if(isset($this->request['get']['page'])) { 28 $page = $this->request['get']['page']; 29 } 30 $players = $this->Player->findAll($page); 31 $players_count = $this->Player->countAll(); 32 $params = [ 33 'players' => $players, 34 'pages' => $players_count / 20 35 ]; 36 return $params; 37 } 38 // 編集画面用 39 public function edit() { 40 if(empty($this->request['get']['id'])) { 41 echo '指定のパラメータが不正です。このページは表示できません。'; 42 exit; 43 } 44 $player = $this->Player->findById($this->request['get']['id']); 45 $params = [ 46 'player' => $player, 47 ]; 48 return $params; 49 } 50 // 更新フォームバリデーション 51 public function validate($post) { 52 $error = []; 53 // 省略 54 return [$post,$error]; 55 } 56 57 // 編集画面更新用 58 public function update($post) { 59 // echo "<pre>"; 60 // echo var_dump($post); 61 // echo "</pre>"; 62 // echo var_dump($post['club']); 63 // exit(); 64 $player = $this->Player->dbUpdate($post); 65 }

PHP

1//MVC Model 2<?php 3require_once(ROOT_PATH .'/Models/Db.php'); 4 5class Player extends Db { 6 7 public function __construct($dbh = null) { 8 parent::__construct($dbh); 9 } 10 11 // 選手情報更新用関数 12 public function dbUpdate($post) { 13 try { 14 // DB接続 15 $sth = $this->dbh; 16 // DBを更新するSQL文 17 $sql = "UPDATE players SET 18 name = :name, country_id = :country_id, uniform_num = :uniform_num, 19 position = :position, club = :club, birth = :birth, height = :height, weight = :weight 20 WHERE id = :id"; 21 // トランザクション開始 22 $sth->beginTransaction(); 23 // 値をセット 24 $stmt = $sth->prepare($sql); 25 $stmt->bindValue(':id',$post['id'],PDO::PARAM_INT); 26 $stmt->bindParam(':name',$post['name'],PDO::PARAM_STR); 27 $stmt->bindValue(':country_id',(int)$post['country_id'],PDO::PARAM_INT); 28 $stmt->bindValue(':uniform_num',(int)$post['uniform_num'],PDO::PARAM_INT); 29 $stmt->bindParam(':position',$post['position'],PDO::PARAM_STR); 30 $stmt->bindParam(':club',$post['club'],PDO::PARAM_STR); 31 $stmt->bindValue(':birth',(int)$post['birth'],PDO::PARAM_INT); 32 $stmt->bindValue(':height',(int)$post['height'],PDO::PARAM_INT); 33 $stmt->bindValue(':weight',(int)$post['weight'],PDO::PARAM_INT); 34 $stmt->execute(); 35 $sth->commit(); 36 } catch(PDOException $e) { 37 $sth->rollBack(); 38 exit($e); 39 } 40 }

php

1//MVC View update.php 2<?php 3require_once(ROOT_PATH .'Controllers/PlayerController.php'); 4session_start(); 5 6if (!isset($_SESSION['form'])){ 7 header('Location: index.php'); 8 exit(); 9} else { 10 $post = $_SESSION['form']; 11} 12$player = new PlayerController(); 13$player->update($post); 14 15unset($_SESSION['form']); 16header('Location: index.php'); 17exit(); 18 19?>

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

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

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

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

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

m.ts10806

2021/12/13 07:09

「うまくいかず」のところを、どう書いて何が起きたか具体的に書いていただけると
n_k23

2021/12/13 07:13 編集

申し訳ありません。 うまくいかずはSQL更新する際のid指定がうまくいっていないのでidのデータを確認してみたのですが 更新関数の前で$post['id']を出力してみたのですがデータがしっかりときているので問題ないと思っているのですがSQL更新がされないことです。 質問を修正しておきます。
m.ts10806

2021/12/13 08:53

SQLではなくDBでは。 SQLはDBを更新するための命令文そのものです。
m.ts10806

2021/12/13 08:54

あと「うまくいかない」という表現が癖になってるみたいなのでやめられたほうが良いかと。情報量ゼロの表現です。
n_k23

2021/12/13 09:03

返信ありがとうございます。 確かに「うまくいかない」というのが癖になっていますね。 しっかりと内容を表現するように気を付けていきます。
guest

回答3

0

PDOStatement::bindValuePDOStatement::bindParam は使う目的が違います。
参考:bindParam()とbindValue()の違い - Qiita
参考:PHP bindParam()の落とし穴とbindValue()メモ - Qiita

UPDATE文を実行する上では bindValue() の方に統一してください。

投稿2021/12/13 08:06

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

n_k23

2021/12/13 09:04

php-gres様 返信ありがとうございます。 どちらでも問題ないと思っていたのですが参考URLにて内容を しっかりと確認いたしました。 ありがとうございます。
guest

0

ベストアンサー

前準備

Db::__construct()の実装が分からないので、

PHPでデータベースに接続するときのまとめ
を参考にして例外を正しく捕まえられるようにします。

開発の前提

正しいSQLを固定値で直接実行してみて、正常に動作することを確認します

問題の解明

前準備が出来ている場合、SQLが間違っていたりプレースホルダに正しくバインドされていない場合、例外が発生します。

ただ、現状のコード

PHP

1 } catch(PDOException $e) { 2 $sth->rollBack(); 3 exit($e); 4 } 5

だと、問題があってもロールバックして終わってしまい、何が起きているか把握出来ないので

PHP

1 } catch(PDOException $e) { 2 $sth->rollBack(); 3 echo $e->getMessage(); 4 echo $e->getTraseAsString(); 5 exit(1); 6 } 7

とするか、フレームワークの提供するロガーにエラー内容を出力させてエラーメッセージを確認してください。

エラーメッセージを確認出来れば、それに沿ってデバッグをすれば解決します。

$post['id']を出力してみるとデータがしっかりと入っているのみ更新されないので困惑しています。

は上記の後に確認かなという感じですが、id以外も全部チェックしましょう。

投稿2021/12/13 08:05

編集2021/12/13 08:06
tanat

総合スコア18727

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

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

退会済みユーザー

退会済みユーザー

2021/12/13 08:08

例外をキャッチできるようにして、$e->getMessage() などとしてエラー内容をチェックできるようにしないと、始まらないですよね。
n_k23

2021/12/13 09:13 編集

tanat様、php-gres様 ご回答ありがとうございます。 先ほどの両名に指摘された箇所を修正しエラーメッセージを表示させてみたところ エラー箇所が判明いたしました。 エラー箇所を調査し修正を行っていきたいと思います。 エラーメッセージを表示させるといったことを失念しておりました。 ご指摘、ありがとうございます。
tanat

2021/12/13 09:18

> php-gresさん この辺りを完全に無視している教材が結構な割合で存在するのが困ったところですよね。 > n_k23さん エラーが表示されて良かったです。 `php xdebug ブレークポイント `+使用しているIDE名(VSCode等)で検索して、コードにブレークポイントを仕掛けられる環境を作るとデバッグがより楽になるので(echoやvar_dumpでコードを汚さなくても変数の内容が確認出来るようになります)、デバッグ環境構築にチャレンジするのもお勧めです。
n_k23

2021/12/13 09:32

tanat様 ご返信ありがとうございます。 今まで色んな箇所でechoやvar_dumpを使い表示してはコードを消してを繰り返していたので これでエラー箇所を探すのは大変だなと思っていました。 落ち着いたらデバック環境構築に挑戦してみたいと思います。
guest

0

php

1// 選手情報更新用関数 2 public function dbUpdate($post) { 3 try { 4 // DB接続 5 $sth = $this->dbh; 6 // DBを更新するSQL文 7 $sql = "UPDATE players SET 8 name = :name, country_id = :country_id, uniform_num = :uniform_num, 9 position = :position, club = :club, birth = :birth, height = :height, weight = :weight 10 WHERE id = :id"; 11 // トランザクション開始 12 $sth->beginTransaction(); 13 // 値をセット 14 $stmt = $sth->prepare($sql); 15 $stmt->bindValue(':id',$post['id'],PDO::PARAM_INT); 16 $stmt->bindValue(':name',$post['name'],PDO::PARAM_STR); 17 $stmt->bindValue(':country_id',(int)$post['country_id'],PDO::PARAM_INT); 18 $stmt->bindValue(':uniform_num',(int)$post['uniform_num'],PDO::PARAM_INT); 19 $stmt->bindValue(':position',$post['position'],PDO::PARAM_STR); 20 $stmt->bindValue(':club',$post['club'],PDO::PARAM_STR); 21 $stmt->bindValue(':birth',$post['birth'],PDO::PARAM_STR);//原因PDO::PARAM_INT 22 $stmt->bindValue(':height',(int)$post['height'],PDO::PARAM_INT); 23 $stmt->bindValue(':weight',(int)$post['weight'],PDO::PARAM_INT); 24 $stmt->execute(); 25 $sth->commit(); 26 } catch(PDOException $e) { 27 $sth->rollBack(); 28 echo $e->getMessage(); 29 echo $e->getTraceAsString(); 30 exit(1); 31 } 32 }

ご回答いただいた2名の内容を記述し検証してみると更新の際のエラーメッセージがわかりやすく表示された。
sqlstate[22007]: invalid datetime format: 1292 incorrect date value: '1979' for column 'birth' at row 1
idが問題だと思っていたが違っていた。birthの項目で無効な日時形式というエラーが発生していた。
そこでbirthの値を確認してみると値をINT型で渡していたのが原因だと判明。
修正し無事、DBを更新することができました。
的確なアドバイスしていただきありがとうございます。

投稿2021/12/13 12:00

n_k23

総合スコア21

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問