初心者で勉強中です。
sqlite を使ってチャットのプログラムをサーバーにアップロードをするとうまく動きます。
sqliteで接続する部分をmysqlに直してサーバにアップして接続すると
「Call to a member function execute() on a non-object in」とエラーが出て止まってしまいます。
どこがおかしいでしょうか?
mysqlはきちんと作動しています。(他のプログラムで試しました)
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__;
// ログの表示
$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 "
}
?>
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__;
// ログの表示
$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 "
}
?>
> 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 かどちらかに統一すれば良いでしょう。
テーブルのカラム作成時、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件)