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

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

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

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

Q&A

解決済

1回答

1524閲覧

データベースに値が格納されない

newyee

総合スコア213

PHP

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

0グッド

0クリップ

投稿2019/04/11 03:31

登録フォームから、ユーザー情報を入力したら、データーベースに情報を格納する、新規ユーザ登録ページを作成したのですが、データベースにデーターが挿入されない為、以下のコードにて、問題点がありましたら、教えて頂きたいです。
以下は、「user_register.php」になります。

php

1<?php 2require_once 'function.php'; 3require_once 'config.php'; 4 5session_start(); 6$err = []; 7 8if(!empty($_POST)){ 9 10 $name = filter_input(INPUT_POST,'name'); 11 $password = filter_input(INPUT_POST,'password'); 12 13 if(!$name){ 14 $err['name'] = '名前を入力してください'; 15 16 } 17 18 if(!$password){ 19 20 $err['password'] = 'パスワードを入力してください'; 21 22 } 23 24 if(empty($err)){ 25 26 $password = password_hash($password,PASSWORD_DEFAULT); 27 28 try{ 29 //データベースにユーザー情報登録 30 $db = db_connection(DSN,DB_USERNAME,DB_PASSWORD); 31 $stmt = $db->prepare("INSERT INTO users_2(name,password) VALUES(:name,: password "); 32 33 $stmt->bindValue(':name',$name,PDO::PARAM_STR); 34 $stmt->bindValue(':password',$password,PDO::PARAM_STR); 35 $stmt->execute(); 36 37 //登録ユーザーのid取得 38 $stmt = $db->prepare("SELECT id FROM users_2 WHERE name = :name AND password = :password "); 39 $stmt->bindValue(':name',$name,PDO::PARAM_STR); 40 $stmt->bindValue(':password',$password,PDO::PARAM_STR); 41 $stmt->execute(); 42 43 if($row = $stmt->fetch()){ 44 $_SESSION['id'] = $row['id']; 45 }else{ 46 echo 'エラー'; 47 } 48 exit(); 49 50 }catch(PDOException $e){ 51 52 $e->getMessage(); 53 exit(); 54 55 } 56 57 } 58 59} 60 61?> 62 63 64 65<!DOCTYPE html> 66<html lang="en"> 67<head> 68 <meta charset="UTF-8"> 69 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 70 <title>register</title> 71</head> 72<body> 73 <h1>ユーザー登録</h1> 74 <form action="user_register.php" method="post"> 75 <p>名前:<input type="text" name="name"></p> 76 <p>パスワード:<input type="password" name="password"></p> 77 <input type="submit"value="送信"> 78 </form> 79 <?php 80 if(!empty($err)): 81 foreach($err as $value): ?> 82 <p><?= $value ?></p> 83 <?php endforeach; 84 85 endif; 86?> 87 88</body> 89</html>

以下は、「function.php」になります

php

1<?php 2function db_connection($dsn,$user,$password){ 3 $db = new PDO($dsn,$user,$password); 4 $db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 5 $db->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); 6 return $db; 7} 8 9function h($str){ 10 return htmlspecialchars($str,ENT_QUOTES,'UTF-8'); 11}

以下は、「config.php」になります

php

1<?php 2define('DSN','mysql:host=localhost;dbname=online_bbs;charset=utf8'); 3define('DB_USERNAME', 'root'); 4define('DB_PASSWORD', '12345');

よろしくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

これだけでは何とも言えませんが、1つ指摘するとしたら下記

php

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

getMessage()の返却値はstringです。
返ってくる値を出力も何もしていないのでしたらエラーtry内で起きた異常に気づくことはできません。
echoするかexit()の引数に入れるか開発中のものであればvar_dump($e);として全部出力するのもありです。
いずれにしてもその場で出力してしまってはエラーログとれないのでログ出力は必須です。

投稿2019/04/11 03:35

編集2019/04/11 03:39
m.ts10806

総合スコア80765

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

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

newyee

2019/04/11 03:40

ご回答ありがとうございます。 echo しましたら、エラーメッセージが表示され、解決できました
m.ts10806

2019/04/11 03:50 編集

というか先に聞いておけばよかったですね。 >データベースにデーターが挿入されない 実行したらどういう画面になるか、とか。 catchに入ってるならexit()にいってるわけで、出力処理がないので「何も画面に出ない」という現象になるはずですよね。 他で出力されるとしたら下記 if($row = $stmt->fetch()){ $_SESSION['id'] = $row['id']; }else{ echo 'エラー'; } ですけど、ifがtrueのときに何もしてないので「何も画面に出なかった」=「うまくいった」という担保にはなりません。 開発段階のものであれば全ての分岐で何かしら出力を挟んでおくのが定石です。 if($row = $stmt->fetch()){ $_SESSION['id'] = $row['id']; echo 'OK'; }else{ echo 'エラー'; } おすすめは任意のメッセージよりもプログラム行数の出力。 echo __LINE__.PHP_EOL; https://www.php.net/manual/ja/language.constants.predefined.php これなら「どこを通ったか」がほぼ一意になるし、わざわざデバッグecho用の文言考えなくても済みます。 毎回これ打つのがめんどくさければ共通関数用意しておいて呼び出せばよいです。 function myline(){ echo __LINE__.PHP_EOL; } myline();
newyee

2019/04/11 03:49

$stmt = $db->prepare("INSERT INTO users_2(name,password) VALUES(:name ,:password )");」 こちらの部分は「user_register.php」の修正後なのですが、最後のダブルクォートの位置がカッコの内側「(:name ,:password ")」に入っていたのが原因でした。
newyee

2019/04/11 03:52

アドバイスどうもです。 >開発段階のものであれば全ての分岐で何かしら出力を挟んでおくのが定石です 出来るだけそうしていこうと思います。
m.ts10806

2019/04/11 03:54

> 最後のダブルクォートの位置がカッコの内側「(:name ,:password ")」に入っていたのが原因でした。 SQLは直接DBに対して実行して正常動作したものを使いましょう。 https://teratail.com/questions/182972#reply-272231 > MySQLは外部の仕組みです。プログラムから利用する前に、実際に想定したデータがとれるSQLを作って正しく結果を得られてからプログラムに組み込むのが確実です。 直接実行して想定通り動かないものは外部から使っても想定通り動くはずがありません。
newyee

2019/04/11 03:55

行番号を表示する関数なんてあるんですね。 確かに、これだと、echoせずとも、どこの行が問題なのか分かるので便利ですね
newyee

2019/04/11 03:58 編集

実は、dbへは直接コピペして、試してみたのですが、それが成功したんですよね。 なので、そこで格納できない原因が分からなくなったのですが、恐らくプレースホルダの部分をいじってる際に、ダブルクォートの位置を間違えてしまったのかもしれません
m.ts10806

2019/04/11 04:07 編集

>echoせずとも、どこの行が問題なのか分かるので便利ですね echoは必要ですよ。定数で文字列が保管されているので。共通関数でechoまで持っただけの話です。 var_dump()にも同じことが言えますね。htmlspecialchars()についても同じ。 標準関数をラッパーして短縮するのは色々なところで応用がきくので覚えておいて損はありません。 あとは通った個所のメソッド名を知るもの、そこまでの経緯をトレースするものdebug_backtrace() など。デバッグ方法は適宜取り入れる必要があります。var_dump()が全てではありません。 > 実は、dbへは直接コピペして、試してみたのですが、それが成功したんですよね。 そこは一言入れておかないと誰にも伝わりません。 でもそこまで踏み込んだならもう1歩です。「成功したSQLとプログラムに書いたSQLを比べる」ことで差異に気づけたはずだからです。 プログラムは書いたようにしか動かないので、別の個所で正常に動いたものを移管してまた別の環境でそのまま動く保証はどこにもありません。単に1つ担保ができた程度です。(もちろん何の担保もなしに突っ込むのは愚行です)「コピーして書き換える」という手動手順が発生しているからです。手順が多ければ不具合の発生率は上がります。 動かないのはプログラム自身の責任ではなく書いた人の責任です。正しく書けていないから動かない、まずは自身を疑いましょう。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問