sqlite3での質問です。

DB自体をはじめて触ります。
PDOでデータの出し入れをしているのですがupdateの際に以下のエラーが出てきます。
Fatal error: Call to a member function bindParam() on a non-object in /サーバー内パス/example.php on line 102
色々と調べて文字コードなんかが原因である事が多いとわかりました。
今は以下のコードでデータには特に何もせずにデータをDBに放り込んでいます。
098行目 $sql = "INSERT INTO blog(id, example)
099行目  VALUES(:id, :example,)";
100行目 $conn = new PDO("sqlite:./test.sql");
101行目 $stmt = $conn->prepare($sql);
102行目 $stmt->bindParam(":id", $id);
103行目 $stmt->bindParam(":example", $example);
104行目 $stmt->execute();
105行目 $id = $conn->lastInsertId();
IDやexampleにはPOSTのデータがそのまま入っています。
そこで質問なのですが、DBに入れる放り込む際にやった方がよいことが以下でいいかどうか教えてください。
文字コードの変換とHTMLエンティティに変換
$_POST['id'] = mb_convert_encoding($_POST['id'], "UTF-8", "auto");
$_POST['id'] = htmlspecialchars($_POST['id']);
insertとupdateではまた違うのかもしれませんが、DBにデータを入れる際にやったほうがいいことや気をつけた方がよい事があればご教示ください。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2011/02/05 21:46:59
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答3件)

id:hanako393 No.1

回答回数1142ベストアンサー獲得回数87

ポイント27pt

文字コードの問題でなくて、SQL文が間違ってるんだと思いますが・・・。

http://d.hatena.ne.jp/pidgeot/20100730/1280510910

http://learnaboutphpmysql.blogspot.com/2010/10/call-to-member-fu...

id:quocard

ご指摘ありがとうございます。

質問にもありますようにそちらのコードでINSERT自体は行えております。

正常に動いているように見えているけど実際には違っているということでしょうか?

2011/02/04 12:51:29
id:kopj No.2

回答回数123ベストアンサー獲得回数6

ポイント27pt

098行目 $sql = "INSERT INTO blog(id, example)

099行目  VALUES(:id, :example,)";


このSQLで

id, example に :id, :example, を 入れるというようなっていますが、カンマの数が合わないため、通常は このSQL自体でエラーになると思いますよ。

id:quocard

ご指摘ありがとうございます。

こちらに写したさいに紛れ込んでしまったようです。

実際に使用しているものは

99行目 VALUES(:id, :example)";

となっております。

2011/02/04 13:32:17
id:pretaroe No.3

回答回数531ベストアンサー獲得回数75

ポイント26pt

>エスケープしなければならない文字が含まれている

この可能性を疑っておられるのかもしれませんが、

INSRTでも、同じ文字列のデータを格納するのなら同じ現象がでると思います。

bindする場合は、エスケープは必要ありません。

UODATEで$id、$exampleの値が英数字だけの場合でも出るかどうかを確認して

いただけるでしょうか?

これで、正常にUPDATEされるが、他のデータでは質問文のようにエラーになると

いうのなら、SQL文は間違えていないでしょう。

英数字だけでもエラーになるのでしたら、エスケープとかの問題ではないと思います。

もし可能なら、

エラーが出る実際のSQL文と:example等の値を教えていただけませんか?

id:quocard

すいません。

実際には以下の2つでINSERTとUPDATEを行っております。

追加

$sql = "INSERT INTO blog(id, example)

VALUES(:id, :example)";

$conn = new PDO("sqlite:./test.sql3");

$stmt = $conn->prepare($sql);

$stmt->bindParam(":id", $id);

$stmt->bindParam(":example", $example);

$stmt->execute();

$id = $conn->lastInsertId();

更新

$sql = "UPDATE blog SET

id = :id,

example = :example,

WHERE id = :id";

$conn = new PDO("sqlite:./test.sql3");

$stmt = $conn->prepare($sql);

$stmt->bindParam(":id", $id);

$stmt->bindParam(":example", $example);

$stmt->execute();

エラーについてですが、エラーが出ていた102行目 $stmt->bindParam(":id", $id);の中身は英数字(0=9)になります。

直前でvar_dumpした際にも3や4といったものが出力されたので問題はないと思います。

exampleの中身は日本語文章が入っています。文字コードはサーバー含めて全てUTF-8となっているので

UTF-8になっているのではないかと思います。

