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

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

回答の条件
  • 1人3回まで
  • 13歳以上
  • 登録:2014/02/15 08:31:14
  • 終了:2014/02/22 08:35:03
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" />

チャット



名前:
本文:


__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" />

チャット



名前:
本文:


__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

tezcello回答回数460ベストアンサー獲得回数692014/02/15 10:23:05

ポイント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

TransFreeBSD回答回数665ベストアンサー獲得回数2672014/02/15 10:23:37

ポイント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時にエラーになると思います。

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

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

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

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

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません