• ベストアンサー

プリペアド・ステートメントの使い道

PHPとMySQLを独学で勉強して、1ヶ月ちょっとになります。 本には、「MySQLへの処理は、プリペアドステートメントで書くとよい」とありました。 メリットとしては、 (1)実行時のパフォーマンスがあがる(ネットによると若干あがる程度?) (2)自動でクォートの処理が行われるためSQLインジェクション対策になる とありました。 メリットがあるようなので、今のところ、すべてのMySQLへの処理について、 MDB2や、MDB2のExtendedを用いて、prepare、execute、getAllなどでphpを書いています。 しかし、毎回プリペアドして、実行しているため、phpが煩雑になっているように思います。 そのため、全てプリペアドで書いている自分のやり方がよいのか、 疑問に思えてきました。 またプリペアドのメリットは(2)が大きいようなので、 テキストボックスなどのinputされた内容を処理するSQL文のみ、 プリペアドで書けばいいのかな? と思うようになりました。 実際のところは、 (1)MySQLへの処理は、なるべく全てプリペアードした方がよいのでしょうか? (2)ある条件のときだけ、プリペアドすればよいのでしょうか? ぜひ、ご意見うかがわせていただきたいです。 よろしくお願いします。

  • PHP
  • 回答数2
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

個人でちまちまやっている間はどんなやり方をしてもOK。 プリペアドという仕組みが用意されているのだから、便利だと思うなら 使うべきだし、不便を感じたら別の仕組みを模索してもよいかと。 これが、プロジェクトでうごいているのであれば、データの引渡しに 一定のルール決めが必要になるでしょうから、自然とプリペアドに 近い形になるでしょう。 また、プリペアドしたからといってユーザーから送られてくるデータが 保証されるわけではないので、きちんとバリデート処理はいれる 必要があります。

korota-xp
質問者

お礼

本に書いてあるとおりにしようとしすぎて 迷走していたもので、そう教えていただけると助かります。 とりあえず、個人でやっている段階なので、 適宜使いやすい方法でしていこうと思います。 内容のチェックは、本に従いながらやっていましたが、 あれはバリデート処理というんですね、ふむふむ。 いつもありがとうございます^^

その他の回答 (1)

  • dalianse
  • ベストアンサー率35% (7/20)
回答No.2

よほど大きな理由があれば使う、使わないを分けてもいいかもしれませんが、できれば1つの方法に統一しといた方がよいと思います。 ちなみに以下のように書けばそれほど煩雑でもないと思います。 $SQL = "select id from tbl"; $stmt = $pdo->prepare($SQL); $stmt->execute();

korota-xp
質問者

お礼

確かに、それだと手間がかからなさそうに思えます。 今までは、本の通りに $sql = 'SELECT id FROM tbl WHERE sex = ?'; $type = array('text'); $data = array('男'); $stmt = $mdb2->prepare($sql, $type); $stmt->execute($data); のように書いていました。 もう少し省略したり、まとめたりして、使いやすいようにする必要があるなと思いました。 PDOクラスを用いる方法も知りました。 ありがとうございます!

