人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

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

●質問者: hilogolf
●カテゴリ:コンピュータ ウェブ制作
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

質問者から

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
";
}
?>

1 ● tezcello
●150ポイント

> 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 かどちらかに統一すれば良いでしょう。


2 ● TransFreeBSD
●150ポイント

テーブルのカラム作成時、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時にエラーになると思います。

関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