2011/02/04 22:55:46
  • id:windofjuly
    うぃんど 2011/02/04 16:27:59
    間接回答拒否の設定がいつもながら厳しいので回答権利は無いけれど、コメント欄を開放なさったので、少しだけ

    (1)改行コードが入ってしまっている
    098行目 $sql = "INSERT INTO blog(id, example)
    099行目  VALUES(:id, :example,)";
      ↓
    098行目 $sql = "INSERT INTO blog(id, example) VALUES(:id, :example,)";

    (2)エスケープしなければならない文字が含まれている
    sqlite_escape_string
  • id:windofjuly
    うぃんど 2011/02/04 16:56:29
    以前書いたものを引っ張り出してみたら$sqlに改行コードが混ざるくらいならOKだった
    全角スペースなどを混ぜるとnon-objectって言われたから、まぁ、どっちにしても $sql の中身を良く見直してもらうしかないですね
  • id:b-wind
    >Call to a member function bindParam() on a non-object
    なんかそもそもの所をだれもちゃんと指摘してないのが不思議だが、
    このエラーは直訳しても解るとおりオブジェクトでない物に対し、メソッド呼び出しを行おうとした場合の物。

    つまり直前で行っている、
    $stmt = $conn->prepare($sql);
    これですでにエラーが出て $stmt にオブジェクトが帰ってきていない。

    それはそれとして文字コード周りの処理はPDOの仕様でめんどくさい事になってるようだ。
    http://www.tokumaru.org/d/20100701.html
    最新の事情は知らないけどね。
  • id:sayo213sayo
    コメント荒らし キタ━━(━(━(-( ( (゚∀゚) ) )-)━)━) ━━ !!!!!
     
    拒否られているのにコメント欄に回答を投稿しようという傲岸不遜
    他の回答者が投稿しにくくなることに対してはお構いなし
  • id:windofjuly
    うぃんど 2011/02/05 18:31:51
    >実際には以下の2つでINSERTとUPDATEを行っております。

    プログラムを掲載するのではなく、プログラムを動かして出来上がった $sql を echo で出力して、まずは自分で確認してみてください
    それこそが解決への近道ですよ
     
    >var_dumpした際にも3や4といったものが出力された
     
    質問文や返信欄では $id などとなっているけれど、実際には配列になってたりしませんか?
    質問用に自分なりに削ったのだと思いますが、削った部分にこそ問題点が隠されていますね
     
    PDOの問題に関してはUTF-8に統一されている限りにおいては問題ないと言って良いと思いますが、環境整備もままならぬ状況の人も多いですから、忘れてはいけない問題ではありますね
    以前の質問も根本的問題点は環境整備であったと思うのですが、その後、どのように整えたのかについては確認を要するかもしれません
    http://q.hatena.ne.jp/1287795575
  • id:quocard
    windofjuly 様
    すいません。基本的に回答権についてはデフォルトでいじってませんので設定といわれましてもなんともいえません。
    いくつか見直しをしてみてる中でsqlite_escape_stringについてはとても参考になりました。
    またこちらに掲載するにあたり削ったものとしては変数のみで、それ以外はそのままになります。
    変数も配列などではなく半角英数字のみのものです。
    環境にも問題があるのかもしれませんがPDOでの受け渡しをいったんやめてsqlite文にすることで正常に動くことを確認しました。

    b-wind 様
    回答ありがとうございます。
    PDOではなくsqlite文で行うことでデータの出し入れを行うようにしました。
    扱うデータ自体は同じなのでPDOの扱いに対する理解が不足していたとしかいえません。

    データベース自体を扱うのが初めてではあるので普段からデータベースを使用されているかたからすれば
    おかしな点が山盛りだったかと思いますが、少しずつでも良いので進めればと思っております。

    皆さん回答ありがとうございました。
  • id:windofjuly
    うぃんど 2011/02/06 05:34:07
    PDOを使い続けるのであればphpの環境まわりを見回す必要がありそうですがSQLite専用のモジュールを使うことに変更したのであれば、そのほうが楽と言えば楽です(今後のためにはしっかり学んでおく必要はあると思いますけど、とりあえず動くものを作る達成感を得るほうが今は重要でしょうね)
    問題点とすればprepareが無いという点ですが、個人用としてローカルで使うのであれば、SQLインジェクションの脅威におびえることも特にないので、SQLiteモジュールのほうがやっぱり楽ですね(SQLインジェクションについても学んでくださいね)
    SQLiteモジュールで、どのようなことが出来るかについては下記も覗いてみてください(sqlite_escape_stringもマニュアルページを見ていれば…ってのはもうよしておきます)
    http://jp.php.net/manual/ja/book.sqlite.php
     
    話は変わって回答権についてですが、下記のユーザーページにある「他ユーザーの設定による回答拒否」の設定になります
    http://q.hatena.ne.jp/quocard/config
    デフォルトは「拒否しない」になってるはずなので、過去のどこかの時点でご自身で変更なさったということになります
    「拒否しない」に設定変更することによって、必ずしもプラスになるというものでもありませんので、別に今のままでも結構だとは思いますが、そういった設定方法があるということを知っておくと便利だと思います
    この人には回答してほしくないと思った場合には回答拒否ユーザーにアカウント名を入れてしまうという手もあります(コメント欄やいわし質問には効きません。人力検索形式の回答欄への投稿だけができなくなるという設定です)
     
    何はともあれ、あせらず、がんばってください

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

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

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

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