PHPのプラミングの質問です。

初心者で勉強中です。
sqlite を使ってチャットのプログラムをサーバーにアップロードをするとうまく動きます。
sqliteで接続する部分をmysqlに直してサーバにアップして接続すると
「Call to a member function execute() on a non-object in」とエラーが出て止まってしまいます。
どこがおかしいでしょうか?
mysqlはきちんと作動しています。(他のプログラムで試しました)

回答の条件
  • 1人3回まで
  • 登録:
  • 終了:2014/02/22 08:35:03
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。
id:hilogolf

sqliteのプログラム

$savepath = dirname(__FILE__).'/chatlog.db'; // ログの保存先

$script_name = $_SERVER["SCRIPT_NAME"]; // このプログラムのパス

// データベースへの接続

try {

$db = new PDO("sqlite:test.db");

} catch (PDOException $e) {

echo "データベースに接続できません。".$e->getMessage();

exit;

}

// チャットログのテーブル定義

$create_query = <<< ___SQL___

CREATE TABLE IF NOT EXISTS chatlog (

log_id INTEGER PRIMARY KEY, /* ログID */

name TEXT, /* 名前 */

body TEXT, /* 本文 */

ctime INTEGER /* 投稿日時 */

);

___SQL___;

$db->exec($create_query);

// 書き込み処理があったか?

if (isset($_GET["name"]) && isset($_GET["body"])) {

if ($_GET["name"] == "" || $_GET["body"] == "") {// 入力の検証

echo "

名前と本文は必ず入力してね。

"; exit;

}

// データベースに挿入

$template = "INSERT INTO chatlog (name,body,ctime)".

"VALUES(?,?,?);";

$stmt = $db->prepare($template);

$stmt->execute(array($_GET["name"],$_GET["body"], time()));

header("location: $script_name"); exit; // リロードする

}

// 書き込みフォームの表示

echo <<< __FORM__

<link type="text/css" rel="stylesheet" href="chat.css" />

<h3>チャット</h3>

<form action="$script_name" method="GET">

名前:<input type="text" name="name" size="8" />

本文:<input type="text" name="body" size="40" />

<input type="submit" value="書込" />

</form>

__FORM__;

// ログの表示

$select_query = "SELECT * FROM chatlog ORDER BY log_id DESC";

$stmt = $db->query($select_query);

foreach ($stmt as $row) {

$name = htmlspecialchars($row["name"]);

$body = htmlspecialchars($row["body"]);

$ctime = date("H:i:s", $row["ctime"]);

echo "

($ctime) $name > $body
";

}

?>

mysqlのプログラム

$savepath = dirname(__FILE__).'/chatlog.db';

$script_name = $_SERVER["SCRIPT_NAME"];

// データベースへの接続

try {

$username = "********";

$password = "*******";

$pdo = new PDO(

'mysql:host=************',

$username,

$password,

array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")

);

} catch (PDOException $e) {

echo "データベースに接続できません。".$e->getMessage();

exit;

}

// チャットログのテーブル定義

$create_query = <<< ___SQL___

CREATE TABLE IF NOT EXISTS chatlog (

log_id INTEGER PRIMARY KEY, /* ログID */

name TEXT, /* 名前 */

body TEXT, /* 本文 */

ctime INTEGER /* 投稿日時 */

);

___SQL___;

$db->exec($create_query);

if (isset($_GET["name"]) && isset($_GET["body"])) {

if ($_GET["name"] == "" || $_GET["body"] == "") {

echo "

名前と本文は必ず入力してね。

"; exit;

}

$template = "INSERT INTO chatlog (name,body,ctime)".

"VALUES(?,?,?);";

$stmt = $db->prepare($template);

$stmt->execute(array($_GET["name"],$_GET["body"], time()));

header("location: $script_name"); exit; // リロードする

}

echo <<< __FORM__

<link type="text/css" rel="stylesheet" href="chat.css" />

<h3>チャット</h3>

<form action="$script_name" method="GET">

名前:<input type="text" name="name" size="8" />

本文:<input type="text" name="body" size="40" />

<input type="submit" value="書込" />

</form>

__FORM__;

// ログの表示

$select_query = "SELECT * FROM chatlog ORDER BY log_id DESC";

$stmt = $db->query($select_query);

foreach ($stmt as $row) {

$name = htmlspecialchars($row["name"]);

$body = htmlspecialchars($row["body"]);

$ctime = date("H:i:s", $row["ctime"]);

echo "

($ctime) $name > $body
";

}

?>

回答2件)

id:tezcello No.1

回答回数460ベストアンサー獲得回数69

ポイント150pt

> Call to a member function execute() on a non-object in
エラーメッセージが出ているのだから、それが糸口になるはずです。
execute() しようとして non-objuect となっているのだから、PDO がどこかで失敗していると考えるのが筋でしょう。

で、よく見ると...
> $pdo = new PDO('mysql:....
> $db->exec($create_query);
明らかに PDO のインスタンスでないモノで呼び出そうとしていますね。

$pdo か $db かどちらかに統一すれば良いでしょう。

id:TransFreeBSD No.2

回答回数668ベストアンサー獲得回数268

ポイント150pt

テーブルのカラム作成時、log_idにAUTO_INCREMENTを付けてください。

log_id INTEGER AUTO_INCREMENT PRIMARY KEY, /* ログID */

エラーの意味は「オブジェクトではないのにexecute()メンバ関数を呼んだ」ということです。
なのでexecute()を探すと、

$stmt->execute(array($_GET["name"],$_GET["body"], time()));

とありますね。これの$stmtがオブジェクトではないと言ってるわけです。で、$stmtは一つ前の

$stmt = $db->prepare($template);

で代入されています。で、prepare()がオブジェクトを返さない時があるかというと、マニュアルにエラー時FALSEを返す場合があるとあります。ということはここでエラーになっているのでしょう。
ということは$templateが怪しいということで見てみると、

$template = "INSERT INTO chatlog (name,body,ctime)".
"VALUES(?,?,?);";

一見良さそうに見えますが、テーブルのchatlogはと言うと、

// チャットログのテーブル定義
$create_query = <<< ___SQL___
CREATE TABLE IF NOT EXISTS chatlog (
log_id INTEGER PRIMARY KEY, /* ログID */
name TEXT, /* 名前 */
body TEXT, /* 本文 */
ctime INTEGER /* 投稿日時 */
);
___SQL___;
$db->exec($create_query);

ここでもエラーチェックされていないのでエラーが発生している可能性、既に違うカラムの同名テーブルがある可能性とかありますが、よく見るとlog_idがPRIMARY KEYなのに INSERT INTOにありません。
sqliteではINTEGER PRIMARY KEYの場合、自動的にAUTOINCREMENT になるようなのでエラーになりませんが、mysqlでは明示しないとINSERT時にエラーになると思います。

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません