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

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

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

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

Q&A

解決済

3回答

21285閲覧

PHPの「Fatal error: Uncaught Error: Call to a member function query() on null」エラーについて

KM46

総合スコア17

PHP

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

0グッド

0クリップ

投稿2019/06/04 01:46

##PHPのデータベースを利用した掲示板で内容が表示できない
ログインした状態からチャットを入力し、

  • 入力したユーザー
  • 内容

の二点を、SQliteを利用して表示する掲示板を作成したいのですが、
エラーメッセージが表示され上手くいきません。
#発生している問題・エラーメッセージ

php

1Notice: Undefined variable: db in C:\xampp\htdocs\login-bbs2.php on line 91 2 3Fatal error: Uncaught Error: Call to a member function query() on null in C:\xampp\htdocs\login-bbs2.php:91 Stack trace: #0 C:\xampp\htdocs\login-bbs2.php(72): show_log() #1 C:\xampp\htdocs\login-bbs2.php(28): show_login_contents() #2 {main} thrown in C:\xampp\htdocs\login-bbs2.php on line 91

##該当のソースコード

php

1<?php session_start(); 2$users = array( 3 "takeshi" => "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3",//test 4 "yutaka" => "ee3f7d52ca341c51c694af9288701f4ce43be0ad",//rabit 5 "akiko" => "f91a8ee646a277a2f1359709604b99c1b32d9f24",//panda 6 "mamoru" => "e08f57d03a1a78d2473c0520cbf0db9d3aadcc49" 7); 8 9$savepath = dirname(__FILE__).'/log.db'; 10$script=$_SERVER["SCRIPT_NAME"]; 11 12try { 13 $db = new PDO("sqlite:$savepath"); 14} catch (PDOException $e) { 15 echo "接続失敗:".$e->getMessage(); exit; 16} 17 18$create_query = <<< __SQL__ 19CREATE TABLE IF NOT EXISTS log (                          20 log_id INTEGER PRIMARY KEY, 21 user TEXT; 22 body TEXT, 23); 24__SQL__; 25$db->exec($create_query); 26 27if (isset($_SESSION["login"])) { 28 show_login_contents(); 29} 30 31if (isset($_POST["user"])) { 32 check_login(); 33} else { 34 show_login_form(); 35} 36 37function show_login_form() { 38 global $script; 39 echo <<< __FORM__ 40 <div id="loginform"> 41 <form action="$script" method="POST"><h3>ログインしてください</h3> 42 <label>ユーザー名</label><input type="text" name="user" /> 43 <label>パスワード</label><input type="password" name="pass" /> 44 <button type="submit">ログイン</button> 45 </form></div> 46__FORM__; 47} 48 49function check_login() { 50 global $users, $script; 51 if(empty($_POST["pass"])){ 52 echo "パスワードが入力されていません"; exit; 53 } 54 if(empty($users[$_POST["user"]])) { 55 echo "ユーザーが存在しないかパスワードが違います。"; exit; 56 } 57 58 $pass_correct = $users[$_POST["user"]]; 59 if(sha1($_POST["pass"]) != $pass_correct) { 60 echo "ユーザーが存在しないかパスワードが違います。"; exit; 61 } 62 63 $_SESSION["login"] = array("user" => $_POST["user"]); 64 echo "<a href='$script'>ログインしました!</a>"; 65} 66 67function show_login_contents() { 68 $m = isset($_GET["m"]) ? $_GET["m"]:""; 69 switch ($m) { 70 case "logout": show_logout(); break; 71 case "write": write_log(); break; 72 default: show_log(); break; 73 } 74} 75 76function show_log() { 77 global $script, $savefile; 78 $user = $_SESSION["login"]["user"]; 79 echo "<h1>こんにちは、{$user}さん!</h1>"; 80 echo "現在ログイン中"; 81 echo "→(<a href='$script?m=logout'>ログアウトする</a>)"; 82 echo "</ul>"; 83 echo "<form action='$script' method='get'>"; 84 echo "<input type='text' name='body' size='40' />"; 85 echo "<input type='hidden' name='m' value='write' />"; 86 echo "<input type='submit' value='書き込み' />"; 87 echo "</form>"; 88 echo "<h3>掲示板</h3>"; 89 90 $select_query = "SELECT * FROM log ORDER BY log_id DESC"; 91 $stmt = $db->query($select_query); //エラー箇所です 92 93 foreach ($stmt as $row) { 94 $name = htmlspecialchars($row["user"]); 95 $body = htmlspecialchars($row["body"]); 96 echo "<div class='log'>$name &gt; $body</div>"; 97 } 98} 99 100// 次回ここから 101 102function write_log() { 103 if (isset($_GET["body"])) { 104 if ($_GET["body"] == "") { 105 echo "<p>内容を入力してください。</p>"; exit; 106 } 107 108 $template = "INSERT INTO chatlog (user,body)". 109 "VALUES(?,?);"; 110 $stmt = $db->prepare($template); 111 $stmt->execute(array($_GET["user"],$_GET["body"])); 112 header("location: $script"); exit; 113 } 114} 115 116function show_logout() { 117 global $scripit; 118 unset($_SESSION["login"]); 119 echo "<a href='script'>ログアウトしました</a>"; 120 exit; 121}

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

PHPのバージョンは5.2.0です。

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

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

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

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

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

guest

回答3

0

Fatal error: Uncaught Error: Call to a member function query() on null in C:\xampp\htdocs\login-bbs2.php:91 Stack trace: #0 C:\xampp\htdocs\login-bbs2.php(72): show_log() #1 C:\xampp\htdocs\login-bbs2.php(28): show_login_contents() #2 {main} thrown in C:\xampp\htdocs\login-bbs2.php on line 91

書いてあるとおりで、

オブジェクトのメンバーメソッドの query() を呼び出そうとしたけれど、オブジェクトが null です

なのですから、

PHP

1 $stmt = $db->query($select_query); //エラー箇所です

この $db が NULL で呼び出しているのです。

なぜかというと、

try { $db = new PDO("sqlite:$savepath"); } catch (PDOException $e) { echo "接続失敗:".$e->getMessage(); exit; }

で $db は「グローバルスコープ」で配置されていますから、show_log() 関数内部では見ることができません(関数ローカルの $db という変数と見なされ、初期値指定してないので NULL になる)。

PHP のマニュアルを見て、変数のスコープを意識してください。

※まあ、global 指定するよりは show_log() に引数として $db 渡すようにした方がよいと思いますが

投稿2019/06/04 02:01

tacsheaven

総合スコア13703

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

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

KM46

2019/06/04 02:15

$dbを利用しているshow_log()と、write_log()にグローバルでdbを渡すようにしたところ、今度は以下のようなエラーメッセージが表示されました。 `Warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\login-bbs2.php on line 93` m6uさんに教えていただいた「DB Browser for SQLite」を利用して確認したところ、 db自体は出来ているのですが、テーブルが作成されていないみたいなので、改めて質問させて頂きます。
guest

0

エラー箇所でvar_dump($db);すれば、たぶんNULLだと思うので、
$db = new PDO("sqlite:$savepath");でアクセスする先のデータベースファイルにphpからアクセスできてないのかもしれない。
ファイル自体のアクセス権が足りないとか、そもそもファイルが存在しないとか。

「DB Browser for SQLite」“SQLite”のデータベースを管理できるソフト - 窓の杜
などSQLiteファイルを観られるツールで読めることを確認するなど。

あるいは、そのスコープで$dbが未定義になっているとか。

投稿2019/06/04 01:59

編集2019/06/04 02:01
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

KM46

2019/06/04 02:09

ありがとうございます。 教えていただいたツールで確認したところlog.db自体は作成されているのですが、肝心の中身が何も作成されていませんでした。テーブル自体が作成されていないようなので、コード自体を見直してみます。
退会済みユーザー

退会済みユーザー

2019/06/04 02:15

「CREATE TABLE IF NOT EXISTS 」って構文がSQLiteで使えないかもしれません。テーブルのSELECTに失敗したときにテーブルを作成するなど、アプローチを見直すべきかと。(もうわかってる話かもしれません、すみません。)
guest

0

ベストアンサー

show_log()内に$dbは未定義です(エラーそのまま)
とりあえずの解決策で良ければglobalで渡すと良いです。

投稿2019/06/04 01:56

m.ts10806

総合スコア80873

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

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

KM46

2019/06/04 02:06

回答ありがとうございます。 とりあえず該当のエラーは解消されました。
m.ts10806

2019/06/04 02:08

はい。本当に「とりあえず」です。 他のglobalも含めてglobalに頼らない実装が望ましいのは言うまでもありません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.42%

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

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

質問する

関連した質問