0
$query = "SELECT 1 FROM users WHERE username = :username";
$query_params = array(':username' => $_POST['username']);
try
{
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
die("Failed to run query: " . $ex->getMessage());
}

$row = $stmt->fetch();
if($row)
{
die("This username is already in use");
}

これはすべて機能しますが、次のとおりです。

  1. SELECTクエリが単にorの場合、準備されたステートメントが本当に必要SELECT COUNTですか?
    テーブルに操作がなければINSERT / UPDATE / DELETE、SQLインジェクションやスパムの危険はないと思いますか?

  2. try/catchデータベースにアクセスするたびにステートメントが本当に必要ですか?

4

4 に答える 4

2

ユーザーが何らかの方法で変更できるクエリに変数を入れる場合は、準備済みステートメントを使用する必要があります。

于 2013-01-09T19:36:17.680 に答える
2

誰かが SELECT を終了し、ユーザー名に INSERT ステートメントを追加する可能性があるため、SELECT ステートメントでも SQL インジェクションの危険性が常にあります。ただし、mysql_real_escape_string() を使用している場合や、DB クラスが値をエスケープしている場合は、SELECT ステートメントでの try/catch について心配する必要はありません。値をエスケープした場合、SQL にはこれで十分です。

$username = mysql_real_escape_string($username); // escape the string first.
$query = "SELECT 1 FROM users WHERE username = '$username'";
于 2013-01-09T19:36:40.707 に答える
2

1) いいえ、準備済みステートメントを使用する必要はありません。たとえば、PDO::query や PDO::quote を使用して、文字列連結を使用してクエリを作成できます。ただし、外部から提供された文字列を使用している場合は常に、SELECT を実行しているだけであっても、SQL インジェクションによる損傷のリスクがあります。たとえば、攻撃者は「;」を使用して、1 つのステートメントで 2 つのステートメントを実行しようとする可能性があります。提供された文字列で。PDO::quote は、これを防ぐもう 1 つの方法です。

2) 呼び出し元のコードからエラーをスローすることもできますが、どこかでエラー処理を考慮する必要があります。

于 2013-01-09T19:37:16.870 に答える
1

データベースへの接続に関する限り、これが必要な唯一のアプローチです。Try and Catch: (MySql データベースを使用している場合)

try {
    $conn = new PDO('mysql:host=localhost;dbname=DBNAME', 'USER', 'PASS', array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
} catch(PDOException $e) {
    echo 'ERROR: ' . $e->getMessage();
}

さらに、count には組み込みの count クエリがあります。

$affected_rows = $stmt->rowCount();

知らなかった場合は、ここに良いチュートリアルがあります

http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers

于 2013-01-09T19:38:37.900 に答える