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

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

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

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

Q&A

解決済

4回答

1851閲覧

PHPの「Warning: Invalid argument supplied for foreach()」エラーについて

KM46

総合スコア17

PHP

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

0グッド

0クリップ

投稿2019/06/04 02:29

PHPのデータベースを利用した掲示板を作成したい

ログインした状態からチャットを入力し、

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

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

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

Warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\login-bbs2.php on line 92

該当のソースコード

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, $db; 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 foreach ($stmt as $row) { 93 $name = htmlspecialchars($row["user"]); 94 $body = htmlspecialchars($row["body"]); 95 echo "<div class='log'>$name &gt; $body</div>"; 96 } 97} 98 99// 次回はここから 100 101function write_log() { 102 global $db; 103 if (isset($_GET["body"])) { 104 if ($_GET["body"] == "") { 105 echo "<p>内容を入力してください。</p>"; exit; 106 } 107 108 $template = "INSERT INTO log (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}

試したこと

「DB Browser for SQLite」を利用して確認したところ、
login.db自体は作成されているのですが、テーブル自体がうまく作成できていないみたいです...。
たぶん、該当の部分に問題があると思うのですが...。

php

1$create_query = <<< __SQL__ 2CREATE TABLE IF NOT EXISTS log (                          3 log_id INTEGER PRIMARY KEY, 4 user TEXT; 5 body TEXT, 6); 7__SQL__; 8$db->exec($create_query);

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

・windows10
・XAMPP

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

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

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

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

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

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

guest

回答4

0

ベストアンサー

デバッグしてください。

1.結果を確認すること

php

1 $select_query = "SELECT * FROM log ORDER BY log_id DESC"; 2 $stmt = $db->query($select_query); 3 var_dump($stmt);exit; 4 foreach ($stmt as $row) { 5 $name = htmlspecialchars($row["user"]); 6 $body = htmlspecialchars($row["body"]); 7 echo "<div class='log'>$name &gt; $body</div>"; 8 }

2.SELECT * FROM log ORDER BY log_id DESCをDBに対して実際に実行してみること(sqliteでコマンドから実行する方法例
CREATE TABLEとかも試してみると良いですよ。直接実行して成功しないSQLはプログラムから実行しても成功しません。
SQLテストサービスなども活用してください。(例:SQL Fiddle

3.PDOExceptionをキャッチする仕組みを導入すること

DB接続部

php

1try { 2 $db = new PDO("sqlite:$savepath"); 3 $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 4 $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 5} catch (PDOException $e) { 6 echo "接続失敗:".$e->getMessage(); exit; 7}

問題の箇所

php

1try { 2 $select_query = "SELECT * FROM log ORDER BY log_id DESC"; 3 $stmt = $db->query($select_query); 4 foreach ($stmt as $row) { 5 $name = htmlspecialchars($row["user"]); 6 $body = htmlspecialchars($row["body"]); 7 echo "<div class='log'>$name &gt; $body</div>"; 8 } 9} catch (PDOException $e) { 10 var_dump($e);die(); 11}

※CREATE TABLEに問題があると思うのでしたらそこにも同じようにtry-catch張ってください。
$eはなるべくvar_dump()などで全て出力したほうがより多くの情報を得られます。

デバッグによって問題の切り分けを行い、原因の絞り込み、対策を行っていきます。

蛇足:

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

PHP7.1以上を使いましょう。
5.6ですらサポート終了した今、さすがに5.2は学習対象としてもお世辞にも良いとは言えません。

投稿2019/06/04 02:40

編集2019/06/04 03:01
m.ts10806

総合スコア80731

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

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

0

SQL

1CREATE TABLE IF NOT EXISTS log (                          2 log_id INTEGER PRIMARY KEY, 3 user TEXT; 4 body TEXT, 5);

第2カラムが user TEXT**;** になってるので、ここで文が終了してしまい、create table 文としては不完全ですね。良く見直してください。

投稿2019/06/04 02:46

tacsheaven

総合スコア13703

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

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

0

これで解決できませんか?

php

1$create_query = <<< __SQL__ 2CREATE TABLE IF NOT EXISTS log (                          3 log_id INTEGER PRIMARY KEY, 4 user TEXT, 5 body TEXT 6);

投稿2019/06/05 09:09

hide0128

総合スコア245

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

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

0

CREATE TABLE IF NOT EXISTS log (                         

原因がわかりました。
上記の文に大量の空欄が含まれていました(-_-;)

CREATE TABLE IF NOT EXISTS log (
上記のように修正したところ、無事にテーブルも作成され、問題なく動いたので報告させていただきます。空白を表示するようにエディターを設定しないといけませんね...。

投稿2019/06/07 02:37

編集2019/06/07 02:39
KM46

総合スコア17

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問