1

私は、ログインしたメンバーが家族や友人に紹介を送信して、サインアップを勧めることができる紹介システムを開発しました。

すべて正常に機能しますが、昨日、24時間以内に送信できる紹介の最大数を制限することにしました。私はこれを1日あたり最大3つの紹介に制限しました。

問題があると思われるコードを以下に投稿しました。私が抱えている問題は、どのように見えても、今日の最大紹介数に達したというエラーメッセージが表示されることです。コードで何が間違っているのかわかりません。

// referral query
$referral_limit = mysql_query("SELECT 'created_on' FROM 'user_referrals'
WHERE `referrer_uid` = $referrer_uid ") or die(mysql_error());

if(mysql_num_rows($referral_limit) > 0){
    while($row = mysql_fetch_assoc($referral_limit)){

            $db_time = $row['created_on'];

            if((time() - $db_time) > 86400){
                // is within 24 hours and has reached maximum daily referral allowance
                $error[] = "You have reached the maximum referrals for today.";
            }
    }
}

$ db_timeをエコーアウトしようとしましたが、すべてを実行すると、created_onであるフィールド名であり、この場合はタイムスタンプを表示する実際の値ではありません。データベースのcreated_onフィールドには、紹介が行われたタイムスタンプが含まれています。これをチェックして、紹介しているユーザーが過去24時間以内に紹介を行っていないことを確認します。

また、1日あたり3ビットに制限する余分なビットを追加していないことに気付くでしょうが、この問題を最初に修正できるまで、そのビットを追加したくありませんでした。

データベーステーブルは次のようになります。

CREATE TABLE IF NOT EXISTS `user_referrals` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`referrer_uid` int(11) NOT NULL,
`recipient_username` varchar(15) NOT NULL,
`referrer_email` varchar(254) DEFAULT NULL,
`referred_id` char(32) NOT NULL,
`referred_email` varchar(254) NOT NULL,
`status` char(9) NOT NULL,
`created_on` int(11) NOT NULL,
`updated_on` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `referred_id` (`referred_id`),
KEY `referrer_uid` (`referrer_uid`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=72 ;

編集

これがいくつかの支援の後の私のコードです。紹介はありませんが、過去24時間以内に紹介が行われたとのことです。

エラーチェックを間違えていると思います。

$referral_limit = mysql_query("
        SELECT COUNT(*)
        FROM `user_referrals`
        WHERE `referrer_uid` = $referrer_uid
        AND `created_on` > UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 1 DAY))") or die(mysql_error());

if($referral_limit > 0) {
    $error[] = "You have reached the maximum referrals for today.";
}
4

6 に答える 6

9

MySQLでもフィルタリングできる場合は、PHPで完全なMySQL結果セットをフィルタリングしないでください。コード例では、MySQLから数千行をフェッチして、フィルタリングループを実行するだけです。これは、これまでで最も難しいパフォーマンスキラーです。むしろ、より良いSQLステートメントを使用してください。

SELECT COUNT(*) FROM 'referrals' WHERE `referrer_uid`=? AND created_on > UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 1 DAY))

このステートメントは、過去24時間の指定されたリファラーのリファラーの数(!)を返すだけです。

さらに、のように変数をMySQLに直接挿入しないでWHERE name=$nameください。これにより、アプリケーションが無数のSQLインジェクション攻撃にさらされることになります。SQLインジェクションが何であるかわからない場合は、今すぐ学ぶ必要があります。

于 2011-07-13T10:09:03.683 に答える
2

MySQLを使用してそれを計算することもできます。

$referral_limit = mysql_query("SELECT COUNT(*)
                               FROM referrals
                               WHERE referrer_uid = $referrer_uid
                               AND created_on >= NOW() - INTERVAL 1 DAY
                              ") or die(mysql_error());

それcreated_ondatetimeまたはであるという条件でtimestamp。なぜ宣言されているのINTですか?

于 2011-07-13T10:09:13.340 に答える
1

選択するフィールド名を一重引用符で囲まないでください。これは、返される文字列として解釈されるためです。たとえば、必要な

SELECT created_on ...

(実際にコードにバッククォートがあり、例に含まれているコードが正しくない場合を除きます)。

于 2011-07-13T10:07:02.317 に答える
1

クエリは次のようになります

$referral_limit = mysql_query("SELECT `created_on` FROM `referrals`
 WHERE `referrer_uid` = $referrer_uid ") or die(mysql_error());

これはcreated_onのバックティックであり、引用符ではありません。引用符を使用すると、フィールドは文字列になり、SELECT 1 FROM table1を返します。

于 2011-07-13T10:07:39.953 に答える
1

created_onint(11)NOT NULL、 updated_onint(11)DEFAULT NULL、

確かにこれらは日時フィールドである必要がありますか?

于 2011-07-13T10:07:50.673 に答える
0

クエリを変更する

$referral_limit = mysql_query("SELECT 'created_on' FROM 'user_referrals'WHERE `referrer_uid` = $referrer_uid ") or die(mysql_error());

$referral_limit = mysql_query("SELECT `created_on` FROM `user_referrals` WHERE `referrer_uid` = $referrer_uid ") or die(mysql_error());
于 2011-07-13T10:33:23.790 に答える