Johnboy URL Shortnerを使用していますが、生成されたURLがデータベースに存在するかどうかをチェックおよび確認しないことに気付きました。URLが一意であることを確認するにはどうすればよいですか>
5 に答える
長いURLまたは短いURL、あるいはその両方に対して一意のインデックス/制約を作成します。スクリプトが同じ値の別のレコードを挿入しようとすると、INSERTステートメントは失敗し、テストして適切に処理できる特定のエラーコードが表示されます。
define('MYSQL_ER_DUP_ENTRY', 1062);
...
if ( !mysql_query($mysql, $query) ) {
if ( MYSQL_ER_DUP_ENTRY==mysql_errno($mysql) ) {
// handle duplicate entry
}
}
ジョンボーイのスクリプトは脆弱性に満ちているようです...しかし、ここに行きます!(新しい短縮URLを計算するindex.phpスクリプトを変更)
$short = substr(str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'), 0, 5);
$unique = false;
while(!$unique) {
$exists = mysql_fetch_assoc(mysql_query("SELECT url_link FROM urls WHERE url_short = '".$short."'"));
if($exists['url_link'] != '') {
// one already exists! create another, try again.
$short = substr(str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'), 0, 5);
} else {
$unique = true;
}
}
mysql_query("INSERT INTO urls (url_link, url_short, url_ip, url_date) VALUES
(
'".addslashes($_POST['url'])."',
'".$short."',
'".$_SERVER['REMOTE_ADDR']."',
'".time()."'
)
");
DBテーブルは次のようになります。
CREATE TABLE IF NOT EXISTS `urls` (
`url_id` int(11) NOT NULL auto_increment,
`url_link` varchar(255) default NULL,
`url_short` varchar(6) default NULL,
`url_date` int(10) default NULL,
`url_ip` varchar(255) default NULL,
`url_hits` int(11) default '0',
PRIMARY KEY (`url_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
主キーは自動インクリメントされた整数であり、アプリ全体で使用されることはありません。あなたはそれを取り除き、url_short
主キーとして使うことができます。次に、新しいものを挿入するときに、次の3つのいずれかを実行できます。
- INSERT IGNOREを使用して、重複をサイレントに破棄します。
- INSERT ... ON DUPLICATE KEY UPDATE ...を使用して、重複を更新します。
- 通常
INSERT
を使用してエラーコードを確認します。1062の場合、それは重複です。
私は#3に行きます。
ただし、addslashes()
SQLに入力パラメーターを挿入するために使用されることを考えると、このスクリプトの使用はまったく避けたいと思います。それは時代遅れで安全ではないように見えます。
UNIQUE
データベース列に追加するだけで十分url_link
です。
外部キー制約を使用して、データベースレベルで一意のURLを確保できます。次に、PHPで、クエリが行を挿入したことを確認します。挿入されている場合は、一意のURLが挿入されていることがわかります。挿入されていない場合は、ユーザーまたはスクリプトに新しい文字列で再試行する機会を与えます。