0

内部でさまざまなタスクに使用される webapp を作成しています。定期的にデータを照会する必要がある MySQL データベースを使用します。

私は準備済みステートメントを認識しており、それらがベストプラクティスであることを認識していますが、多数のテーブルと結合を考えると、クエリを取得して実行し、結果を返す一般的な関数を作成するのが最も簡単であることがわかりました。

これがライブサイトにある場合、SQL インジェクションに対して脆弱になる可能性があることは理解していますが、この方法を使用することで本質的に悪いことはありますか? 私はphpとMySQLの間のインターフェースに比較的慣れていないので、webappでステートメントを繰り返し実行する方法のベストプラクティスを知りたいと思っています.

SELECTこれは、クエリに使用する関数の例です。

function getSQLResultsPDO($query){
  $mydb = new PDO('mysql:host=localhost;dbname=mydatabase;charset=utf8', 'user', 'password');
  $sth = $mydb->prepare($query);
 if (!$sth) {
    echo "\n<pre>PDO::errorInfo():</pre>\n";
    echo "<pre>";
    print_r($conn->errorInfo());
    echo "</pre>";
}
  $sth->execute();

  $result = $sth->fetchAll(PDO::FETCH_CLASS);
  if (empty($result)){
    $result = false;
  }

  return $result;

}
4

2 に答える 2

5

@jay Harris のコメントにのみ同意できます。「そのスクリプトに関するすべてが悪い習慣です」

このような関数を使用してデータベースを処理するという考えは唯一の正しい選択ですが、実装はすべて間違っています。

まず第一に、なぜそのような機能を持つことは準備されたステートメントと矛盾すると思いますか? 追加のパラメーターを 1 つだけ(データを含む配列) 追加して、関数と安全性の両方を持たないのはなぜでしょうか?

次に、既に説明したように、クエリごとに接続するのではなく、アプリケーションごとに 1接続します。

最後に、エラー処理の方法が間違っています。

function getSQLResultsPDO($query, $params = array(), type = PDO::FETCH_CLASS){
  global $mydb;
  $sth = $mydb->prepare($query);
  $sth->execute($params);
  return $sth->fetchAll($type);
}

あまり便利ではありませんが、少なくとも使用可能で、95% 安全です。

この機能をしばらく使用すると、1 つしかないのは非常に不便であることがわかります。そして最終的に、一連の関数が必要であることがわかります。1 つは行を返さない DML クエリを実行し、いくつかの関数はさまざまな種類の結果を返します。

次の 2 つのコードを比較してください。

$data = getSQLResultsPDO("SELECT name FROM users WHERE id=?", array($id));
if (isset($data[0]->name)) {
    $name = $data[0]->name;
}
//and
$name = getSQLscalar("SELECT name FROM users WHERE id=?", array($id));
于 2013-06-26T14:23:09.430 に答える
0

それは良い習慣になる可能性があります。フレームワークを見ると、似たようなものを実装していますが、より複雑で、さまざまな方法を使用してクエリを作成できる点が異なります。これを行うポイントは、クエリを集中化することです。すべてのクエリが同じパスを通過する場合、すべてのクエリに関係する何かを変更する方が簡単です。たとえば、データベースを MySQL から別のものに変更したい場合。また、この中心点で注射を防御できます。

ですから、あなたのアイデアは良いのですが、もちろん改善できる点もあります。アプリケーションを開くときに単一の接続を作成し、後で実行するすべてのクエリに使用できます。クエリ メソッドがクラス内にある場合、接続はクラス属性である可能性があります。たとえば、コンストラクターで初期化されます。

私の提案は、他の人がどのようにそれを行っているかを見て、そこからインスピレーションを得ることです. たとえば、フレームワークがこれをどのように処理するかを見てください。

また、このことについても説明している素敵な MVC チュートリアルがあります。

http://johnsquibb.com/tutorials

于 2013-06-26T14:14:43.327 に答える