データベースに接続できません。 - PHPプロ!Q&A掲示板

4832

  • 0P

データベースに接続できません。

質問日時 / 2017年3月22日 22:16    回答数 / 1件

Questioner:  mimizu89  このエントリーをはてなブックマークに追加 

キーワード / キーワードが設定されていません

アカウント認証のプログラムを書いてみたんですが実行してみるとデータべースに接続できませんでした。
Notice: Undefined variable: stmt in C:\xampp\htdocs\green\rogin-output.php on line 25

Fatal error: Uncaught Error: Call to a member function fetch() on null in C:\xampp\htdocs\green\rogin-output.php:25 Stack trace: #0 {main} thrown in C:\xampp\htdocs\green\rogin-output.php on line 25
という画面がでます。解決方法を教えてください。お願いします。

<?php require 'header.php';?>
<?php
$username=$_POST['username'];
$password=$_POST['password'];

$username=htmlspecialchars($username, ENT_QUOTES, 'UTF-8');
$password=htmlspecialchars($password, ENT_QUOTES, 'UTF-8');

try{
$dns='mysql:host=localhost,dbname=greendb,charset=utf8';
$dbuser='ishihara';
$dbpassword='1485';
$dbh=new PDO($dns,$dbuser,$dbpassword);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql='select username from account where password=?';
$stmt=$dbh->prepare($sql);
$stmt->bindValue(':password, $password, PDO::PARAM_INT');
$stmt->execute();    
}
catch(PDOException $e){
echo '接続できませんでした。';    
}

if($stmt->fetch()==true){
    header('Location:green-home.php');
}
else{
    echo 'ログインできませんでした。';
}
?>
<?php require 'footer.php';?>

この質問への意見の募集は締め切られ、ポイントは既に配分されました。
意見を投稿することはできますが、ポイントを受け取ることはできません。



ツリー一覧

┗A01shimix>$dns='mysql:host=localhost,dbname=greendb,charset

回答一覧

並び替え:

A01
answerershimix [3月23日 09:13] (最終編集:3月23日 11:36)

>$dns='mysql:host=localhost,dbname=greendb,charset=utf8';

DNSの記述をマニュアルで確認していただければわかると思いますが、カンマではなくセミコロンで区切ります。
http://php.net/manual/ja/ref.pdo-mysql.connection.php



以下気付いた点


・提示されているエラーメッセージは無意味です。接続してSQL実行していることが前提のソースをtry~catch構文の『外』に書いていますから(接続でエラーになってcatchで捕捉されていればtryブロックは途中までしか実行されていません)エラーになるのが当然です。

・prepareしているSQL文のプレースホルダは疑問符なのにbindValueは名前付きプレースホルダ(:password)になっています。というか全部が文字列リテラルになっています。そもそもパスワードが整数というのもヘンです(間違いないですか)。
  $sql='select username from account where password=?';
  $stmt->bindValue(':password, $password, PDO::PARAM_INT');

  $sql='select username from account where password=:password';
  $stmt->bindValue(':password', $password, PDO::PARAM_INT);

・$usernameや$passwordをhtmlspecialchars()している意図がわかりません。何のための関数かはご存知ですよね>htmlspecialchars。htmlとして返す(表示する)文字列以外に使ってはいけません。
  http://php.net/manual/ja/function.htmlspecialchars.php

・DBに生のパスワードを格納しているようですが、これはやめましょう。パスワードからpassword_hash()を使って生成した文字列を格納してください(取り出したらpassword_verify()でチェックする)。
  http://php.net/manual/ja/function.password-hash.php

・もしheader.phpというのがhtmlを返すものだったらheader()より前に置いてはいけません(footer.phpがあるので心配になりました)。
  http://php.net/manual/ja/function.header.php
  1. <?php
  2. session_start()// セッションを使うならここで開始
  3.  
  4. $username = isset($_POST['username']) ? $_POST['username'] : '';;
  5. $password = isset($_POST['password']) ? $_POST['password'] : '';;
  6.  
  7. try {
  8.     $dns = 'mysql:host=localhost;dbname=greendb;charset=utf8';
  9.     $dbuser = 'ishihara';
  10.     $dbpassword = '1485';
  11.  
  12.     $dbh = new PDO($dns$dbuser$dbpassword);
  13.     $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARESfalse);
  14.     $dbh->setAttribute(PDO::ATTR_ERRMODEPDO::ERRMODE_EXCEPTION);
  15.     $stmt = $dbh->prepare('select * from account where username=?');
  16.     $stmt->execute(array($username));    
  17.     if ($row = $stmt->fetch()){
  18.         if (password_verify($password$row['password'])) {
  19.             // 必要に応じてセッション変数セット
  20.             header('Location:green-home.php');
  21.         } else {
  22.             $emsg = 'ログインできませんでした。'// パスワード不一致
  23.         }
  24.     ] else {
  25.         $emsg = 'ログインできませんでした。'// 未登録ユーザ
  26.     }
  27. } catch (PDOException $e) {
  28.     $emsg = 'データベースエラーです';    
  29. }
  30.  
  31. if (isset($emsg)) {
  32.     require 'header.php';
  33.     echo $emsg;
  34.     require 'footer.php';
  35. }
  36. ?>

この意見に回答する

ツリーへ TOPへ

<<質問一覧へ



Pick Up Q&A

Q
ログファイルの中の空のデータ行を削除したい
 このエントリーをはてなブックマークに追加 
A
ログのデータ個数(列数)が固定で、空のログが"<><><>"だと既知であれば if ($line === "<><><>") { continue; } で読み飛ばしてもいいのでは? ...

>>続きを読む

まずは配列や文字列の扱いから、じっくり勉強して行きましょう。

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)

Q&A掲示板 新着情報