関連するQ&A

  • MDB2 プリペアードステートメントについて

    顧客情報管理システムを開発居しています。 下記のコードはMDB2を使用して、既に入力された情報を変更するための物をテストのため簡略化した物(のはず)ですが、$res = $sth -> execute ($data);の部分でエラーが発生してしまいます。 おそらくプリペアードステートメントの問題だと思い調べてみましたがお手上げです。。 知っている方からすればかなり馬鹿らしい間違いだと思いますが。。。 教えて下さい。 ちなみにmySQLを使用しています。 <?php //DBへの接続に必要な処理は完了し、$mdb2と言うオブジェクトは既に存在している。 $sql = "UPDATE customer_list SET name = ?,post = ?,address = ?,email = ? WHERE code = ?"; $typ = array("text","integer","text","text","integer"); $sth = $mdb2 -> prepare($sql,$typ); $data = array($_POST['name'],$_POST['post'],$_POST['add'],$_POST['email'],$_POST['code']); echo $data; $res = $sth -> execute ($data); ?>

    • ベストアンサー
    • PHP
  • prepareでSQLインジェクション対策?

    PHPでMySQLを操作しています。 PDOのprepare()を使えば(プレースホルダを使えば?)、SQLインジェクションは必ず発生しないと言えますか? もし、そうだとすれば、SQLインジェクション対策はかなり簡単ですよね?でも、セキュリティの話でよく取り上げられるということは、実際は他の問題が発生したりするんですかね?

    • ベストアンサー
    • PHP
  • SQLインジェクション及びクロスサイトスクリプティング対策について

    MYSQLとPHPの掲示板があったのでどちらで質問させて頂こうか悩んだのですが、こちらの方に書き込みさせて頂きます。 現在、PHPとMYSQLを用いたプログラミングの勉強をしています。 そこで一つ疑問に感じた事がありましたので、お尋ねしたく投稿させて頂きます。 PEARなどを使わずに、平でSQL文を発行して表示しているのですが… SQLインジェクション対策・クロスサイトスクリプティング対策として以下の4つに気を付けています。 1. 文字コードはUTF8を使用 2. マジッククォートは基本的にオフ。オンの場合はスクリプト中でstripslashesを実行 3. 2のマジッククォート対策のあとにデータのインサート時に全ての挿入文字列にmysql_real_escape_stringを実行 4. データの出力時にhtmlspecialcharsを実行 以上の対策でSQLインジェクション対策及びクロスサイトスクリプティングについては十分でしょうか? コードも出さずに漠然とした質問なので返答しづらいかもしれませんが、幅広くご意見を頂けましたら助かります。 よろしくお願いします。 ※幅広くご意見頂きたいと思っておりますので記事の終了やお礼が遅くなってしまったらすみませんm(_ _)m

    • ベストアンサー
    • PHP
  • プリペアードステートメントの最終的なSQL文の確認

    プリペアードステートメントでSQLを実行しております。 プリペアードステートメントで最終的に実行されたSQL文を確認する方法はないでしょうか。 <実行SQL> $sql = "SELECT * FROM member where user = :username and password = :password and delflag ='0'"; $stmt = $this->db->prepare($sql); $flag = $stmt->execute(array(':username' => $user,':password' => $pass)); $passには、ユーザーから入力されたパスワード情報 $userには、ユーザーから入力されたユーザー名が入っております。 executeで実行された、$userの内容と$passwordの内容が埋め込まれ実行された 最終的な$SQL文を確認したいと思っています。 どのようにすれば確認できるものなのでしょうか。 ご教授よろしくお願いします。

    • ベストアンサー
    • PHP
  • phpプリペアードステートメントについて質問です。

    phpの練習で、以下のようなhtmlファイルとphpファイルを作り XAMPで作業をおこなっています。 以下にあるhtml.phpファイルでのやり取りはうまくいっているのですが、 このphpをプリペアードステートメントにする所で躓いています。 いろいろ調べてやってはみたものの、どうしても%を使った あいまい検索のところがわかりません。 ---------------------------------------------------------------- 以下、プリペアードステートメントにする前の ページ内容です。こちらではうまくいっています。 html <form method="post" action="kensaku.php"> ご意見コードを入力してください。<br /> <input name="code" type="text" style="width:100px"><br /> <br /> <input type="submit" value="送信"> </form> php <?php $code=$_POST['code']; $dsn = 'mysql:dbname=phpkiso;host=localhost'; $user = 'root'; $password =''; $dbh = new PDO($dsn,$user,$password); $dbh->query('SET NAMES UTF-8'); $sql = "select * from `anketo` where `goiken` like '%{$code}%' "; $stmt = $dbh->prepare($sql); $stmt-> execute(); while(1) { $rec=$stmt->fetch(PDO::FETCH_ASSOC); if($rec==false) { break; } print $rec['code']; print $rec['nickname']; print $rec['email']; print $rec['goiken']; print '<br />'; } $dbh = null; ?> ---------------------------------------------------------------- 以上のphpの中の以下の分を $sql = "select * from `anketo` where `goiken` like '%{$code}%' "; $stmt = $dbh->prepare($sql); $stmt-> execute(); ↓ $sql ="SELECT*FROM anketo WHERE goiken like ?"; $stmt = $dbh->prepare($sql); $data[] = $code; $stmt->execute(array("%$_GET[$data]%")); こんな風に直しては見たのですが、なんだか うまくい行かずです。 よろしければ教えてください。 宜しくお願い致します。

    • 締切済み
    • PHP
  • PHP+PDO+MYSQL で実行されたSQL文の取得について

    PHP+PDO+MYSQL で実行されたSQL文の取得について PEARのDBからPDOへの移行をしていましてデバック用のSQL文取得で困っています。 $sql = "SELECT * FROM sample where id = ? And id2 = ?" PEARのDBでは $db->query($sql,array(1,5)); $db->last_query; で実行したSQL文を取得することは可能でした。 PDOの場合 $sql_result = $pdo->prepare($sql); $sql_result->execute(array(1,5)); でリプレースフォルダ(クォート処理?)を利用してSQLを実行出来るようですが、 実行したSQLを確認する方法がマニュアル等を読みましたがどうしても分かりません。 どなたかご存知の方がいらっしゃいましたらご教授お願い致します。

    • ベストアンサー
    • PHP
  • PHPのSQLインジェクションはsprintf?

    PHPのSQLインジェクションですが、sprintf内でクォートをしてあるとそれで大丈夫なのでしょうか? 以下のようなコードがあり、nameは画面入力なのでSQLインジェクションが起こるのでは? と作成者に確認したところ、"%s"してあるから大丈夫との返事をもらいました。 ネット調べるとmysql_real_escape_stringでエスケープしてから"%s"で変換すれば大丈夫といった内容は見つけたのですが、mysql_real_escape_stringなど不要との返事をもらいました。 なぜ?と聞くとそういうものだとしか回答がありません。 sprintf('UPDATE users SET name = "%s" WHERE id = %d', name, id); 結局上記のコードでSQLインジェクションは解消されているのでしょうか?

    • ベストアンサー
    • PHP
  • MySQLとPostgreSQLについてのSQLインジェクション

    はじめて質問させていただきます。 よろしくお願いします。 現在、私は大学の研究テーマでデータベース(MySQL、PostgreSQL)を使っているCGIを自作し、それぞれのデータベースについてSQLインジェクションの脆弱性について調べる、という研究を行っています。 ブラインドSQLインジェクションについて調べているのですが、 PostgreSQLの場合、pg_tablesというテーブルにデータベースのテーブル一覧表がのっていて、それを参照することでテーブル名が取得でき、いろいろ悪いことができてしまいますが、MySQLの場合、ブラインドSQLインジェクションを起こそうと思った場合どのようなコマンドを使えばよいのでしょうか? SHOW TABLESで使用中のデータベースのテーブル一覧は取得できますが、それをクエリの一部として使うことはできるのでしょうか・・・? また、全く関係ない質問なのですが、このCGIはRubyで記述して作りました。Rubyにはプリペアドステートメントという機能があるのですが、これをデータベースにアクセスするすべての箇所で用いればSQLインジェクションは100%起きないといえるのでしょうか?(現在考え得る範囲でよいのでお願いします) 卒論で困っているので知っている方がおられましたらどうかよろしくお願いいたします。

  • MySQLにデータを入れる際、エンコードしたほうが...

    PHPとMySQLを組み合わせて掲示板を作成しているのですが、SQLインジェクションの心配や、検索を簡単にするためDBに入力する際、すべてのデータをPHP側でエンコードし入力し、表示するときのみでコードするやり方はPHP的にもMySQL的にもどうなのでしょうか? 自分的には多少データ量は増えるものの、英数字や=などの記号のみを入力するだけなので、比較的検索は簡単になると思います。また、SQLインジェクションなども記号が変換されるため防ぐことができると考えています。 よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • SQLを直接フォームから入力するプログラムについて

    HTML+CSS+PHP+MySQLで「SQL実習サイト」を作っています。 SQLを入力し、その結果を確認するという学習用のサイトです。 現在はXAMPP上で動かしているだけですが、上手くできたらWeb上に上げる予定です。 質問は、そのサイトでのSQLインジェクション対策についてです。 作成している「SQL実習サイト」では、フォームにSQL文を直接入力してもらい、そのままその SQL文をPHPで実行するようにしています。 具体的には、POSTで自分自身(index.php)にSQLを送信し、それをクエリとして実行しています。 <h2>SQL入力</h2> <form action="index.php" method="post">     <textarea name="input_sql" cols=38 rows=3></textarea>     <input id="sql" type="submit" value="SQL実行"> </form> (~略~) $_SESSION['jikkou_sql'] = $_POST['input_sql']; (~略~) $sql = $_SESSION['jikkou_sql']; $query = mysql_query($sql, $conn); IPAの「安全なSQLの呼び出し方」等から調べると、SQLインジェクション対策としては プレースホルダ(プリペアド・ステートメント)が有効だとありますが、 作成しているケースだとSQLを直接実行するのでプレースホルダが使えない気がします。 「SQL実習サイト」ではSELECT文のみ実行できるようにしたいと考えています。 入力してもらったSQLの中で「SELECT」を探すようにして自作のSQLインジェクション対策を 行えばよろしいのでしょうか?(DELETEやUPDATEがあれば無効化したり・・・) それとも、そもそもこのような使い方ではSQLインジェクション対策はできないのでしょうか? ご教授よろしくお願いします。

    • ベストアンサー
    • PHP